From 32e6600272b885c595c094f0bc69459250220dcb Mon Sep 17 00:00:00 2001 From: ElfFlu <228066338+ElfFlu@users.noreply.github.com> Date: Sat, 23 Aug 2025 19:05:32 +0200 Subject: [PATCH 001/211] fix: remove authentication tag bytes from attachment download Signed-off-by: ElfFlu <228066338+ElfFlu@users.noreply.github.com> --- crates/core/files/src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/core/files/src/lib.rs b/crates/core/files/src/lib.rs index dacc988e5..f9db78102 100644 --- a/crates/core/files/src/lib.rs +++ b/crates/core/files/src/lib.rs @@ -80,6 +80,9 @@ pub async fn fetch_from_s3(bucket_id: &str, path: &str, nonce: &str) -> Result Date: Mon, 5 May 2025 22:14:10 +0100 Subject: [PATCH 002/211] feat: ready payload field customisation --- Cargo.lock | 1 + crates/bonfire/Cargo.toml | 1 + crates/bonfire/src/config.rs | 40 ++++++++++++++++++----- crates/bonfire/src/events/impl.rs | 21 +++++------- crates/core/database/src/events/client.rs | 33 +++++++++++++------ 5 files changed, 66 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4d310e03f..a3c3b0241 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6294,6 +6294,7 @@ dependencies = [ "once_cell", "querystring", "redis-kiss", + "regex", "revolt-config", "revolt-database", "revolt-models", diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index e447825d4..c01602706 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -19,6 +19,7 @@ async-channel = "2.3.1" # parsing querystring = "1.1.0" +regex = "1.11.1" # serde bincode = "1.3.3" diff --git a/crates/bonfire/src/config.rs b/crates/bonfire/src/config.rs index 5642d3baa..ea02092e5 100644 --- a/crates/bonfire/src/config.rs +++ b/crates/bonfire/src/config.rs @@ -1,8 +1,13 @@ use async_tungstenite::tungstenite::{handshake, Message}; use futures::channel::oneshot::Sender; +use once_cell::sync::Lazy; use revolt_database::events::client::ReadyPayloadFields; use revolt_result::{create_error, Result}; use serde::{Deserialize, Serialize}; +use regex::Regex; + +/// matches either a single word ie "users" or a key and value ie "settings[notifications]" +static READY_PAYLOAD_FIELD_REGEX: Lazy = Lazy::new(|| Regex::new(r#"^(\w+)(?:\[(\w+)\])?$"#).unwrap()); /// Enumeration of supported protocol formats #[derive(Debug)] @@ -17,6 +22,7 @@ pub struct ProtocolConfiguration { protocol_version: i32, format: ProtocolFormat, session_token: Option, + ready_payload_fields: ReadyPayloadFields } impl ProtocolConfiguration { @@ -25,11 +31,13 @@ impl ProtocolConfiguration { protocol_version: i32, format: ProtocolFormat, session_token: Option, + ready_payload_fields: ReadyPayloadFields ) -> Self { Self { protocol_version, format, session_token, + ready_payload_fields } } @@ -86,14 +94,8 @@ impl ProtocolConfiguration { } /// Get ready payload fields - pub fn get_ready_payload_fields(&self) -> Vec { - vec![ - ReadyPayloadFields::Users, - ReadyPayloadFields::Servers, - ReadyPayloadFields::Channels, - ReadyPayloadFields::Members, - ReadyPayloadFields::Emoji, - ] + pub fn get_ready_payload_fields(&self) -> &ReadyPayloadFields { + &self.ready_payload_fields } } @@ -124,6 +126,7 @@ impl handshake::server::Callback for WebsocketHandshakeCallback { let mut protocol_version = 1; let mut format = ProtocolFormat::Json; let mut session_token = None; + let mut ready_payload_fields = ReadyPayloadFields::default(); // Parse and map parameters from key-value to known variables. for (key, value) in params { @@ -139,6 +142,26 @@ impl handshake::server::Callback for WebsocketHandshakeCallback { _ => {} }, "token" => session_token = Some(value.into()), + "ready" => { + if let Some(captures) = READY_PAYLOAD_FIELD_REGEX.captures(value) { + if let Some(field) = captures.get(0) { + match field.as_str() { + "users" => ready_payload_fields.users = true, + "servers" => ready_payload_fields.servers = true, + "channels" => ready_payload_fields.channels = true, + "members" => ready_payload_fields.members = true, + "emojis" => ready_payload_fields.emojis = true, + "channel_unreads" => ready_payload_fields.channel_unreads = true, + "user_settings" => { + if let Some(subkey) = captures.get(1) { + ready_payload_fields.user_settings.push(subkey.as_str().to_string()); + } + }, + _ => {} + } + } + } + } _ => {} } } @@ -151,6 +174,7 @@ impl handshake::server::Callback for WebsocketHandshakeCallback { protocol_version, format, session_token, + ready_payload_fields }) .is_ok() { diff --git a/crates/bonfire/src/events/impl.rs b/crates/bonfire/src/events/impl.rs index 160e7c6c0..49b30d510 100644 --- a/crates/bonfire/src/events/impl.rs +++ b/crates/bonfire/src/events/impl.rs @@ -95,7 +95,7 @@ impl State { pub async fn generate_ready_payload( &mut self, db: &Database, - fields: Vec, + fields: &ReadyPayloadFields, ) -> Result { let user = self.clone_user(); self.cache.is_bot = user.bot.is_some(); @@ -168,7 +168,7 @@ impl State { .await?; // Fetch customisations. - let emojis = if fields.contains(&ReadyPayloadFields::Emoji) { + let emojis = if fields.emojis { Some( db.fetch_emoji_by_parent_ids( &servers @@ -183,17 +183,14 @@ impl State { }; // Fetch user settings - let user_settings = if let Some(ReadyPayloadFields::UserSettings(keys)) = fields - .iter() - .find(|e| matches!(e, ReadyPayloadFields::UserSettings(_))) - { - Some(db.fetch_user_settings(&user.id, keys).await?) + let user_settings = if !fields.user_settings.is_empty() { + Some(db.fetch_user_settings(&user.id, &fields.user_settings).await?) } else { None }; // Fetch channel unreads - let channel_unreads = if fields.contains(&ReadyPayloadFields::ChannelUnreads) { + let channel_unreads = if fields.channel_unreads { Some(db.fetch_unreads(&user.id).await?) } else { None @@ -241,22 +238,22 @@ impl State { } Ok(EventV1::Ready { - users: if fields.contains(&ReadyPayloadFields::Users) { + users: if fields.users { Some(users) } else { None }, - servers: if fields.contains(&ReadyPayloadFields::Servers) { + servers: if fields.servers { Some(servers.into_iter().map(Into::into).collect()) } else { None }, - channels: if fields.contains(&ReadyPayloadFields::Channels) { + channels: if fields.channels { Some(channels.into_iter().map(Into::into).collect()) } else { None }, - members: if fields.contains(&ReadyPayloadFields::Members) { + members: if fields.members { Some(members.into_iter().map(Into::into).collect()) } else { None diff --git a/crates/core/database/src/events/client.rs b/crates/core/database/src/events/client.rs index aa9fb0b9f..b64a02ad7 100644 --- a/crates/core/database/src/events/client.rs +++ b/crates/core/database/src/events/client.rs @@ -20,16 +20,29 @@ pub enum Ping { } /// Fields provided in Ready payload -#[derive(PartialEq)] -pub enum ReadyPayloadFields { - Users, - Servers, - Channels, - Members, - Emoji, - - UserSettings(Vec), - ChannelUnreads, +#[derive(PartialEq, Debug, Clone, Deserialize)] +pub struct ReadyPayloadFields { + pub users: bool, + pub servers: bool, + pub channels: bool, + pub members: bool, + pub emojis: bool, + pub user_settings: Vec, + pub channel_unreads: bool +} + +impl Default for ReadyPayloadFields { + fn default() -> Self { + Self { + users: true, + servers: true, + channels: true, + members: true, + emojis: true, + user_settings: Vec::new(), + channel_unreads: false + } + } } /// Protocol Events From 964884a5de81f8b459bbc09068c67889bb827cd4 Mon Sep 17 00:00:00 2001 From: Zomatree Date: Tue, 16 Sep 2025 20:46:05 +0100 Subject: [PATCH 003/211] chore: add policy changes --- crates/bonfire/src/config.rs | 38 +++++++++++++----- crates/bonfire/src/events/impl.rs | 47 ++++++++++++++--------- crates/core/database/src/events/client.rs | 9 +++-- 3 files changed, 63 insertions(+), 31 deletions(-) diff --git a/crates/bonfire/src/config.rs b/crates/bonfire/src/config.rs index ea02092e5..5cd87b8b4 100644 --- a/crates/bonfire/src/config.rs +++ b/crates/bonfire/src/config.rs @@ -1,13 +1,14 @@ use async_tungstenite::tungstenite::{handshake, Message}; use futures::channel::oneshot::Sender; use once_cell::sync::Lazy; +use regex::Regex; use revolt_database::events::client::ReadyPayloadFields; use revolt_result::{create_error, Result}; use serde::{Deserialize, Serialize}; -use regex::Regex; /// matches either a single word ie "users" or a key and value ie "settings[notifications]" -static READY_PAYLOAD_FIELD_REGEX: Lazy = Lazy::new(|| Regex::new(r#"^(\w+)(?:\[(\w+)\])?$"#).unwrap()); +static READY_PAYLOAD_FIELD_REGEX: Lazy = + Lazy::new(|| Regex::new(r#"^(\w+)(?:\[(\w+)\])?$"#).unwrap()); /// Enumeration of supported protocol formats #[derive(Debug)] @@ -22,7 +23,7 @@ pub struct ProtocolConfiguration { protocol_version: i32, format: ProtocolFormat, session_token: Option, - ready_payload_fields: ReadyPayloadFields + ready_payload_fields: ReadyPayloadFields, } impl ProtocolConfiguration { @@ -31,13 +32,13 @@ impl ProtocolConfiguration { protocol_version: i32, format: ProtocolFormat, session_token: Option, - ready_payload_fields: ReadyPayloadFields + ready_payload_fields: ReadyPayloadFields, ) -> Self { Self { protocol_version, format, session_token, - ready_payload_fields + ready_payload_fields, } } @@ -126,7 +127,22 @@ impl handshake::server::Callback for WebsocketHandshakeCallback { let mut protocol_version = 1; let mut format = ProtocolFormat::Json; let mut session_token = None; - let mut ready_payload_fields = ReadyPayloadFields::default(); + let mut ready_payload_fields = if params.iter().any(|(k, _)| *k == "ready") { + // If they pass the ready field, set all fields to false + + ReadyPayloadFields { + users: false, + servers: false, + channels: false, + members: false, + emojis: false, + user_settings: Vec::new(), + channel_unreads: false, + policy_changes: false, + } + } else { + ReadyPayloadFields::default() + }; // Parse and map parameters from key-value to known variables. for (key, value) in params { @@ -143,6 +159,7 @@ impl handshake::server::Callback for WebsocketHandshakeCallback { }, "token" => session_token = Some(value.into()), "ready" => { + // Re-enable all the fields the client specifies if let Some(captures) = READY_PAYLOAD_FIELD_REGEX.captures(value) { if let Some(field) = captures.get(0) { match field.as_str() { @@ -154,9 +171,12 @@ impl handshake::server::Callback for WebsocketHandshakeCallback { "channel_unreads" => ready_payload_fields.channel_unreads = true, "user_settings" => { if let Some(subkey) = captures.get(1) { - ready_payload_fields.user_settings.push(subkey.as_str().to_string()); + ready_payload_fields + .user_settings + .push(subkey.as_str().to_string()); } - }, + } + "policy_changes" => ready_payload_fields.policy_changes = true, _ => {} } } @@ -174,7 +194,7 @@ impl handshake::server::Callback for WebsocketHandshakeCallback { protocol_version, format, session_token, - ready_payload_fields + ready_payload_fields, }) .is_ok() { diff --git a/crates/bonfire/src/events/impl.rs b/crates/bonfire/src/events/impl.rs index 49b30d510..83b0d4c6f 100644 --- a/crates/bonfire/src/events/impl.rs +++ b/crates/bonfire/src/events/impl.rs @@ -101,15 +101,17 @@ impl State { self.cache.is_bot = user.bot.is_some(); // Fetch pending policy changes. - let policy_changes = if user.bot.is_some() { - vec![] + let policy_changes = if user.bot.is_some() || !fields.policy_changes { + None } else { - db.fetch_policy_changes() - .await? - .into_iter() - .filter(|policy| policy.created_time > user.last_acknowledged_policy_change) - .map(Into::into) - .collect() + Some( + db.fetch_policy_changes() + .await? + .into_iter() + .filter(|policy| policy.created_time > user.last_acknowledged_policy_change) + .map(Into::into) + .collect(), + ) }; // Find all relationships to the user. @@ -176,7 +178,10 @@ impl State { .map(|x| x.id.to_string()) .collect::>(), ) - .await?, + .await? + .into_iter() + .map(|emoji| emoji.into()) + .collect(), ) } else { None @@ -184,14 +189,23 @@ impl State { // Fetch user settings let user_settings = if !fields.user_settings.is_empty() { - Some(db.fetch_user_settings(&user.id, &fields.user_settings).await?) + Some( + db.fetch_user_settings(&user.id, &fields.user_settings) + .await?, + ) } else { None }; // Fetch channel unreads let channel_unreads = if fields.channel_unreads { - Some(db.fetch_unreads(&user.id).await?) + Some( + db.fetch_unreads(&user.id) + .await? + .into_iter() + .map(|unread| unread.into()) + .collect(), + ) } else { None }; @@ -238,11 +252,7 @@ impl State { } Ok(EventV1::Ready { - users: if fields.users { - Some(users) - } else { - None - }, + users: if fields.users { Some(users) } else { None }, servers: if fields.servers { Some(servers.into_iter().map(Into::into).collect()) } else { @@ -258,10 +268,9 @@ impl State { } else { None }, - emojis: emojis.map(|vec| vec.into_iter().map(Into::into).collect()), - + emojis, user_settings, - channel_unreads: channel_unreads.map(|vec| vec.into_iter().map(Into::into).collect()), + channel_unreads, policy_changes, }) diff --git a/crates/core/database/src/events/client.rs b/crates/core/database/src/events/client.rs index b64a02ad7..996347cac 100644 --- a/crates/core/database/src/events/client.rs +++ b/crates/core/database/src/events/client.rs @@ -28,7 +28,8 @@ pub struct ReadyPayloadFields { pub members: bool, pub emojis: bool, pub user_settings: Vec, - pub channel_unreads: bool + pub channel_unreads: bool, + pub policy_changes: bool, } impl Default for ReadyPayloadFields { @@ -40,7 +41,8 @@ impl Default for ReadyPayloadFields { members: true, emojis: true, user_settings: Vec::new(), - channel_unreads: false + channel_unreads: false, + policy_changes: true, } } } @@ -76,7 +78,8 @@ pub enum EventV1 { #[serde(skip_serializing_if = "Option::is_none")] channel_unreads: Option>, - policy_changes: Vec, + #[serde(skip_serializing_if = "Option::is_none")] + policy_changes: Option>, }, /// Ping response From 3a3415915f0d0fdce1499d47a2b7fa097f5946ea Mon Sep 17 00:00:00 2001 From: Zomatree Date: Tue, 16 Sep 2025 20:50:34 +0100 Subject: [PATCH 004/211] fix: relax settings name regex --- crates/bonfire/src/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bonfire/src/config.rs b/crates/bonfire/src/config.rs index 5cd87b8b4..05f7cf5a0 100644 --- a/crates/bonfire/src/config.rs +++ b/crates/bonfire/src/config.rs @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize}; /// matches either a single word ie "users" or a key and value ie "settings[notifications]" static READY_PAYLOAD_FIELD_REGEX: Lazy = - Lazy::new(|| Regex::new(r#"^(\w+)(?:\[(\w+)\])?$"#).unwrap()); + Lazy::new(|| Regex::new(r#"^(\w+)(?:\[(\S+)\])?$"#).unwrap()); /// Enumeration of supported protocol formats #[derive(Debug)] From fb4011084d6a5fdf164a6569bd8a9c5a91aed80c Mon Sep 17 00:00:00 2001 From: Zomatree Date: Tue, 16 Sep 2025 19:15:34 +0100 Subject: [PATCH 005/211] refactor: move ratelimits to a generic system for all web servers --- Cargo.lock | 19 + crates/core/database/src/models/users/axum.rs | 13 +- crates/core/ratelimits/Cargo.toml | 25 ++ crates/core/ratelimits/src/axum.rs | 193 ++++++++++ crates/core/ratelimits/src/lib.rs | 7 + crates/core/ratelimits/src/ratelimiter.rs | 145 ++++++++ crates/core/ratelimits/src/rocket.rs | 162 ++++++++ crates/delta/Cargo.toml | 1 + crates/delta/src/main.rs | 9 +- crates/delta/src/util/mod.rs | 2 +- crates/delta/src/util/ratelimiter.rs | 347 ------------------ crates/delta/src/util/ratelimits.rs | 81 ++++ crates/services/autumn/Cargo.toml | 1 + crates/services/autumn/src/api.rs | 4 +- crates/services/autumn/src/main.rs | 26 +- crates/services/autumn/src/ratelimits.rs | 28 ++ 16 files changed, 705 insertions(+), 358 deletions(-) create mode 100644 crates/core/ratelimits/Cargo.toml create mode 100644 crates/core/ratelimits/src/axum.rs create mode 100644 crates/core/ratelimits/src/lib.rs create mode 100644 crates/core/ratelimits/src/ratelimiter.rs create mode 100644 crates/core/ratelimits/src/rocket.rs delete mode 100644 crates/delta/src/util/ratelimiter.rs create mode 100644 crates/delta/src/util/ratelimits.rs create mode 100644 crates/services/autumn/src/ratelimits.rs diff --git a/Cargo.lock b/Cargo.lock index a3c3b0241..ca1011677 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -962,6 +962,7 @@ checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" dependencies = [ "async-trait", "axum-core", + "axum-macros", "bytes 1.10.1", "futures-util", "http 1.3.1", @@ -6259,6 +6260,7 @@ dependencies = [ "revolt-config", "revolt-database", "revolt-files", + "revolt-ratelimits", "revolt-result", "revolt_clamav-client", "serde", @@ -6415,6 +6417,7 @@ dependencies = [ "revolt-models", "revolt-permissions", "revolt-presence", + "revolt-ratelimits", "revolt-result", "revolt_rocket_okapi", "rocket", @@ -6563,6 +6566,22 @@ dependencies = [ "web-push", ] +[[package]] +name = "revolt-ratelimits" +version = "0.8.8" +dependencies = [ + "async-trait", + "authifier", + "axum", + "dashmap", + "log", + "revolt-database", + "revolt-result", + "revolt_rocket_okapi", + "rocket", + "serde", +] + [[package]] name = "revolt-result" version = "0.8.8" diff --git a/crates/core/database/src/models/users/axum.rs b/crates/core/database/src/models/users/axum.rs index da83c5b13..a6d8b5a3b 100644 --- a/crates/core/database/src/models/users/axum.rs +++ b/crates/core/database/src/models/users/axum.rs @@ -1,14 +1,21 @@ -use axum::{extract::FromRequestParts, http::request::Parts}; +use axum::{ + extract::{FromRef, FromRequestParts}, + http::request::Parts, +}; use revolt_result::{create_error, Error, Result}; use crate::{Database, User}; #[async_trait::async_trait] -impl FromRequestParts for User { +impl FromRequestParts for User +where + Database: FromRef, +{ type Rejection = Error; - async fn from_request_parts(parts: &mut Parts, db: &Database) -> Result { + async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { + let db = Database::from_ref(state); if let Some(Ok(bot_token)) = parts.headers.get("x-bot-token").map(|v| v.to_str()) { let bot = db.fetch_bot_by_token(bot_token).await?; db.fetch_user(&bot.id).await diff --git a/crates/core/ratelimits/Cargo.toml b/crates/core/ratelimits/Cargo.toml new file mode 100644 index 000000000..49110e1ef --- /dev/null +++ b/crates/core/ratelimits/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "revolt-ratelimits" +version = "0.8.8" +edition = "2024" + +[features] +rocket = ["dep:rocket", "dep:revolt_rocket_okapi", "revolt-database/rocket-impl"] +axum = ["dep:axum", "revolt-database/axum-impl"] + +default = ["rocket", "axum"] + +[dependencies] +revolt-database = { version = "0.8.8", path = "../database"} +revolt-result = { version = "0.8.8", path = "../result" } + +rocket = { version = "0.5.1", optional = true } +revolt_rocket_okapi = { version = "0.10.0", optional = true } + +axum = { version = "0.7.5", optional = true, features = ["macros"] } + +serde = { version = "1", features = ["derive"] } +authifier = { version = "1.0.15" } +dashmap = "5.2.0" +async-trait = "0.1.81" +log = "0.4" diff --git a/crates/core/ratelimits/src/axum.rs b/crates/core/ratelimits/src/axum.rs new file mode 100644 index 000000000..39b0c3bb6 --- /dev/null +++ b/crates/core/ratelimits/src/axum.rs @@ -0,0 +1,193 @@ +use std::net::SocketAddr; + +use async_trait::async_trait; +use axum::{ + Json, RequestPartsExt, Router, + body::Body, + extract::{ConnectInfo, FromRef, FromRequestParts, State}, + http::{HeaderValue, Request, StatusCode, request::Parts}, + middleware::Next, + response::{IntoResponse, Response}, + routing::get, +}; +use revolt_database::{Database, User}; + +use crate::ratelimiter::{RatelimitInformation, Ratelimiter, RequestKind}; + +#[derive(Clone, Copy)] +pub struct AxumRequestKind; + +impl RequestKind for AxumRequestKind { + type R<'a> = Parts; +} + +pub type RatelimitStorage = crate::ratelimiter::RatelimitStorage; + +fn to_ip(parts: &Parts) -> String { + parts + .extensions + .get::>() + .map(|info| info.ip().to_string()) + .unwrap_or_default() +} + +fn to_real_ip(parts: &Parts) -> String { + if let Ok(true) = std::env::var("TRUST_CLOUDFLARE").map(|x| x == "1") { + parts + .headers + .get("CF-Connecting-IP") + .map(|x| x.to_str().unwrap().to_string()) + .unwrap_or_else(|| to_ip(parts)) + } else { + to_ip(parts) + } +} + +#[async_trait] +impl FromRequestParts for Ratelimiter +where + Database: FromRef, + RatelimitStorage: FromRef, +{ + type Rejection = Json; + + async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { + if parts + .extensions + .get::>>() + .is_none() + { + let storage = RatelimitStorage::from_ref(state); + + let identifier = if let Ok(user) = parts.extract_with_state::(state).await { + user.id + } else { + to_real_ip(parts) + }; + + let (bucket, resource) = storage.resolver.resolve_bucket(parts); + let limit = storage.resolver.resolve_bucket_limit(bucket); + + let ratelimiter = + Ratelimiter::from(&storage.map, &identifier, limit, (bucket, resource)); + + parts.extensions.insert(ratelimiter.map_err(Json)); + }; + + *parts + .extensions + .get::>>() + .unwrap() + } +} + +#[async_trait] +impl FromRequestParts for RatelimitInformation +where + Database: FromRef, + RatelimitStorage: FromRef, +{ + type Rejection = Json; + + async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { + if parts + .extensions + .get::>>() + .is_none() + { + let ratelimiter = parts.extract_with_state::(state).await; + + parts.extensions.insert(ratelimiter); + }; + + let ratelimiter = *parts + .extensions + .get::>>() + .unwrap(); + + match ratelimiter { + Ok(ratelimter) => Ok(RatelimitInformation::Success(ratelimter)), + Err(ratelimiter) => Err(Json(RatelimitInformation::Failure { + retry_after: ratelimiter.reset, + })), + } + } +} + +pub async fn ratelimit_middleware( + State(database): State, + State(ratelimit_storage): State, + request: Request, + next: Next, +) -> Response { + #[derive(axum::extract::FromRef)] + struct TempState { + database: Database, + ratelimit_storage: RatelimitStorage, + } + + let state = TempState { + database, + ratelimit_storage, + }; + + let (mut parts, body) = request.into_parts(); + + let res = Ratelimiter::from_request_parts(&mut parts, &state).await; + + let (Ok(ratelimiter) | Err(Json(ratelimiter))) = &res; + + let mut response = if res.is_ok() { + let request = Request::from_parts(parts, body); + + next.run(request).await + } else { + let ratelimit_info = RatelimitInformation::from_request_parts(&mut parts, &state).await; + + ratelimit_info.map(Json).into_response() + }; + + let Ratelimiter { + key, + limit, + remaining, + reset, + } = ratelimiter; + + let headers = response.headers_mut(); + + headers.insert( + "X-RateLimit-Limit", + HeaderValue::from_str(&limit.to_string()).unwrap(), + ); + headers.insert( + "X-RateLimit-Bucket", + HeaderValue::from_str(&key.to_string()).unwrap(), + ); + headers.insert( + "X-RateLimit-Remaining", + HeaderValue::from_str(&remaining.to_string()).unwrap(), + ); + headers.insert( + "X-RateLimit-Reset-After", + HeaderValue::from_str(&reset.to_string()).unwrap(), + ); + + if res.is_err() { + *response.status_mut() = StatusCode::TOO_MANY_REQUESTS; + }; + + response +} + +async fn ratelimit_info(info: RatelimitInformation) -> Json { + Json(info) +} + +pub fn routes() -> Router +where + Database: FromRef, + RatelimitStorage: FromRef, +{ + Router::new().route("/ratelimit", get(ratelimit_info)) +} diff --git a/crates/core/ratelimits/src/lib.rs b/crates/core/ratelimits/src/lib.rs new file mode 100644 index 000000000..5eaa81080 --- /dev/null +++ b/crates/core/ratelimits/src/lib.rs @@ -0,0 +1,7 @@ +pub mod ratelimiter; + +#[cfg(feature = "rocket")] +pub mod rocket; + +#[cfg(feature = "axum")] +pub mod axum; diff --git a/crates/core/ratelimits/src/ratelimiter.rs b/crates/core/ratelimits/src/ratelimiter.rs new file mode 100644 index 000000000..a232feb32 --- /dev/null +++ b/crates/core/ratelimits/src/ratelimiter.rs @@ -0,0 +1,145 @@ +use std::collections::hash_map::DefaultHasher; +use std::hash::Hasher; +use std::ops::Add; +use std::sync::Arc; +use std::time::{Duration, SystemTime, UNIX_EPOCH}; + +use serde::Serialize; + +use dashmap::DashMap; + +pub trait RequestKind { + type R<'a>; +} + +pub trait RatelimitResolver: Send + Sync { + fn resolve_bucket<'a>(&self, request: &'a R) -> (&'a str, Option<&'a str>); + fn resolve_bucket_limit(&self, bucket: &str) -> u32; +} + +#[derive(Clone)] +pub struct RatelimitStorage { + pub resolver: Arc RatelimitResolver>>, + pub map: Arc>, +} + +impl RatelimitStorage { + pub fn new RatelimitResolver> + 'static>(resolver: R) -> Self { + Self { + resolver: Arc::new(resolver), + map: Arc::new(DashMap::new()), + } + } +} + +/// Ratelimit Bucket +#[derive(Clone, Copy, Debug)] +pub struct Entry { + used: u32, + reset: u128, +} + +/// Get the current time from Unix Epoch as a Duration +fn now() -> Duration { + SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("Time went backwards...") +} + +impl Entry { + /// Find bucket by its key + pub fn from(map: &DashMap, key: u64) -> Entry { + map.get(&key).map(|x| *x).unwrap_or_else(|| Entry { + used: 0, + reset: now().add(Duration::from_secs(10)).as_millis(), + }) + } + + /// Deduct one unit from the bucket and save + pub fn deduct(&mut self) { + let current_time = now().as_millis(); + if current_time > self.reset { + self.used = 1; + self.reset = now().add(Duration::from_secs(10)).as_millis(); + } else { + self.used += 1; + } + } + + /// Save information + pub fn save(self, map: &DashMap, key: u64) { + map.insert(key, self); + } + + /// Get remaining units in the bucket + pub fn get_remaining(&self, limit: u32) -> u32 { + if now().as_millis() > self.reset { + limit + } else { + limit - self.used + } + } + + /// Get how long bucket has until reset + pub fn left_until_reset(&self) -> u128 { + let current_time = now().as_millis(); + self.reset.saturating_sub(current_time) + } +} + +/// Ratelimit Guard +#[derive(Serialize, Clone, Copy, Debug)] +#[allow(dead_code)] +pub struct Ratelimiter { + pub key: u64, + pub limit: u32, + pub remaining: u32, + pub reset: u128, +} + +impl Ratelimiter { + /// Generate guard from identifier and target bucket + pub fn from( + map: &DashMap, + identifier: &str, + limit: u32, + (bucket, resource): (&str, Option<&str>), + ) -> Result { + let mut key = DefaultHasher::new(); + key.write(identifier.as_bytes()); + key.write(bucket.as_bytes()); + + if let Some(id) = resource { + key.write(id.as_bytes()); + } + + let key = key.finish(); + let mut entry = Entry::from(map, key); + + let remaining = entry.get_remaining(limit); + let reset = entry.left_until_reset(); + let mut ratelimiter = Ratelimiter { + key, + limit, + remaining, + reset, + }; + if remaining == 0 { + return Err(ratelimiter); + } + + entry.deduct(); + entry.save(map, key); + ratelimiter.remaining -= 1; + ratelimiter.reset = entry.left_until_reset(); + + Ok(ratelimiter) + } +} + +#[derive(Serialize)] +#[serde(untagged)] +pub enum RatelimitInformation { + Success(Ratelimiter), + Failure { retry_after: u128 }, +} diff --git a/crates/core/ratelimits/src/rocket.rs b/crates/core/ratelimits/src/rocket.rs new file mode 100644 index 000000000..6e7a0c9d8 --- /dev/null +++ b/crates/core/ratelimits/src/rocket.rs @@ -0,0 +1,162 @@ +use async_trait::async_trait; +use log::info; +use rocket::fairing::{Fairing, Info, Kind}; +use rocket::http::uri::Origin; +use rocket::http::{Method, Status}; +use rocket::request::{FromRequest, Outcome}; +use rocket::serde::json::Json; +use rocket::{Data, Request, Response, State}; + +use revolt_rocket_okapi::r#gen::OpenApiGenerator; +use revolt_rocket_okapi::request::{OpenApiFromRequest, RequestHeaderInput}; + +use authifier::models::Session; + +use crate::ratelimiter::RequestKind; +use crate::ratelimiter::{RatelimitInformation, Ratelimiter}; + +#[derive(Clone, Copy)] +pub struct RocketRequestKind; + +impl RequestKind for RocketRequestKind { + type R<'a> = Request<'a>; +} + +pub type RatelimitStorage = crate::ratelimiter::RatelimitStorage; + +/// Find the remote IP of the client +fn to_ip(request: &'_ rocket::Request<'_>) -> String { + request + .remote() + .map(|x| x.ip().to_string()) + .unwrap_or_default() +} + +/// Find the actual IP of the client +fn to_real_ip(request: &'_ rocket::Request<'_>) -> String { + if let Ok(true) = std::env::var("TRUST_CLOUDFLARE").map(|x| x == "1") { + request + .headers() + .get_one("CF-Connecting-IP") + .map(|x| x.to_string()) + .unwrap_or_else(|| to_ip(request)) + } else { + to_ip(request) + } +} + +#[async_trait] +impl<'r> FromRequest<'r> for Ratelimiter { + type Error = Ratelimiter; + + async fn from_request<'a>(request: &'r rocket::Request<'a>) -> Outcome { + let ratelimiter = request + .local_cache_async(async { + use rocket::outcome::Outcome; + + let storage = request.guard::<&State>().await.unwrap(); + + let identifier = if let Outcome::Success(session) = request.guard::().await + { + session.id + } else { + to_real_ip(request) + }; + + let (bucket, resource) = storage.resolver.resolve_bucket(request); + let limit = storage.resolver.resolve_bucket_limit(bucket); + + Ratelimiter::from(&storage.map, &identifier, limit, (bucket, resource)) + }) + .await; + + match ratelimiter { + Ok(ratelimiter) => Outcome::Success(*ratelimiter), + Err(ratelimiter) => Outcome::Error((Status::TooManyRequests, *ratelimiter)), + } + } +} + +impl OpenApiFromRequest<'_> for Ratelimiter { + fn from_request_input( + _gen: &mut OpenApiGenerator, + _name: String, + _required: bool, + ) -> revolt_rocket_okapi::Result { + Ok(RequestHeaderInput::None) + } +} + +/// Attach ratelimiter to the Rocket application +pub struct RatelimitFairing; + +#[async_trait] +impl Fairing for RatelimitFairing { + fn info(&self) -> Info { + Info { + name: "Ratelimiter", + kind: Kind::Request | Kind::Response, + } + } + + async fn on_request(&self, request: &mut Request<'_>, _: &mut Data<'_>) { + use rocket::outcome::Outcome; + if let Outcome::Error(_) = request.guard::().await { + info!( + "User rate-limited on route {}! (IP = {:?})", + request.uri(), + to_real_ip(request) + ); + + request.set_method(Method::Get); + request.set_uri(Origin::parse("/ratelimit").unwrap()) + } + } + + async fn on_response<'r>(&self, request: &'r Request<'_>, response: &mut Response<'r>) { + let guard = request.guard::().await; + let (Outcome::Success(ratelimiter) | Outcome::Error((_, ratelimiter))) = guard else { + unreachable!() + }; + let Ratelimiter { + key, + limit, + remaining, + reset, + } = ratelimiter; + + response.set_raw_header("X-RateLimit-Limit", limit.to_string()); + response.set_raw_header("X-RateLimit-Bucket", key.to_string()); + response.set_raw_header("X-RateLimit-Remaining", remaining.to_string()); + response.set_raw_header("X-RateLimit-Reset-After", reset.to_string()); + + if guard.is_error() { + response.set_status(Status::TooManyRequests); + } + } +} + +#[async_trait] +impl<'r> FromRequest<'r> for RatelimitInformation { + type Error = u128; + + async fn from_request(request: &'r rocket::Request<'_>) -> Outcome { + let info = match request.guard::().await { + Outcome::Success(ratelimiter) => RatelimitInformation::Success(ratelimiter), + Outcome::Error((_, ratelimiter)) => RatelimitInformation::Failure { + retry_after: ratelimiter.reset, + }, + _ => unreachable!(), + }; + Outcome::Success(info) + } +} + +#[rocket::get("/ratelimit")] +fn ratelimit_info(info: RatelimitInformation) -> Json { + Json(info) +} + +pub fn routes() -> Vec { + rocket::routes![ratelimit_info] +} diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index d07b44bb9..889b11672 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -81,6 +81,7 @@ revolt-models = { path = "../core/models", features = [ revolt-presence = { path = "../core/presence" } revolt-result = { path = "../core/result", features = ["rocket", "okapi"] } revolt-permissions = { path = "../core/permissions", features = ["schemas"] } +revolt-ratelimits = { path = "../core/ratelimits", features = ["rocket"] } [build-dependencies] vergen = "7.5.0" diff --git a/crates/delta/src/main.rs b/crates/delta/src/main.rs index 9cce39ce4..6d0eaa605 100644 --- a/crates/delta/src/main.rs +++ b/crates/delta/src/main.rs @@ -11,6 +11,7 @@ pub mod util; use revolt_config::config; use revolt_database::events::client::EventV1; use revolt_database::AMQP; +use revolt_ratelimits::rocket as ratelimiter; use rocket::{Build, Rocket}; use rocket_cors::{AllowedOrigins, CorsOptions}; use rocket_prometheus::PrometheusMetrics; @@ -122,18 +123,22 @@ pub async fn web() -> Rocket { let rocket = rocket::build(); let prometheus = PrometheusMetrics::new(); + // Ratelimits + let ratelimits = ratelimiter::RatelimitStorage::new(util::ratelimits::DeltaRatelimits); + routes::mount(config, rocket) .attach(prometheus.clone()) .mount("/metrics", prometheus) .mount("/", rocket_cors::catch_all_options_routes()) - .mount("/", util::ratelimiter::routes()) + .mount("/", ratelimiter::routes()) .mount("/swagger/", swagger) .mount("/0.8/swagger/", swagger_0_8) .manage(authifier) .manage(db) .manage(amqp) .manage(cors.clone()) - .attach(util::ratelimiter::RatelimitFairing) + .manage(ratelimits) + .attach(ratelimiter::RatelimitFairing) .attach(cors) .configure(rocket::Config { limits: rocket::data::Limits::default().limit("string", 5.megabytes()), diff --git a/crates/delta/src/util/mod.rs b/crates/delta/src/util/mod.rs index 6ee3a7f68..61e6d0dae 100644 --- a/crates/delta/src/util/mod.rs +++ b/crates/delta/src/util/mod.rs @@ -1,2 +1,2 @@ -pub mod ratelimiter; +pub mod ratelimits; pub mod test; diff --git a/crates/delta/src/util/ratelimiter.rs b/crates/delta/src/util/ratelimiter.rs deleted file mode 100644 index 7d00e96dc..000000000 --- a/crates/delta/src/util/ratelimiter.rs +++ /dev/null @@ -1,347 +0,0 @@ -use std::collections::hash_map::DefaultHasher; -use std::hash::Hasher; -use std::ops::Add; -use std::time::{Duration, SystemTime, UNIX_EPOCH}; - -use authifier::models::Session; -use rocket::fairing::{Fairing, Info, Kind}; -use rocket::http::uri::Origin; -use rocket::http::{Method, Status}; -use rocket::request::{FromRequest, Outcome}; -use rocket::serde::json::Json; -use rocket::{Data, Request, Response}; - -use revolt_rocket_okapi::gen::OpenApiGenerator; -use revolt_rocket_okapi::request::{OpenApiFromRequest, RequestHeaderInput}; - -use serde::Serialize; - -use dashmap::DashMap; -use once_cell::sync::Lazy; - -/// Ratelimit Bucket -#[derive(Clone, Copy, Debug)] -struct Entry { - used: u8, - reset: u128, -} - -static MAP: Lazy> = Lazy::new(DashMap::new); - -/// Get the current time from Unix Epoch as a Duration -fn now() -> Duration { - SystemTime::now() - .duration_since(UNIX_EPOCH) - .expect("Time went backwards...") -} - -impl Entry { - /// Find bucket by its key - pub fn from(key: u64) -> Entry { - MAP.get(&key).map(|x| *x).unwrap_or_else(|| Entry { - used: 0, - reset: now().add(Duration::from_secs(10)).as_millis(), - }) - } - - /// Deduct one unit from the bucket and save - pub fn deduct(&mut self) { - let current_time = now().as_millis(); - if current_time > self.reset { - self.used = 1; - self.reset = now().add(Duration::from_secs(10)).as_millis(); - } else { - self.used += 1; - } - } - - /// Save information - pub fn save(self, key: u64) { - MAP.insert(key, self); - } - - /// Get remaining units in the bucket - pub fn get_remaining(&self, limit: u8) -> u8 { - if now().as_millis() > self.reset { - limit - } else { - limit - self.used - } - } - - /// Get how long bucket has until reset - pub fn left_until_reset(&self) -> u128 { - let current_time = now().as_millis(); - if current_time > self.reset { - 0 - } else { - self.reset - current_time - } - } -} - -/// Ratelimit Guard -#[derive(Serialize, Clone, Copy, Debug)] -#[allow(dead_code)] -pub struct Ratelimiter { - key: u64, - limit: u8, - remaining: u8, - reset: u128, -} - -/// Find bucket from given request -/// -/// Optionally, include a resource id to hash against. -fn resolve_bucket<'r>(request: &'r rocket::Request<'_>) -> (&'r str, Option<&'r str>) { - let (segment, resource, extra) = if matches!(request.routed_segment(0), Some("0.8")) { - ( - request.routed_segment(1), - request.routed_segment(2), - request.routed_segment(3), - ) - } else { - ( - request.routed_segment(0), - request.routed_segment(1), - request.routed_segment(2), - ) - }; - - if let Some(segment) = segment { - #[allow(clippy::redundant_locals)] - let resource = resource; - - let method = request.method(); - match (segment, resource, method) { - ("users", target, Method::Patch) => ("user_edit", target), - ("users", _, _) => { - if let Some("default_avatar") = extra { - return ("default_avatar", None); - } - - ("users", None) - } - ("bots", _, _) => ("bots", None), - ("channels", Some(id), _) => { - if request.method() == Method::Post { - if let Some("messages") = extra { - return ("messaging", Some(id)); - } - } - - ("channels", Some(id)) - } - ("servers", Some(id), _) => ("servers", Some(id)), - ("auth", _, _) => { - if request.method() == Method::Delete { - ("auth_delete", None) - } else { - ("auth", None) - } - } - ("swagger", _, _) => ("swagger", None), - ("safety", Some("report"), _) => ("safety_report", Some("report")), - ("safety", _, _) => ("safety", None), - _ => ("any", None), - } - } else { - ("any", None) - } -} - -/// Resolve per-bucket limits -fn resolve_bucket_limit(bucket: &str) -> u8 { - match bucket { - "user_edit" => 2, - "users" => 20, - "bots" => 10, - "messaging" => 10, - "channels" => 15, - "servers" => 5, - "auth" => 15, - "auth_delete" => 255, - "default_avatar" => 255, - "swagger" => 100, - "safety" => 15, - "safety_report" => 3, - _ => 20, - } -} - -/// Find the remote IP of the client -fn to_ip(request: &'_ rocket::Request<'_>) -> String { - request - .remote() - .map(|x| x.ip().to_string()) - .unwrap_or_default() -} - -/// Find the actual IP of the client -fn to_real_ip(request: &'_ rocket::Request<'_>) -> String { - if let Ok(true) = std::env::var("TRUST_CLOUDFLARE").map(|x| x == "1") { - request - .headers() - .get_one("CF-Connecting-IP") - .map(|x| x.to_string()) - .unwrap_or_else(|| to_ip(request)) - } else { - to_ip(request) - } -} - -impl Ratelimiter { - /// Generate guard from identifier and target bucket - pub fn from( - identifier: &str, - (bucket, resource): (&str, Option<&str>), - ) -> Result { - let mut key = DefaultHasher::new(); - key.write(identifier.as_bytes()); - key.write(bucket.as_bytes()); - - if let Some(id) = resource { - key.write(id.as_bytes()); - } - - let key = key.finish(); - let limit = resolve_bucket_limit(bucket); - let mut entry = Entry::from(key); - - let remaining = entry.get_remaining(limit); - let reset = entry.left_until_reset(); - let mut ratelimiter = Ratelimiter { - key, - limit, - remaining, - reset, - }; - if remaining == 0 { - return Err(ratelimiter); - } - - entry.deduct(); - entry.save(key); - ratelimiter.remaining -= 1; - ratelimiter.reset = entry.left_until_reset(); - - Ok(ratelimiter) - } -} - -#[async_trait] -impl<'r> FromRequest<'r> for Ratelimiter { - type Error = Ratelimiter; - - async fn from_request(request: &'r rocket::Request<'_>) -> Outcome { - let ratelimiter = request - .local_cache_async(async { - use rocket::outcome::Outcome; - let identifier = if let Outcome::Success(session) = request.guard::().await - { - session.id - } else { - to_real_ip(request) - }; - - Ratelimiter::from(&identifier, resolve_bucket(request)) - }) - .await; - - match ratelimiter { - Ok(ratelimiter) => Outcome::Success(*ratelimiter), - Err(ratelimiter) => Outcome::Error((Status::TooManyRequests, *ratelimiter)), - } - } -} - -impl OpenApiFromRequest<'_> for Ratelimiter { - fn from_request_input( - _gen: &mut OpenApiGenerator, - _name: String, - _required: bool, - ) -> revolt_rocket_okapi::Result { - Ok(RequestHeaderInput::None) - } -} - -/// Attach ratelimiter to the Rocket application -pub struct RatelimitFairing; - -#[rocket::async_trait] -impl Fairing for RatelimitFairing { - fn info(&self) -> Info { - Info { - name: "Ratelimiter", - kind: Kind::Request | Kind::Response, - } - } - - async fn on_request(&self, request: &mut Request<'_>, _: &mut Data<'_>) { - use rocket::outcome::Outcome; - if let Outcome::Error(_) = request.guard::().await { - info!( - "User rate-limited on route {}! (IP = {:?})", - request.uri(), - to_real_ip(request) - ); - - request.set_method(Method::Get); - request.set_uri(Origin::parse("/ratelimit").unwrap()) - } - } - - async fn on_response<'r>(&self, request: &'r Request<'_>, response: &mut Response<'r>) { - let guard = request.guard::().await; - let (Outcome::Success(ratelimiter) | Outcome::Error((_, ratelimiter))) = guard else { - unreachable!() - }; - let Ratelimiter { - key, - limit, - remaining, - reset, - } = ratelimiter; - - response.set_raw_header("X-RateLimit-Limit", limit.to_string()); - response.set_raw_header("X-RateLimit-Bucket", key.to_string()); - response.set_raw_header("X-RateLimit-Remaining", remaining.to_string()); - response.set_raw_header("X-RateLimit-Reset-After", reset.to_string()); - - if guard.is_error() { - response.set_status(Status::TooManyRequests); - } - } -} - -#[derive(Serialize)] -#[serde(untagged)] -pub enum RatelimitInformation { - Success(Ratelimiter), - Failure { retry_after: u128 }, -} - -#[async_trait] -impl<'r> FromRequest<'r> for RatelimitInformation { - type Error = u128; - - async fn from_request(request: &'r rocket::Request<'_>) -> Outcome { - let info = match request.guard::().await { - Outcome::Success(ratelimiter) => RatelimitInformation::Success(ratelimiter), - Outcome::Error((_, ratelimiter)) => RatelimitInformation::Failure { - retry_after: ratelimiter.reset, - }, - _ => unreachable!(), - }; - Outcome::Success(info) - } -} - -#[rocket::get("/ratelimit")] -fn ratelimit_info(info: RatelimitInformation) -> Json { - Json(info) -} - -pub fn routes() -> Vec { - rocket::routes![ratelimit_info] -} diff --git a/crates/delta/src/util/ratelimits.rs b/crates/delta/src/util/ratelimits.rs new file mode 100644 index 000000000..178d15d23 --- /dev/null +++ b/crates/delta/src/util/ratelimits.rs @@ -0,0 +1,81 @@ +use revolt_ratelimits::ratelimiter::RatelimitResolver; +use rocket::{http::Method, Request}; + +pub struct DeltaRatelimits; + +impl<'a> RatelimitResolver> for DeltaRatelimits { + fn resolve_bucket<'r>(&self, request: &'r Request<'_>) -> (&'r str, Option<&'r str>) { + let (segment, resource, extra) = if request.routed_segment(0) == Some("0.8") { + ( + request.routed_segment(1), + request.routed_segment(2), + request.routed_segment(3), + ) + } else { + ( + request.routed_segment(0), + request.routed_segment(1), + request.routed_segment(2), + ) + }; + + if let Some(segment) = segment { + #[allow(clippy::redundant_locals)] + let resource = resource; + + let method = request.method(); + match (segment, resource, method) { + ("users", target, Method::Patch) => ("user_edit", target), + ("users", _, _) => { + if let Some("default_avatar") = extra { + return ("default_avatar", None); + } + + ("users", None) + } + ("bots", _, _) => ("bots", None), + ("channels", Some(id), _) => { + if request.method() == Method::Post { + if let Some("messages") = extra { + return ("messaging", Some(id)); + } + } + + ("channels", Some(id)) + } + ("servers", Some(id), _) => ("servers", Some(id)), + ("auth", _, _) => { + if request.method() == Method::Delete { + ("auth_delete", None) + } else { + ("auth", None) + } + } + ("swagger", _, _) => ("swagger", None), + ("safety", Some("report"), _) => ("safety_report", Some("report")), + ("safety", _, _) => ("safety", None), + _ => ("any", None), + } + } else { + ("any", None) + } + } + + fn resolve_bucket_limit(&self, bucket: &str) -> u32 { + match bucket { + "user_edit" => 2, + "users" => 20, + "bots" => 10, + "messaging" => 10, + "channels" => 15, + "servers" => 5, + "auth" => 15, + "auth_delete" => 255, + "default_avatar" => 255, + "swagger" => 100, + "safety" => 15, + "safety_report" => 3, + _ => 20, + } + } +} diff --git a/crates/services/autumn/Cargo.toml b/crates/services/autumn/Cargo.toml index 464da056f..3514f501d 100644 --- a/crates/services/autumn/Cargo.toml +++ b/crates/services/autumn/Cargo.toml @@ -52,6 +52,7 @@ revolt-result = { version = "0.8.8", path = "../../core/result", features = [ "utoipa", "axum", ] } +revolt-ratelimits = { version = "0.8.8", path = "../../core/ratelimits", features = ["axum"] } # Axum / web server tempfile = "3.12.0" diff --git a/crates/services/autumn/src/api.rs b/crates/services/autumn/src/api.rs index d068c2dcd..5c5671467 100644 --- a/crates/services/autumn/src/api.rs +++ b/crates/services/autumn/src/api.rs @@ -25,10 +25,10 @@ use tokio::time::Instant; use tower_http::cors::{AllowHeaders, Any, CorsLayer}; use utoipa::ToSchema; -use crate::{exif::strip_metadata, metadata::generate_metadata, mime_type::determine_mime_type}; +use crate::{exif::strip_metadata, metadata::generate_metadata, mime_type::determine_mime_type, AppState}; /// Build the API router -pub async fn router() -> Router { +pub async fn router() -> Router { let config = config().await; let cors = CorsLayer::new() diff --git a/crates/services/autumn/src/main.rs b/crates/services/autumn/src/main.rs index ff29b2e3d..cb936e0cd 100644 --- a/crates/services/autumn/src/main.rs +++ b/crates/services/autumn/src/main.rs @@ -1,8 +1,10 @@ use std::net::{Ipv4Addr, SocketAddr}; -use axum::Router; +use axum::{middleware::from_fn_with_state, Router}; -use revolt_database::DatabaseInfo; +use axum_macros::FromRef; +use revolt_database::{Database, DatabaseInfo}; +use revolt_ratelimits::axum as ratelimiter; use tokio::net::TcpListener; use utoipa::{ openapi::security::{ApiKey, ApiKeyValue, SecurityScheme}, @@ -15,6 +17,13 @@ pub mod clamav; pub mod exif; pub mod metadata; pub mod mime_type; +mod ratelimits; + +#[derive(FromRef, Clone)] +struct AppState { + database: Database, + ratelimit_storage: ratelimiter::RatelimitStorage, +} #[tokio::main] async fn main() -> Result<(), std::io::Error> { @@ -69,12 +78,23 @@ async fn main() -> Result<(), std::io::Error> { // Connect to the database let db = DatabaseInfo::Auto.connect().await.unwrap(); + let ratelimits = ratelimiter::RatelimitStorage::new(ratelimits::AutumnRatelimits); + + let state = AppState { + database: db, + ratelimit_storage: ratelimits, + }; // Configure Axum and router let app = Router::new() .merge(Scalar::with_url("/scalar", ApiDoc::openapi())) .nest("/", api::router().await) - .with_state(db); + .nest("/", ratelimiter::routes()) + .layer(from_fn_with_state( + state.clone(), + ratelimiter::ratelimit_middleware, + )) + .with_state(state); // Configure TCP listener and bind let address = SocketAddr::from((Ipv4Addr::UNSPECIFIED, 14704)); diff --git a/crates/services/autumn/src/ratelimits.rs b/crates/services/autumn/src/ratelimits.rs new file mode 100644 index 000000000..609d8e1ec --- /dev/null +++ b/crates/services/autumn/src/ratelimits.rs @@ -0,0 +1,28 @@ +use axum::http::{request::Parts, Method}; +use revolt_ratelimits::ratelimiter::RatelimitResolver; + +pub struct AutumnRatelimits; + +impl RatelimitResolver for AutumnRatelimits { + fn resolve_bucket<'a>(&self, parts: &'a Parts) -> (&'a str, Option<&'a str>) { + let path = parts + .uri + .path() + .trim_matches('/') + .split_terminator("/") + .collect::>(); + + match (&parts.method, path.as_slice()) { + (&Method::POST, &[tag]) => ("upload", Some(tag)), + _ => ("any", None), + } + } + + fn resolve_bucket_limit(&self, bucket: &str) -> u32 { + match bucket { + "upload" => 10, + "any" => u32::MAX, + _ => unreachable!("Bucket defined but no limit set"), + } + } +} From cc7a7962a882e1627fcd0bc75858a017415e8cfc Mon Sep 17 00:00:00 2001 From: Zomatree Date: Thu, 18 Sep 2025 21:09:53 +0100 Subject: [PATCH 006/211] fix: use `trust_cloudflare` config value instead of env var --- Cargo.lock | 1 + crates/core/ratelimits/Cargo.toml | 1 + crates/core/ratelimits/src/axum.rs | 7 ++++--- crates/core/ratelimits/src/rocket.rs | 9 +++++---- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ca1011677..96b913846 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6575,6 +6575,7 @@ dependencies = [ "axum", "dashmap", "log", + "revolt-config", "revolt-database", "revolt-result", "revolt_rocket_okapi", diff --git a/crates/core/ratelimits/Cargo.toml b/crates/core/ratelimits/Cargo.toml index 49110e1ef..05e1e362d 100644 --- a/crates/core/ratelimits/Cargo.toml +++ b/crates/core/ratelimits/Cargo.toml @@ -12,6 +12,7 @@ default = ["rocket", "axum"] [dependencies] revolt-database = { version = "0.8.8", path = "../database"} revolt-result = { version = "0.8.8", path = "../result" } +revolt-config = { version = "0.8.8", path = "../config" } rocket = { version = "0.5.1", optional = true } revolt_rocket_okapi = { version = "0.10.0", optional = true } diff --git a/crates/core/ratelimits/src/axum.rs b/crates/core/ratelimits/src/axum.rs index 39b0c3bb6..f50cf8671 100644 --- a/crates/core/ratelimits/src/axum.rs +++ b/crates/core/ratelimits/src/axum.rs @@ -11,6 +11,7 @@ use axum::{ routing::get, }; use revolt_database::{Database, User}; +use revolt_config::config; use crate::ratelimiter::{RatelimitInformation, Ratelimiter, RequestKind}; @@ -31,8 +32,8 @@ fn to_ip(parts: &Parts) -> String { .unwrap_or_default() } -fn to_real_ip(parts: &Parts) -> String { - if let Ok(true) = std::env::var("TRUST_CLOUDFLARE").map(|x| x == "1") { +async fn to_real_ip(parts: &Parts) -> String { + if config().await.api.security.trust_cloudflare { parts .headers .get("CF-Connecting-IP") @@ -62,7 +63,7 @@ where let identifier = if let Ok(user) = parts.extract_with_state::(state).await { user.id } else { - to_real_ip(parts) + to_real_ip(parts).await }; let (bucket, resource) = storage.resolver.resolve_bucket(parts); diff --git a/crates/core/ratelimits/src/rocket.rs b/crates/core/ratelimits/src/rocket.rs index 6e7a0c9d8..046317bd4 100644 --- a/crates/core/ratelimits/src/rocket.rs +++ b/crates/core/ratelimits/src/rocket.rs @@ -6,6 +6,7 @@ use rocket::http::{Method, Status}; use rocket::request::{FromRequest, Outcome}; use rocket::serde::json::Json; use rocket::{Data, Request, Response, State}; +use revolt_config::config; use revolt_rocket_okapi::r#gen::OpenApiGenerator; use revolt_rocket_okapi::request::{OpenApiFromRequest, RequestHeaderInput}; @@ -33,8 +34,8 @@ fn to_ip(request: &'_ rocket::Request<'_>) -> String { } /// Find the actual IP of the client -fn to_real_ip(request: &'_ rocket::Request<'_>) -> String { - if let Ok(true) = std::env::var("TRUST_CLOUDFLARE").map(|x| x == "1") { +async fn to_real_ip(request: &'_ rocket::Request<'_>) -> String { + if config().await.api.security.trust_cloudflare { request .headers() .get_one("CF-Connecting-IP") @@ -60,7 +61,7 @@ impl<'r> FromRequest<'r> for Ratelimiter { { session.id } else { - to_real_ip(request) + to_real_ip(request).await }; let (bucket, resource) = storage.resolver.resolve_bucket(request); @@ -105,7 +106,7 @@ impl Fairing for RatelimitFairing { info!( "User rate-limited on route {}! (IP = {:?})", request.uri(), - to_real_ip(request) + to_real_ip(request).await ); request.set_method(Method::Get); From bfe4018e436a4075bae780dd4d35a9b58315e12f Mon Sep 17 00:00:00 2001 From: Zomatree Date: Fri, 19 Sep 2025 02:41:53 +0100 Subject: [PATCH 007/211] fix: apple music to use original url instead of metadata url Apple Music returns the url without the query parameter in the opengraph meta tags, causing the regex to not find the track id, meaning any embed links generated would only link to the album. --- crates/services/january/src/website_embed.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/services/january/src/website_embed.rs b/crates/services/january/src/website_embed.rs index 49ac2846e..25de15372 100644 --- a/crates/services/january/src/website_embed.rs +++ b/crates/services/january/src/website_embed.rs @@ -312,7 +312,7 @@ pub async fn populate_special(original_url: String, metadata: &mut WebsiteMetada Some(Special::GIF) } else { RE_APPLE_MUSIC - .captures_iter(url) + .captures_iter(&original_url) .next() .map(|captures| Special::AppleMusic { album_id: captures[1].to_string(), From b0c977b324b8144c1152589546eb8fec5954c3e7 Mon Sep 17 00:00:00 2001 From: Zomatree Date: Fri, 8 Aug 2025 00:16:20 +0100 Subject: [PATCH 008/211] feat: initial work on tenor gif searching --- .github/workflows/docker.yaml | 20 + Cargo.lock | 1146 +++++++++++---------- README.md | 5 + crates/core/coalesced/Cargo.toml | 22 + crates/core/coalesced/LICENSE | 9 + crates/core/coalesced/src/config.rs | 23 + crates/core/coalesced/src/error.rs | 20 + crates/core/coalesced/src/lib.rs | 7 + crates/core/coalesced/src/service.rs | 168 +++ crates/core/config/Revolt.toml | 3 + crates/core/config/src/lib.rs | 2 + crates/services/gifbox/Cargo.toml | 40 + crates/services/gifbox/Dockerfile | 12 + crates/services/gifbox/src/api.rs | 64 ++ crates/services/gifbox/src/main.rs | 65 ++ crates/services/gifbox/src/tenor/mod.rs | 129 +++ crates/services/gifbox/src/tenor/types.rs | 36 + scripts/build-image-layer.sh | 9 +- scripts/publish-debug-image.sh | 2 + scripts/start.sh | 6 +- 20 files changed, 1266 insertions(+), 522 deletions(-) create mode 100644 crates/core/coalesced/Cargo.toml create mode 100644 crates/core/coalesced/LICENSE create mode 100644 crates/core/coalesced/src/config.rs create mode 100644 crates/core/coalesced/src/error.rs create mode 100644 crates/core/coalesced/src/lib.rs create mode 100644 crates/core/coalesced/src/service.rs create mode 100644 crates/services/gifbox/Cargo.toml create mode 100644 crates/services/gifbox/Dockerfile create mode 100644 crates/services/gifbox/src/api.rs create mode 100644 crates/services/gifbox/src/main.rs create mode 100644 crates/services/gifbox/src/tenor/mod.rs create mode 100644 crates/services/gifbox/src/tenor/types.rs diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index fccaf6341..f0a79f53d 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -152,6 +152,26 @@ jobs: BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest labels: ${{ steps.meta-january.outputs.labels }} + # revoltchat/gifbox + - name: Docker meta + id: meta-gifbox + uses: docker/metadata-action@v4 + with: + images: | + docker.io/revoltchat/gifbox + ghcr.io/revoltchat/gifbox + - name: Publish + uses: docker/build-push-action@v4 + with: + context: . + push: true + platforms: linux/amd64,linux/arm64 + file: crates/services/gifbox/Dockerfile + tags: ${{ steps.meta-gifbox.outputs.tags }} + build-args: | + BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest + labels: ${{ steps.meta-gifbox.outputs.labels }} + # revoltchat/crond - name: Docker meta id: meta-crond diff --git a/Cargo.lock b/Cargo.lock index 96b913846..efcf2cb1a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -125,12 +125,6 @@ dependencies = [ "tokio 1.47.1", ] -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - [[package]] name = "android_system_properties" version = "0.1.5" @@ -142,18 +136,18 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.98" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" +checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" dependencies = [ "backtrace", ] [[package]] name = "arbitrary" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" [[package]] name = "arc-swap" @@ -169,7 +163,7 @@ checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -219,9 +213,9 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.13.2" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb812ffb58524bdd10860d7d974e2f01cc0950c2438a74ee5ec2e2280c6c4ffa" +checksum = "497c00e0fd83a72a79a39fcbd8e3e2f055d6f6c7e025f3b3d91f4f8e76527fb8" dependencies = [ "async-task", "concurrent-queue", @@ -250,20 +244,20 @@ dependencies = [ [[package]] name = "async-io" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19634d6336019ef220f09fd31168ce5c184b295cbf80345437cc36094ef223ca" +checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" dependencies = [ - "async-lock 3.4.1", + "autocfg 1.5.0", "cfg-if", "concurrent-queue", "futures-io", "futures-lite 2.6.1", "parking", - "polling 3.10.0", - "rustix 1.0.8", + "polling 3.11.0", + "rustix", "slab", - "windows-sys 0.60.2", + "windows-sys 0.61.0", ] [[package]] @@ -288,9 +282,9 @@ dependencies = [ [[package]] name = "async-process" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65daa13722ad51e6ab1a1b9c01299142bc75135b337923cfa10e79bbbd669f00" +checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75" dependencies = [ "async-channel 2.5.0", "async-io", @@ -301,7 +295,7 @@ dependencies = [ "cfg-if", "event-listener 5.4.1", "futures-lite 2.6.1", - "rustix 1.0.8", + "rustix", ] [[package]] @@ -312,14 +306,14 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] name = "async-signal" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f567af260ef69e1d52c2b560ce0ea230763e6fbb9214a85d768760a920e3e3c1" +checksum = "43c070bbf59cd3570b6b2dd54cd772527c7c3620fce8be898406dd3ed6adc64c" dependencies = [ "async-io", "async-lock 3.4.1", @@ -327,17 +321,17 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix 1.0.8", + "rustix", "signal-hook-registry", "slab", - "windows-sys 0.60.2", + "windows-sys 0.61.0", ] [[package]] name = "async-std" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "730294c1c08c2e0f85759590518f6333f0d5a0a766a27d519c1b244c3dfd8a24" +checksum = "2c8e079a4ab67ae52b7403632e4618815d6db36d2a010cfe41b02c1b1578f93b" dependencies = [ "async-attributes", "async-channel 1.9.0", @@ -380,7 +374,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -391,13 +385,13 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.88" +version = "0.1.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -518,18 +512,18 @@ dependencies = [ [[package]] name = "avif-serialize" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ea8ef51aced2b9191c08197f55450d830876d9933f8f48a429b354f1d496b42" +checksum = "47c8fbc0f831f4519fe8b810b6a7a91410ec83031b8233f730a0480029f6a23f" dependencies = [ "arrayvec", ] [[package]] name = "aws-config" -version = "1.8.4" +version = "1.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "483020b893cdef3d89637e428d588650c71cfae7ea2e6ecbaee4de4ff99fb2dd" +checksum = "8bc1b40fb26027769f16960d2f4a6bc20c4bb755d403e552c8c1a73af433c246" dependencies = [ "aws-credential-types", "aws-runtime", @@ -557,9 +551,9 @@ dependencies = [ [[package]] name = "aws-credential-types" -version = "1.2.5" +version = "1.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1541072f81945fa1251f8795ef6c92c4282d74d59f88498ae7d4bf00f0ebdad9" +checksum = "d025db5d9f52cbc413b167136afb3d8aeea708c0d8884783cf6253be5e22f6f2" dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api", @@ -569,9 +563,9 @@ dependencies = [ [[package]] name = "aws-lc-rs" -version = "1.13.3" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c953fe1ba023e6b7730c0d4b031d06f267f23a46167dcbd40316644b10a17ba" +checksum = "94b8ff6c09cd57b16da53641caa860168b88c172a5ee163b0288d3d6eea12786" dependencies = [ "aws-lc-sys", "zeroize", @@ -579,9 +573,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.30.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbfd150b5dbdb988bcc8fb1fe787eb6b7ee6180ca24da683b61ea5405f3d43ff" +checksum = "0e44d16778acaf6a9ec9899b92cebd65580b83f685446bf2e1f5d3d732f99dcd" dependencies = [ "bindgen", "cc", @@ -617,9 +611,9 @@ dependencies = [ [[package]] name = "aws-sdk-s3" -version = "1.101.0" +version = "1.106.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b16efa59a199f5271bf21ab3e570c5297d819ce4f240e6cf0096d1dc0049c44" +checksum = "2c230530df49ed3f2b7b4d9c8613b72a04cdac6452eede16d587fc62addfabac" dependencies = [ "aws-credential-types", "aws-runtime", @@ -651,9 +645,9 @@ dependencies = [ [[package]] name = "aws-sdk-sso" -version = "1.79.0" +version = "1.84.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a847168f15b46329fa32c7aca4e4f1a2e072f9b422f0adb19756f2e1457f111" +checksum = "357a841807f6b52cb26123878b3326921e2a25faca412fabdd32bd35b7edd5d3" dependencies = [ "aws-credential-types", "aws-runtime", @@ -673,9 +667,9 @@ dependencies = [ [[package]] name = "aws-sdk-ssooidc" -version = "1.80.0" +version = "1.85.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b654dd24d65568738593e8239aef279a86a15374ec926ae8714e2d7245f34149" +checksum = "67e05f33b6c9026fecfe9b3b6740f34d41bc6ff641a6a32dabaab60209245b75" dependencies = [ "aws-credential-types", "aws-runtime", @@ -695,9 +689,9 @@ dependencies = [ [[package]] name = "aws-sdk-sts" -version = "1.81.0" +version = "1.86.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c92ea8a7602321c83615c82b408820ad54280fb026e92de0eeea937342fafa24" +checksum = "e7d835f123f307cafffca7b9027c14979f1d403b417d8541d67cf252e8a21e35" dependencies = [ "aws-credential-types", "aws-runtime", @@ -757,9 +751,9 @@ dependencies = [ [[package]] name = "aws-smithy-checksums" -version = "0.63.6" +version = "0.63.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9054b4cc5eda331cde3096b1576dec45365c5cbbca61d1fffa5f236e251dfce7" +checksum = "56d2df0314b8e307995a3b86d44565dfe9de41f876901a7d71886c756a25979f" dependencies = [ "aws-smithy-http", "aws-smithy-types", @@ -777,9 +771,9 @@ dependencies = [ [[package]] name = "aws-smithy-eventstream" -version = "0.60.10" +version = "0.60.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604c7aec361252b8f1c871a7641d5e0ba3a7f5a586e51b66bc9510a5519594d9" +checksum = "182b03393e8c677347fb5705a04a9392695d47d20ef0a2f8cfe28c8e6b9b9778" dependencies = [ "aws-smithy-types", "bytes 1.10.1", @@ -809,20 +803,20 @@ dependencies = [ [[package]] name = "aws-smithy-http-client" -version = "1.0.6" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f108f1ca850f3feef3009bdcc977be201bca9a91058864d9de0684e64514bee0" +checksum = "147e8eea63a40315d704b97bf9bc9b8c1402ae94f89d5ad6f7550d963309da1b" dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api", "aws-smithy-types", "h2 0.3.27", - "h2 0.4.11", + "h2 0.4.12", "http 0.2.12", "http 1.3.1", "http-body 0.4.6", "hyper 0.14.32", - "hyper 1.6.0", + "hyper 1.7.0", "hyper-rustls 0.24.2", "hyper-rustls 0.27.7", "hyper-util", @@ -832,15 +826,16 @@ dependencies = [ "rustls-native-certs 0.8.1", "rustls-pki-types", "tokio 1.47.1", + "tokio-rustls 0.26.2", "tower", "tracing", ] [[package]] name = "aws-smithy-json" -version = "0.61.4" +version = "0.61.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a16e040799d29c17412943bdbf488fd75db04112d0c0d4b9290bacf5ae0014b9" +checksum = "eaa31b350998e703e9826b2104dd6f63be0508666e1aba88137af060e8944047" dependencies = [ "aws-smithy-types", ] @@ -866,9 +861,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime" -version = "1.8.6" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e107ce0783019dbff59b3a244aa0c114e4a8c9d93498af9162608cd5474e796" +checksum = "4fa63ad37685ceb7762fa4d73d06f1d5493feb88e3f27259b9ed277f4c01b185" dependencies = [ "aws-smithy-async", "aws-smithy-http", @@ -890,9 +885,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime-api" -version = "1.8.7" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75d52251ed4b9776a3e8487b2a01ac915f73b2da3af8fc1e77e0fce697a550d4" +checksum = "07f5e0fc8a6b3f2303f331b94504bbf754d85488f402d6f1dd7a6080f99afe56" dependencies = [ "aws-smithy-async", "aws-smithy-types", @@ -968,7 +963,7 @@ dependencies = [ "http 1.3.1", "http-body 1.0.1", "http-body-util", - "hyper 1.6.0", + "hyper 1.7.0", "hyper-util", "itoa", "matchit", @@ -1043,7 +1038,7 @@ checksum = "57d123550fa8d071b7255cb0cc04dc302baa6c8c4a79f55701552684d8399bce" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -1075,7 +1070,7 @@ dependencies = [ "heck", "proc-macro-error", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", "ubyte", ] @@ -1169,16 +1164,14 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.69.5" +version = "0.72.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" +checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "cexpr", "clang-sys", - "itertools", - "lazy_static", - "lazycell", + "itertools 0.13.0", "log", "prettyplease", "proc-macro2", @@ -1186,8 +1179,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.104", - "which", + "syn 2.0.106", ] [[package]] @@ -1198,9 +1190,9 @@ checksum = "0669d5a35b64fdb5ab7fb19cae13148b6b5cbdf4b8247faf54ece47f699c8cef" [[package]] name = "bit_field" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" +checksum = "1e4b40c7323adcfc0a41c4b88143ed58346ff65a288fc144329c5c45e05d70c6" [[package]] name = "bitfield" @@ -1216,9 +1208,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.1" +version = "2.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" [[package]] name = "bitstream-io" @@ -1283,7 +1275,7 @@ dependencies = [ "getrandom 0.2.16", "getrandom 0.3.3", "hex", - "indexmap 2.10.0", + "indexmap 2.11.1", "js-sys", "once_cell", "rand 0.9.2", @@ -1308,9 +1300,9 @@ checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "bytemuck" -version = "1.23.1" +version = "1.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422" +checksum = "3995eaeebcdf32f91f980d360f78732ddc061097ab4e39991ae7a6ace9194677" [[package]] name = "byteorder" @@ -1390,10 +1382,11 @@ checksum = "a2698f953def977c68f935bb0dfa959375ad4638570e969e2f1e9f433cbf1af6" [[package]] name = "cc" -version = "1.2.31" +version = "1.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3a42d84bb6b69d3a8b3eaacf0d88f179e1929695e1ad012b6cf64d9caaa5fd2" +checksum = "65193589c6404eb80b450d618eaf9a2cafaaafd57ecce47370519ef674a7bd44" dependencies = [ + "find-msvc-tools", "jobserver", "libc", "shlex", @@ -1431,23 +1424,22 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" [[package]] name = "chrono" -version = "0.4.41" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ - "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "serde", "wasm-bindgen", - "windows-link", + "windows-link 0.2.0", ] [[package]] @@ -1803,7 +1795,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -1823,24 +1815,24 @@ dependencies = [ [[package]] name = "curl" -version = "0.4.48" +version = "0.4.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e2d5c8f48d9c0c23250e52b55e82a6ab4fdba6650c931f5a0a57a43abda812b" +checksum = "79fc3b6dd0b87ba36e565715bf9a2ced221311db47bd18011676f24a6066edbc" dependencies = [ "curl-sys", "libc", "openssl-probe", "openssl-sys", "schannel", - "socket2 0.5.10", + "socket2 0.6.0", "windows-sys 0.59.0", ] [[package]] name = "curl-sys" -version = "0.4.82+curl-8.14.1" +version = "0.4.83+curl-8.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4d63638b5ec65f1a4ae945287b3fd035be4554bbaf211901159c9a2a74fb5be" +checksum = "5830daf304027db10c82632a464879d46a3f7c4ba17a31592657ad16c719b483" dependencies = [ "cc", "libc", @@ -1921,7 +1913,7 @@ dependencies = [ "proc-macro2", "quote 1.0.40", "strsim 0.11.1", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -1954,7 +1946,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core 0.20.11", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -1978,9 +1970,9 @@ checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" [[package]] name = "data-url" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a" +checksum = "be1e0bca6c3637f992fc1cc7cbc52a78c1ef6db076dbf1059c4323d6a2048376" [[package]] name = "deadqueue" @@ -2054,9 +2046,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.4.0" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +checksum = "d630bccd429a5bb5a64b5e94f693bfc48c9f8566418fda4c494cc94f911f87cc" dependencies = [ "powerfmt", "serde", @@ -2070,18 +2062,18 @@ checksum = "d65d7ce8132b7c0e54497a4d9a55a1c2a0912a0d786cf894472ba818fba45762" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] name = "derive-where" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "510c292c8cf384b1a340b816a9a6cf2599eb8f566a44949024af88418000c50b" +checksum = "ef941ded77d15ca19b40374869ac6000af1c9f2a4c0f3d4c70926287e6364a8f" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -2094,7 +2086,7 @@ dependencies = [ "proc-macro2", "quote 1.0.40", "rustc_version", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -2123,11 +2115,11 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b035a542cf7abf01f2e3c4d5a7acbaebfefe120ae4efc7bde3df98186e4b8af7" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "proc-macro2", "proc-macro2-diagnostics", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -2150,7 +2142,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -2327,7 +2319,7 @@ dependencies = [ "heck", "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -2341,13 +2333,13 @@ dependencies = [ [[package]] name = "enum-iterator-derive" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" +checksum = "685adfa4d6f3d765a26bc5dbc936577de9abf756c1feeb3089b01dd395034842" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -2380,7 +2372,7 @@ checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -2400,12 +2392,12 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.0", ] [[package]] @@ -2474,6 +2466,26 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +[[package]] +name = "fax" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05de7d48f37cd6730705cbca900770cab77a89f413d23e100ad7fad7795a0ab" +dependencies = [ + "fax_derive", +] + +[[package]] +name = "fax_derive" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0aca10fb742cb43f9e7bb8467c91aa9bcb8e3ffbc6a6f7389bb93ffc920577d" +dependencies = [ + "proc-macro2", + "quote 1.0.40", + "syn 2.0.106", +] + [[package]] name = "fcm_v1" version = "0.3.0" @@ -2540,6 +2552,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "find-msvc-tools" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fd99930f64d146689264c637b5af2f0233a933bef0d8570e2526bf9e083192d" + [[package]] name = "findshlibs" version = "0.10.2" @@ -2623,9 +2641,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] @@ -2779,7 +2797,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -2842,9 +2860,9 @@ dependencies = [ [[package]] name = "generator" -version = "0.8.5" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d18470a76cb7f8ff746cf1f7470914f900252ec36bbc40b569d74b1258446827" +checksum = "605183a538e3e2a9c1038635cc5c2d194e2ee8fd0d1b66b8349fad7dbacce5a2" dependencies = [ "cc", "cfg-if", @@ -2876,9 +2894,9 @@ dependencies = [ [[package]] name = "getopts" -version = "0.2.23" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cba6ae63eb948698e300f645f87c70f76630d505f23b8907cf1e193ee85048c1" +checksum = "cfe4fbac503b8d1f88e6676011885f34b7174f46e59956bba534ba83abded4df" dependencies = [ "unicode-width", ] @@ -2906,7 +2924,7 @@ dependencies = [ "js-sys", "libc", "r-efi", - "wasi 0.14.2+wasi-0.2.4", + "wasi 0.14.5+wasi-0.2.4", "wasm-bindgen", ] @@ -2919,7 +2937,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -2963,9 +2981,9 @@ dependencies = [ [[package]] name = "glob" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "gloo-timers" @@ -3013,7 +3031,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.10.0", + "indexmap 2.11.1", "slab", "tokio 1.47.1", "tokio-util", @@ -3022,9 +3040,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17da50a276f1e01e0ba6c029e47b7100754904ee8a278f886546e98575380785" +checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" dependencies = [ "atomic-waker", "bytes 1.10.1", @@ -3032,7 +3050,7 @@ dependencies = [ "futures-core", "futures-sink", "http 1.3.1", - "indexmap 2.10.0", + "indexmap 2.11.1", "slab", "tokio 1.47.1", "tokio-util", @@ -3090,9 +3108,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.4" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ "allocator-api2", "equivalent", @@ -3163,7 +3181,7 @@ dependencies = [ "futures-channel", "futures-io", "futures-util", - "idna 1.0.3", + "idna 1.1.0", "ipnet", "once_cell", "rand 0.8.5", @@ -3237,15 +3255,6 @@ dependencies = [ "digest", ] -[[package]] -name = "home" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" -dependencies = [ - "windows-sys 0.59.0", -] - [[package]] name = "hostname" version = "0.3.1" @@ -3268,7 +3277,7 @@ dependencies = [ "markup5ever", "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -3374,20 +3383,22 @@ dependencies = [ [[package]] name = "hyper" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" +checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" dependencies = [ + "atomic-waker", "bytes 1.10.1", "futures-channel", - "futures-util", - "h2 0.4.11", + "futures-core", + "h2 0.4.12", "http 1.3.1", "http-body 1.0.1", "httparse", "httpdate", "itoa", "pin-project-lite 0.2.16", + "pin-utils", "smallvec", "tokio 1.47.1", "want", @@ -3417,7 +3428,7 @@ checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" dependencies = [ "futures-util", "http 1.3.1", - "hyper 1.6.0", + "hyper 1.7.0", "hyper-util", "rustls 0.22.4", "rustls-pki-types", @@ -3434,7 +3445,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" dependencies = [ "http 1.3.1", - "hyper 1.6.0", + "hyper 1.7.0", "hyper-util", "rustls 0.23.31", "rustls-native-certs 0.8.1", @@ -3465,7 +3476,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes 1.10.1", "http-body-util", - "hyper 1.6.0", + "hyper 1.7.0", "hyper-util", "native-tls", "tokio 1.47.1", @@ -3486,7 +3497,7 @@ dependencies = [ "futures-util", "http 1.3.1", "http-body 1.0.1", - "hyper 1.6.0", + "hyper 1.7.0", "ipnet", "libc", "percent-encoding", @@ -3501,9 +3512,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.63" +version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -3511,7 +3522,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core", + "windows-core 0.62.0", ] [[package]] @@ -3648,9 +3659,9 @@ dependencies = [ [[package]] name = "idna" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ "idna_adapter", "smallvec", @@ -3669,24 +3680,25 @@ dependencies = [ [[package]] name = "if_chain" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" +checksum = "cd62e6b5e86ea8eeeb8db1de02880a6abc01a397b2ebb64b5d74ac255318f5cb" [[package]] name = "image" -version = "0.25.6" +version = "0.25.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db35664ce6b9810857a38a906215e75a9c879f0696556a39f59c62829710251a" +checksum = "529feb3e6769d234375c4cf1ee2ce713682b8e76538cb13f9fc23e1400a591e7" dependencies = [ "bytemuck", "byteorder-lite", "color_quant", "exr", "gif", - "image-webp 0.2.3", + "image-webp 0.2.4", + "moxcms", "num-traits", - "png", + "png 0.18.0", "qoi", "ravif", "rayon", @@ -3708,9 +3720,9 @@ dependencies = [ [[package]] name = "image-webp" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6970fe7a5300b4b42e62c52efa0187540a5bef546c60edaf554ef595d2e6f0b" +checksum = "525e9ff3e1a4be2fbea1fdf0e98686a6d98b4d8f937e1bf7402245af1909e8c3" dependencies = [ "byteorder-lite", "quick-error 2.0.1", @@ -3747,12 +3759,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.10.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" +checksum = "206a8042aec68fa4a62e8d3f7aa4ceb508177d9324faf261e1959e495b7a1921" dependencies = [ "equivalent", - "hashbrown 0.15.4", + "hashbrown 0.15.5", "serde", ] @@ -3797,16 +3809,16 @@ checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] name = "io-uring" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4" +checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "cfg-if", "libc", ] @@ -3900,6 +3912,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.15" @@ -3908,25 +3929,19 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jobserver" -version = "0.1.33" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ "getrandom 0.3.3", "libc", ] -[[package]] -name = "jpeg-decoder" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00810f1d8b74be64b13dbf3db89ac67740615d6c891f0e7b6179326533011a07" - [[package]] name = "js-sys" -version = "0.3.77" +version = "0.3.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "0c0b063578492ceec17683ef2f8c5e89121fbd0b172cbc280635ab7567db2738" dependencies = [ "once_cell", "wasm-bindgen", @@ -4162,17 +4177,11 @@ dependencies = [ "spin", ] -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - [[package]] name = "lebe" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" +checksum = "7a79a3332a6609480d7d0c9eab957bca6b455b91bb84e66d19f5ff66294b85b8" [[package]] name = "lettre" @@ -4199,9 +4208,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.174" +version = "0.2.175" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" +checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" [[package]] name = "libfuzzer-sys" @@ -4299,15 +4308,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" - -[[package]] -name = "linux-raw-sys" -version = "0.9.4" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "litemap" @@ -4327,43 +4330,43 @@ dependencies = [ [[package]] name = "log" -version = "0.4.27" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" dependencies = [ "value-bag", ] [[package]] name = "logos" -version = "0.15.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab6f536c1af4c7cc81edf73da1f8029896e7e1e16a219ef09b184e76a296f3db" +checksum = "ff472f899b4ec2d99161c51f60ff7075eeb3097069a36050d8037a6325eb8154" dependencies = [ "logos-derive", ] [[package]] name = "logos-codegen" -version = "0.15.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "189bbfd0b61330abea797e5e9276408f2edbe4f822d7ad08685d67419aafb34e" +checksum = "192a3a2b90b0c05b27a0b2c43eecdb7c415e29243acc3f89cc8247a5b693045c" dependencies = [ "beef", "fnv", "lazy_static", "proc-macro2", "quote 1.0.40", - "regex-syntax 0.8.5", + "regex-syntax", "rustc_version", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] name = "logos-derive" -version = "0.15.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebfe8e1a19049ddbfccbd14ac834b215e11b85b90bab0c2dba7c7b92fb5d5cba" +checksum = "605d9697bcd5ef3a42d38efc51541aa3d6a4a25f7ab6d1ed0da5ac632a26b470" dependencies = [ "logos-codegen", ] @@ -4390,7 +4393,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" dependencies = [ "cfg-if", - "generator 0.8.5", + "generator 0.8.7", "scoped-tls", "tracing", "tracing-subscriber", @@ -4429,7 +4432,16 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown 0.15.4", + "hashbrown 0.15.5", +] + +[[package]] +name = "lru" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfe949189f46fabb938b3a9a0be30fdd93fd8a09260da863399a8cf3db756ec8" +dependencies = [ + "hashbrown 0.15.5", ] [[package]] @@ -4462,7 +4474,7 @@ dependencies = [ "macro_magic_core", "macro_magic_macros", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -4476,7 +4488,7 @@ dependencies = [ "macro_magic_core_macros", "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -4487,7 +4499,7 @@ checksum = "b02abfe41815b5bd98dbd4260173db2c116dda171dc0fe7838cb206333b83308" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -4498,7 +4510,7 @@ checksum = "73ea28ee64b88876bf45277ed9a5817c1817df061a74f2b988971a12570e5869" dependencies = [ "macro_magic_core", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -4523,11 +4535,11 @@ checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" [[package]] name = "matchers" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" dependencies = [ - "regex-automata 0.1.10", + "regex-automata", ] [[package]] @@ -4570,9 +4582,9 @@ checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "memmap2" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "483758ad303d734cec05e5c12b41d7e93e6a6390c5e9dae6bdeb7c1259012d28" +checksum = "843a98750cd611cc2965a8213b53b43e715f13c37a9e096c6408e69990961db7" dependencies = [ "libc", ] @@ -4672,11 +4684,29 @@ dependencies = [ "uuid", ] +[[package]] +name = "mongocrypt" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22426d6318d19c5c0773f783f85375265d6a8f0fa76a733da8dc4355516ec63d" +dependencies = [ + "bson", + "mongocrypt-sys", + "once_cell", + "serde", +] + +[[package]] +name = "mongocrypt-sys" +version = "0.1.4+1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dda42df21d035f88030aad8e877492fac814680e1d7336a57b2a091b989ae388" + [[package]] name = "mongodb" -version = "3.2.4" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0f8c69f13acf07eae386a2974f48ffd9187ea2aba8defbea9aa34e7e272c5f3" +checksum = "622f272c59e54a3c85f5902c6b8e7b1653a6b6681f45e4c42d6581301119a4b8" dependencies = [ "async-trait", "base64 0.13.1", @@ -4695,14 +4725,15 @@ dependencies = [ "hmac", "macro_magic", "md-5", + "mongocrypt", "mongodb-internal-macros", "once_cell", "pbkdf2", "percent-encoding", "rand 0.8.5", "rustc_version_runtime", - "rustls 0.21.12", - "rustls-pemfile 1.0.4", + "rustls 0.23.31", + "rustversion", "serde", "serde_bytes", "serde_with", @@ -4714,23 +4745,33 @@ dependencies = [ "take_mut", "thiserror 1.0.69", "tokio 1.47.1", - "tokio-rustls 0.24.1", + "tokio-rustls 0.26.2", "tokio-util", "typed-builder", "uuid", - "webpki-roots 0.25.4", + "webpki-roots 0.26.11", ] [[package]] name = "mongodb-internal-macros" -version = "3.2.4" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9202de265a3a8bbb43f9fe56db27c93137d4f9fb04c093f47e9c7de0c61ac7d" +checksum = "63981427a0f26b89632fd2574280e069d09fb2912a3138da15de0174d11dd077" dependencies = [ "macro_magic", "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", +] + +[[package]] +name = "moxcms" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd32fa8935aeadb8a8a6b6b351e40225570a37c43de67690383d87ef170cd08" +dependencies = [ + "num-traits", + "pxfm", ] [[package]] @@ -4754,9 +4795,9 @@ dependencies = [ [[package]] name = "mutate_once" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16cf681a23b4d0a43fc35024c176437f9dcd818db34e0f42ab456a0ee5ad497b" +checksum = "13d2233c9842d08cfe13f9eac96e207ca6a2ea10b80259ebe8ad0268be27d2af" [[package]] name = "nanoid" @@ -4817,12 +4858,11 @@ dependencies = [ [[package]] name = "nu-ansi-term" -version = "0.46.0" +version = "0.50.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" dependencies = [ - "overload", - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -4866,7 +4906,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -4959,7 +4999,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -4998,7 +5038,7 @@ version = "0.10.73" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "cfg-if", "foreign-types", "libc", @@ -5015,7 +5055,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -5064,12 +5104,6 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - [[package]] name = "p256" version = "0.11.1" @@ -5175,7 +5209,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -5219,26 +5253,26 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pest" -version = "2.8.1" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1db05f56d34358a8b1066f67cbb203ee3e7ed2ba674a6263a1d5ec6db2204323" +checksum = "21e0a3a33733faeaf8651dfee72dd0f388f0c8e5ad496a3478fa5a922f49cfa8" dependencies = [ "memchr", - "thiserror 2.0.12", + "thiserror 2.0.16", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.8.1" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb056d9e8ea77922845ec74a1c4e8fb17e7c218cc4fc11a15c5d25e189aa40bc" +checksum = "bc58706f770acb1dbd0973e6530a3cff4746fb721207feb3a8a6064cd0b6c663" dependencies = [ "pest", "pest_generator", @@ -5246,22 +5280,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.8.1" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87e404e638f781eb3202dc82db6760c8ae8a1eeef7fb3fa8264b2ef280504966" +checksum = "6d4f36811dfe07f7b8573462465d5cb8965fffc2e71ae377a33aecf14c2c9a2f" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] name = "pest_meta" -version = "2.8.1" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edd1101f170f5903fde0914f899bb503d9ff5271d7ba76bbb70bea63690cc0d5" +checksum = "42919b05089acbd0a5dcd5405fb304d17d1053847b81163d09c4ad18ce8e8420" dependencies = [ "pest", "sha2", @@ -5336,7 +5370,7 @@ dependencies = [ "phf_shared 0.11.3", "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -5380,7 +5414,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -5457,7 +5491,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3af6b589e163c5a788fab00ce0c0366f6efbb9959c2f9874b224936af7fce7e1" dependencies = [ "base64 0.22.1", - "indexmap 2.10.0", + "indexmap 2.11.1", "quick-xml", "serde", "time", @@ -5476,6 +5510,19 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "png" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97baced388464909d42d89643fe4361939af9b7ce7a31ee32a168f832a70f2a0" +dependencies = [ + "bitflags 2.9.4", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + [[package]] name = "polling" version = "2.8.0" @@ -5494,16 +5541,16 @@ dependencies = [ [[package]] name = "polling" -version = "3.10.0" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5bd19146350fe804f7cb2669c851c03d69da628803dab0d98018142aaa5d829" +checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" dependencies = [ "cfg-if", "concurrent-queue", "hermit-abi 0.5.2", "pin-project-lite 0.2.16", - "rustix 1.0.8", - "windows-sys 0.60.2", + "rustix", + "windows-sys 0.61.0", ] [[package]] @@ -5526,9 +5573,9 @@ checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" [[package]] name = "potential_utf" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" dependencies = [ "zerovec", ] @@ -5566,12 +5613,12 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.36" +version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff24dfcda44452b9816fff4cd4227e1bb73ff5a2f1bc1105aa92fb8565ce44d2" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -5636,14 +5683,14 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] name = "proc-macro2" -version = "1.0.95" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" dependencies = [ "unicode-ident", ] @@ -5656,7 +5703,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", "version_check", "yansi", ] @@ -5677,7 +5724,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52717f9a02b6965224f95ca2a81e2e0c5c43baacd28ca057577988930b6c3d5b" dependencies = [ "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -5694,6 +5741,15 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "pxfm" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55f4fedc84ed39cb7a489322318976425e42a147e2be79d8f878e2884f94e84" +dependencies = [ + "num-traits", +] + [[package]] name = "qoi" version = "0.4.1" @@ -5723,9 +5779,9 @@ checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" [[package]] name = "quick-xml" -version = "0.38.1" +version = "0.38.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9845d9dccf565065824e69f9f235fafba1587031eda353c1f1561cd6a6be78f4" +checksum = "42a232e7487fc2ef313d96dde7948e7a3c05101870d8985e4fd8d26aedd27b89" dependencies = [ "memchr", ] @@ -5943,7 +5999,7 @@ dependencies = [ "built", "cfg-if", "interpolate_name", - "itertools", + "itertools 0.12.1", "libc", "libfuzzer-sys", "log", @@ -5981,9 +6037,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" dependencies = [ "either", "rayon-core", @@ -5991,9 +6047,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -6065,7 +6121,7 @@ version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", ] [[package]] @@ -6085,58 +6141,43 @@ checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] name = "regex" -version = "1.11.1" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.9", - "regex-syntax 0.8.5", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", + "regex-automata", + "regex-syntax", ] [[package]] name = "regex-automata" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.5", + "regex-syntax", ] [[package]] name = "regex-lite" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" - -[[package]] -name = "regex-syntax" -version = "0.6.29" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" +checksum = "943f41321c63ef1c92fd763bfe054d2668f7f225a5c29f0105903dc2fc04ba30" [[package]] name = "regex-syntax" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" [[package]] name = "reqwest" @@ -6180,19 +6221,19 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.22" +version = "0.12.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc931937e6ca3a06e3b6c0aa7841849b160a90351d6ab467a8b9b9959767531" +checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" dependencies = [ "base64 0.22.1", "bytes 1.10.1", "encoding_rs", "futures-core", - "h2 0.4.11", + "h2 0.4.12", "http 1.3.1", "http-body 1.0.1", "http-body-util", - "hyper 1.6.0", + "hyper 1.7.0", "hyper-rustls 0.27.7", "hyper-tls 0.6.0", "hyper-util", @@ -6220,9 +6261,9 @@ dependencies = [ [[package]] name = "resolv-conf" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95325155c684b1c89f7765e30bc1c42e4a6da51ca513615660cb8a62ef9a88e3" +checksum = "6b3789b30bd25ba102de4beabd95d21ac45b69b1be7d14522bab988c526d6799" [[package]] name = "resvg" @@ -6310,6 +6351,15 @@ dependencies = [ "ulid 0.5.0", ] +[[package]] +name = "revolt-coalesced" +version = "0.8.8" +dependencies = [ + "indexmap 2.11.1", + "lru 0.16.1", + "tokio 1.47.1", +] + [[package]] name = "revolt-config" version = "0.8.8" @@ -6457,6 +6507,27 @@ dependencies = [ "webp", ] +[[package]] +name = "revolt-gifbox" +version = "0.8.8" +dependencies = [ + "axum", + "axum-extra", + "lru_time_cache", + "reqwest 0.12.23", + "revolt-coalesced", + "revolt-config", + "revolt-models", + "revolt-result", + "serde", + "serde_json", + "tokio 1.47.1", + "tracing", + "urlencoding", + "utoipa", + "utoipa-scalar", +] + [[package]] name = "revolt-january" version = "0.8.8" @@ -6469,7 +6540,7 @@ dependencies = [ "mime", "moka", "regex", - "reqwest 0.12.22", + "reqwest 0.12.23", "revolt-config", "revolt-files", "revolt-models", @@ -6607,7 +6678,7 @@ dependencies = [ "erased-serde", "http 1.3.1", "http-body-util", - "hyper 1.6.0", + "hyper 1.7.0", "hyper-rustls 0.26.0", "hyper-util", "parking_lot", @@ -6758,7 +6829,7 @@ dependencies = [ "either", "figment", "futures", - "indexmap 2.10.0", + "indexmap 2.11.1", "log", "memchr", "multer", @@ -6806,11 +6877,11 @@ checksum = "575d32d7ec1a9770108c879fc7c47815a80073f96ca07ff9525a94fcede1dd46" dependencies = [ "devise", "glob", - "indexmap 2.10.0", + "indexmap 2.11.1", "proc-macro2", "quote 1.0.40", "rocket_http", - "syn 2.0.104", + "syn 2.0.106", "unicode-xid 0.2.6", "version_check", ] @@ -6853,7 +6924,7 @@ dependencies = [ "futures", "http 0.2.12", "hyper 0.14.32", - "indexmap 2.10.0", + "indexmap 2.11.1", "log", "memchr", "pear", @@ -6947,9 +7018,9 @@ checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" [[package]] name = "rustc-hash" -version = "1.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustc_version" @@ -6972,28 +7043,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" -dependencies = [ - "bitflags 2.9.1", - "errno", - "libc", - "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", -] - -[[package]] -name = "rustix" -version = "1.0.8" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "errno", "libc", - "linux-raw-sys 0.9.4", - "windows-sys 0.60.2", + "linux-raw-sys", + "windows-sys 0.61.0", ] [[package]] @@ -7029,9 +7087,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" dependencies = [ "aws-lc-rs", + "log", "once_cell", + "ring", "rustls-pki-types", - "rustls-webpki 0.103.4", + "rustls-webpki 0.103.5", "subtle", "zeroize", ] @@ -7057,7 +7117,7 @@ dependencies = [ "openssl-probe", "rustls-pki-types", "schannel", - "security-framework 3.2.0", + "security-framework 3.4.0", ] [[package]] @@ -7110,9 +7170,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.4" +version = "0.103.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" +checksum = "b5a37813727b78798e53c2bec3f5e8fe12a6d6f8389bf9ca7802add4c9905ad8" dependencies = [ "aws-lc-rs", "ring", @@ -7122,9 +7182,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.21" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "rustybuzz" @@ -7132,7 +7192,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c85d1ccd519e61834798eb52c4e886e8c2d7d698dd3d6ce0b1b47eb8557f1181" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "bytemuck", "core_maths", "log", @@ -7152,11 +7212,11 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "schannel" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.0", ] [[package]] @@ -7205,7 +7265,7 @@ dependencies = [ "proc-macro2", "quote 1.0.40", "serde_derive_internals", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -7297,7 +7357,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "core-foundation 0.9.4", "core-foundation-sys", "libc", @@ -7306,11 +7366,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "3.2.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" +checksum = "60b369d18893388b345804dc0007963c99b7d665ae71d275812d828c6f089640" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "core-foundation 0.10.1", "core-foundation-sys", "libc", @@ -7319,9 +7379,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.14.0" +version = "2.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" dependencies = [ "core-foundation-sys", "libc", @@ -7333,7 +7393,7 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4eb30575f3638fc8f6815f448d50cb1a2e255b0897985c8c59f4d37b72a07b06" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "cssparser", "derive_more", "fxhash", @@ -7348,9 +7408,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" [[package]] name = "sentry" @@ -7504,7 +7564,7 @@ dependencies = [ "rand 0.9.2", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.16", "time", "url", "uuid", @@ -7512,20 +7572,22 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.219" +version = "1.0.223" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "a505d71960adde88e293da5cb5eda57093379f64e61cf77bf0e6a63af07a7bac" dependencies = [ + "serde_core", "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.17" +version = "0.11.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8437fd221bde2d4ca316d61b90e337e9e702b3820b87d63caa9ba6c02bd06d96" +checksum = "fe07b5d88710e3b807c16a06ccbc9dfecd5fff6a4d2745c59e3e26774f10de6a" dependencies = [ "serde", + "serde_core", ] [[package]] @@ -7537,15 +7599,24 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_core" +version = "1.0.223" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20f57cbd357666aa7b3ac84a90b4ea328f1d4ddb6772b430caa5d9e1309bb9e9" +dependencies = [ + "serde_derive", +] + [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.223" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "3d428d07faf17e306e699ec1e91996e5a165ba5d6bce5b5155173e91a8a01a56" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -7556,30 +7627,32 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] name = "serde_json" -version = "1.0.142" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ - "indexmap 2.10.0", + "indexmap 2.11.1", "itoa", "memchr", "ryu", "serde", + "serde_core", ] [[package]] name = "serde_path_to_error" -version = "0.1.17" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59fab13f937fa393d08645bf3a84bdfe86e296747b506ada67bb15f10f218b2a" +checksum = "a30a8abed938137c7183c173848e3c9b3517f5e038226849a4ecc9b21a4b4e2a" dependencies = [ "itoa", "serde", + "serde_core", ] [[package]] @@ -7613,7 +7686,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.10.0", + "indexmap 2.11.1", "schemars 0.9.0", "schemars 1.0.4", "serde", @@ -7632,7 +7705,7 @@ dependencies = [ "darling 0.20.11", "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -7771,9 +7844,9 @@ checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" [[package]] name = "slab" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" [[package]] name = "slotmap" @@ -7948,7 +8021,7 @@ dependencies = [ "proc-macro2", "quote 1.0.40", "rustversion", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -7991,9 +8064,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.104" +version = "2.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" dependencies = [ "proc-macro2", "quote 1.0.40", @@ -8044,7 +8117,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -8078,7 +8151,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "core-foundation 0.9.4", "system-configuration-sys 0.6.0", ] @@ -8142,15 +8215,15 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tempfile" -version = "3.20.0" +version = "3.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" +checksum = "84fa4d11fadde498443cca10fd3ac23c951f0dc59e080e9f4b93d4df4e4eea53" dependencies = [ "fastrand 2.3.0", "getrandom 0.3.3", "once_cell", - "rustix 1.0.8", - "windows-sys 0.59.0", + "rustix", + "windows-sys 0.61.0", ] [[package]] @@ -8184,11 +8257,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.12" +version = "2.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0" dependencies = [ - "thiserror-impl 2.0.12", + "thiserror-impl 2.0.16", ] [[package]] @@ -8199,18 +8272,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] name = "thiserror-impl" -version = "2.0.12" +version = "2.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -8224,23 +8297,25 @@ dependencies = [ [[package]] name = "tiff" -version = "0.9.1" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +checksum = "af9605de7fee8d9551863fd692cce7637f548dbd9db9180fcc07ccc6d26c336f" dependencies = [ + "fax", "flate2", - "jpeg-decoder", + "half", + "quick-error 2.0.1", "weezl", + "zune-jpeg", ] [[package]] name = "time" -version = "0.3.41" +version = "0.3.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +checksum = "83bde6f1ec10e72d583d91623c939f623002284ef622b87de38cfd546cbf2031" dependencies = [ "deranged", - "itoa", "libc", "num-conv", "num_threads", @@ -8252,15 +8327,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" [[package]] name = "time-macros" -version = "0.2.22" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" dependencies = [ "num-conv", "time-core", @@ -8286,7 +8361,7 @@ dependencies = [ "bytemuck", "cfg-if", "log", - "png", + "png 0.17.16", "tiny-skia-path", ] @@ -8313,9 +8388,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" dependencies = [ "tinyvec_macros", ] @@ -8365,7 +8440,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -8470,7 +8545,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.10.0", + "indexmap 2.11.1", "toml_datetime", "winnow 0.5.40", ] @@ -8481,12 +8556,12 @@ version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 2.10.0", + "indexmap 2.11.1", "serde", "serde_spanned", "toml_datetime", "toml_write", - "winnow 0.7.12", + "winnow 0.7.13", ] [[package]] @@ -8529,7 +8604,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "bytes 1.10.1", "http 1.3.1", "http-body 1.0.1", @@ -8545,7 +8620,7 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "bytes 1.10.1", "futures-util", "http 1.3.1", @@ -8589,7 +8664,7 @@ checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -8625,14 +8700,14 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.19" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" dependencies = [ "matchers", "nu-ansi-term", "once_cell", - "regex", + "regex-automata", "sharded-slab", "smallvec", "thread_local", @@ -8677,13 +8752,22 @@ dependencies = [ [[package]] name = "typed-builder" -version = "0.10.0" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd9d30e3a08026c78f246b173243cf07b3696d274debd26680773b6773c2afc7" +dependencies = [ + "typed-builder-macro", +] + +[[package]] +name = "typed-builder-macro" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89851716b67b937e393b3daa8423e67ddfc4bbbf1654bcf05488e95e0828db0c" +checksum = "3c36781cc0e46a83726d9879608e4cf6c2505237e263a8eb8c24502989cfdb28" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 1.0.109", + "syn 2.0.106", ] [[package]] @@ -8794,9 +8878,9 @@ checksum = "260bc6647b3893a9a90668360803a15f96b85a5257b1c3a0c3daf6ae2496de42" [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" [[package]] name = "unicode-normalization" @@ -8880,12 +8964,12 @@ dependencies = [ [[package]] name = "url" -version = "2.5.4" +version = "2.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" dependencies = [ "form_urlencoded", - "idna 1.0.3", + "idna 1.1.0", "percent-encoding", "serde", ] @@ -8950,7 +9034,7 @@ version = "4.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5afb1a60e207dca502682537fefcfd9921e71d0b83e9576060f09abc6efab23" dependencies = [ - "indexmap 2.10.0", + "indexmap 2.11.1", "serde", "serde_json", "utoipa-gen", @@ -8966,7 +9050,7 @@ dependencies = [ "proc-macro2", "quote 1.0.40", "regex", - "syn 2.0.104", + "syn 2.0.106", "ulid 1.2.1", ] @@ -8984,9 +9068,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.17.0" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d" +checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" dependencies = [ "getrandom 0.3.3", "js-sys", @@ -9139,11 +9223,20 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasi" -version = "0.14.2+wasi-0.2.4" +version = "0.14.5+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +checksum = "a4494f6290a82f5fe584817a676a34b9d6763e8d9d18204009fb31dceca98fd4" dependencies = [ - "wit-bindgen-rt", + "wasip2", +] + +[[package]] +name = "wasip2" +version = "1.0.0+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03fa2761397e5bd52002cd7e73110c71af2109aca4e521a9f40473fe685b0a24" +dependencies = [ + "wit-bindgen", ] [[package]] @@ -9157,35 +9250,36 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.100" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "7e14915cadd45b529bb8d1f343c4ed0ac1de926144b746e2710f9cd05df6603b" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", + "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.100" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +checksum = "e28d1ba982ca7923fd01448d5c30c6864d0a14109560296a162f80f305fb93bb" dependencies = [ "bumpalo", "log", "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.50" +version = "0.4.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +checksum = "0ca85039a9b469b38336411d6d6ced91f3fc87109a2a27b0c197663f5144dffe" dependencies = [ "cfg-if", "js-sys", @@ -9196,9 +9290,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "7c3d463ae3eff775b0c45df9da45d68837702ac35af998361e2c84e7c5ec1b0d" dependencies = [ "quote 1.0.40", "wasm-bindgen-macro-support", @@ -9206,22 +9300,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "7bb4ce89b08211f923caf51d527662b75bdc9c9c7aab40f86dcb9fb85ac552aa" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "f143854a3b13752c6950862c906306adb27c7e839f7414cec8fea35beab624c1" dependencies = [ "unicode-ident", ] @@ -9250,9 +9344,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.77" +version = "0.3.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +checksum = "77e4b637749ff0d92b8fad63aa1f7cff3cbe125fd49c175cd6345e7272638b12" dependencies = [ "js-sys", "wasm-bindgen", @@ -9270,20 +9364,14 @@ dependencies = [ [[package]] name = "webp" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f53152f51fb5af0c08484c33d16cca96175881d1f3dec068c23b31a158c2d99" +checksum = "c071456adef4aca59bf6a583c46b90ff5eb0b4f758fc347cea81290288f37ce1" dependencies = [ "image", "libwebp-sys", ] -[[package]] -name = "webpki-roots" -version = "0.25.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" - [[package]] name = "webpki-roots" version = "0.26.11" @@ -9308,18 +9396,6 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a751b3277700db47d3e574514de2eced5e54dc8a5436a3bf7a0b248b2cee16f3" -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix 0.38.44", -] - [[package]] name = "widestring" version = "1.2.0" @@ -9344,11 +9420,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.9" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.0", ] [[package]] @@ -9373,9 +9449,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" dependencies = [ "windows-collections", - "windows-core", + "windows-core 0.61.2", "windows-future", - "windows-link", + "windows-link 0.1.3", "windows-numerics", ] @@ -9385,7 +9461,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" dependencies = [ - "windows-core", + "windows-core 0.61.2", ] [[package]] @@ -9396,9 +9472,22 @@ checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ "windows-implement", "windows-interface", - "windows-link", - "windows-result", - "windows-strings", + "windows-link 0.1.3", + "windows-result 0.3.4", + "windows-strings 0.4.2", +] + +[[package]] +name = "windows-core" +version = "0.62.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57fe7168f7de578d2d8a05b07fd61870d2e73b4020e9f49aa00da8471723497c" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link 0.2.0", + "windows-result 0.4.0", + "windows-strings 0.5.0", ] [[package]] @@ -9407,8 +9496,8 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" dependencies = [ - "windows-core", - "windows-link", + "windows-core 0.61.2", + "windows-link 0.1.3", "windows-threading", ] @@ -9420,7 +9509,7 @@ checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -9431,7 +9520,7 @@ checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -9440,14 +9529,20 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" +[[package]] +name = "windows-link" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" + [[package]] name = "windows-numerics" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" dependencies = [ - "windows-core", - "windows-link", + "windows-core 0.61.2", + "windows-link 0.1.3", ] [[package]] @@ -9456,9 +9551,9 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" dependencies = [ - "windows-link", - "windows-result", - "windows-strings", + "windows-link 0.1.3", + "windows-result 0.3.4", + "windows-strings 0.4.2", ] [[package]] @@ -9467,7 +9562,16 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ - "windows-link", + "windows-link 0.1.3", +] + +[[package]] +name = "windows-result" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7084dcc306f89883455a206237404d3eaf961e5bd7e0f312f7c91f57eb44167f" +dependencies = [ + "windows-link 0.2.0", ] [[package]] @@ -9476,7 +9580,16 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ - "windows-link", + "windows-link 0.1.3", +] + +[[package]] +name = "windows-strings" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7218c655a553b0bed4426cf54b20d7ba363ef543b52d515b3e48d7fd55318dda" +dependencies = [ + "windows-link 0.2.0", ] [[package]] @@ -9508,11 +9621,11 @@ dependencies = [ [[package]] name = "windows-sys" -version = "0.60.2" +version = "0.61.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa" dependencies = [ - "windows-targets 0.53.3", + "windows-link 0.2.0", ] [[package]] @@ -9552,7 +9665,7 @@ version = "0.53.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" dependencies = [ - "windows-link", + "windows-link 0.1.3", "windows_aarch64_gnullvm 0.53.0", "windows_aarch64_msvc 0.53.0", "windows_i686_gnu 0.53.0", @@ -9569,7 +9682,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" dependencies = [ - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -9721,9 +9834,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.7.12" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" +checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" dependencies = [ "memchr", ] @@ -9739,13 +9852,10 @@ dependencies = [ ] [[package]] -name = "wit-bindgen-rt" -version = "0.39.0" +name = "wit-bindgen" +version = "0.45.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags 2.9.1", -] +checksum = "5c573471f125075647d03df72e026074b7203790d41351cd6edc96f46bcccd36" [[package]] name = "writeable" @@ -9812,7 +9922,7 @@ checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", "synstructure 0.13.2", ] @@ -9829,7 +9939,7 @@ dependencies = [ "http 0.2.12", "hyper 0.14.32", "hyper-rustls 0.24.2", - "itertools", + "itertools 0.12.1", "log", "percent-encoding", "rustls 0.22.4", @@ -9845,22 +9955,22 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.26" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.26" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -9880,7 +9990,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", "synstructure 0.13.2", ] @@ -9920,7 +10030,7 @@ checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote 1.0.40", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -9940,9 +10050,9 @@ dependencies = [ [[package]] name = "zune-jpeg" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1f7e205ce79eb2da3cd71c5f55f3589785cb7c79f6a03d1c8d1491bda5d089" +checksum = "29ce2c8a9384ad323cf564b67da86e21d3cfdff87908bc1223ed5c99bc792713" dependencies = [ "zune-core", ] diff --git a/README.md b/README.md index 3dd25cf5b..1f1ccbb03 100644 --- a/README.md +++ b/README.md @@ -21,9 +21,11 @@ The services and libraries that power the Revolt service.
| `core/permissions` | [crates/core/permissions](crates/core/permissions) | Core: Permission Logic | ![Crates.io Version](https://img.shields.io/crates/v/revolt-permissions) ![Crates.io Version](https://img.shields.io/crates/msrv/revolt-permissions) ![Crates.io Version](https://img.shields.io/crates/size/revolt-permissions) ![Crates.io License](https://img.shields.io/crates/l/revolt-permissions) | | `core/presence` | [crates/core/presence](crates/core/presence) | Core: User Presence | ![Crates.io Version](https://img.shields.io/crates/v/revolt-presence) ![Crates.io Version](https://img.shields.io/crates/msrv/revolt-presence) ![Crates.io Version](https://img.shields.io/crates/size/revolt-presence) ![Crates.io License](https://img.shields.io/crates/l/revolt-presence) | | `core/result` | [crates/core/result](crates/core/result) | Core: Result and Error types | ![Crates.io Version](https://img.shields.io/crates/v/revolt-result) ![Crates.io Version](https://img.shields.io/crates/msrv/revolt-result) ![Crates.io Version](https://img.shields.io/crates/size/revolt-result) ![Crates.io License](https://img.shields.io/crates/l/revolt-result) | +| `core/coalesced` | [crates/core/coalesced](crates/core/coalesced) | Core: Coalescion service | ![Crates.io Version](https://img.shields.io/crates/v/revolt-coalesced) ![Crates.io Version](https://img.shields.io/crates/msrv/revolt-coalesced) ![Crates.io Version](https://img.shields.io/crates/size/revolt-coalesced) ![Crates.io License](https://img.shields.io/crates/l/revolt-coalesced) | | `delta` | [crates/delta](crates/delta) | REST API server | ![License](https://img.shields.io/badge/license-AGPL--3.0--or--later-blue) | | `bonfire` | [crates/bonfire](crates/bonfire) | WebSocket events server | ![License](https://img.shields.io/badge/license-AGPL--3.0--or--later-blue) | | `services/january` | [crates/services/january](crates/services/january) | Proxy server | ![License](https://img.shields.io/badge/license-AGPL--3.0--or--later-blue) | +| `services/gifbox` | [crates/services/gifbox](crates/services/gifbox) | Tenor proxy server | ![License](https://img.shields.io/badge/license-AGPL--3.0--or--later-blue) | | `services/autumn` | [crates/services/autumn](crates/services/autumn) | File server | ![License](https://img.shields.io/badge/license-AGPL--3.0--or--later-blue) | | `daemons/crond` | [crates/daemons/crond](crates/daemons/crond) | Timed data clean up daemon server | ![License](https://img.shields.io/badge/license-AGPL--3.0--or--later-blue) | | `daemons/pushd` | [crates/daemons/pushd](crates/daemons/pushd) | Push notification daemon server | ![License](https://img.shields.io/badge/license-AGPL--3.0--or--later-blue) | @@ -66,6 +68,7 @@ As a heads-up, the development environment uses the following ports: | `crates/bonfire` | 14703 | | `crates/services/autumn` | 14704 | | `crates/services/january` | 14705 | +| `crates/services/gifbox` | 14706 | Now you can clone and build the project: @@ -141,6 +144,8 @@ cargo run --bin revolt-bonfire cargo run --bin revolt-autumn # run the proxy server cargo run --bin revolt-january +# run the tenor proxy +cargo run --bin revolt-gifbox # run the push daemon (not usually needed in regular development) cargo run --bin revolt-pushd diff --git a/crates/core/coalesced/Cargo.toml b/crates/core/coalesced/Cargo.toml new file mode 100644 index 000000000..4485d65db --- /dev/null +++ b/crates/core/coalesced/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "revolt-coalesced" +version = "0.8.8" +edition = "2021" +license = "MIT" +authors = ["Paul Makles ", "Zomatree "] +description = "Revolt Backend: Coalescion service" + +[features] +tokio = ["dep:tokio"] +queue = ["dep:indexmap"] +cache = ["dep:lru"] + +default = ["tokio", "queue", "cache"] + +[dependencies] +tokio = { version = "1.47.0", features = ["sync"], optional = true } +indexmap = { version = "*", optional = true } +lru = { version = "*", optional = true } + +[dev-dependencies] +tokio = { version = "1.47.0", features = ["rt", "rt-multi-thread", "macros", "time"] } diff --git a/crates/core/coalesced/LICENSE b/crates/core/coalesced/LICENSE new file mode 100644 index 000000000..7c2815b9f --- /dev/null +++ b/crates/core/coalesced/LICENSE @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) 2024 Pawel Makles + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/crates/core/coalesced/src/config.rs b/crates/core/coalesced/src/config.rs new file mode 100644 index 000000000..00ef7990b --- /dev/null +++ b/crates/core/coalesced/src/config.rs @@ -0,0 +1,23 @@ +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct CoalescionServiceConfig { + /// How many tasks are running at once + pub max_concurrent: Option, + /// Whether to queue tasks once `max_concurrent` is reached + #[cfg(feature = "queue")] + pub queue_requests: bool, + /// Max amount of tasks in the buffer queue + #[cfg(feature = "queue")] + pub max_queue: Option, +} + +impl Default for CoalescionServiceConfig { + fn default() -> Self { + Self { + max_concurrent: Some(100), + #[cfg(feature = "queue")] + queue_requests: true, + #[cfg(feature = "queue")] + max_queue: Some(100) + } + } +} diff --git a/crates/core/coalesced/src/error.rs b/crates/core/coalesced/src/error.rs new file mode 100644 index 000000000..a53955971 --- /dev/null +++ b/crates/core/coalesced/src/error.rs @@ -0,0 +1,20 @@ +use std::fmt::Display; + +#[derive(Clone, PartialEq, Eq, Debug)] +pub enum Error { + RecvError, + MaxConcurrent, + MaxQueue, +} + +impl Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Error::RecvError => write!(f, "Unable to receive data from the channel"), + Error::MaxConcurrent => write!(f, "Max number of tasks running at once"), + Error::MaxQueue => write!(f, "Max number of tasks in queue"), + } + } +} + +impl std::error::Error for Error {} diff --git a/crates/core/coalesced/src/lib.rs b/crates/core/coalesced/src/lib.rs new file mode 100644 index 000000000..6fd18267a --- /dev/null +++ b/crates/core/coalesced/src/lib.rs @@ -0,0 +1,7 @@ +mod config; +mod error; +mod service; + +pub use config::CoalescionServiceConfig; +pub use error::Error; +pub use service::CoalescionService; \ No newline at end of file diff --git a/crates/core/coalesced/src/service.rs b/crates/core/coalesced/src/service.rs new file mode 100644 index 000000000..3d3b1c9b0 --- /dev/null +++ b/crates/core/coalesced/src/service.rs @@ -0,0 +1,168 @@ +use std::{collections::{HashMap}, fmt::Debug, hash::Hash, sync::Arc, future::Future}; + +use tokio::{sync::{watch::{channel as watch_channel, Receiver}, RwLock, Mutex}}; + +#[cfg(feature = "cache")] +use lru::LruCache; + +#[cfg(feature = "queue")] +use indexmap::IndexMap; + +use crate::{CoalescionServiceConfig, Error}; + +#[derive(Clone, Debug)] +#[allow(clippy::type_complexity)] +pub struct CoalescionService { + config: Arc, + watchers: Arc, Error>>>>>>, + #[cfg(feature = "queue")] + queue: Arc, Error>>>>>>, + #[cfg(feature = "cache")] + cache: Option>>>>, +} + +impl CoalescionService { + pub fn new() -> Self { + Self::default() + } + + pub fn from_config(config: CoalescionServiceConfig) -> Self { + Self { + config: Arc::new(config), + watchers: Arc::new(RwLock::new(HashMap::new())), + #[cfg(feature = "queue")] + queue: Arc::new(RwLock::new(IndexMap::new())), + #[cfg(feature = "cache")] + cache: None, + } + } + + #[cfg(feature = "cache")] + pub fn from_cache(config: CoalescionServiceConfig, cache: LruCache>) -> Self { + Self { + cache: Some(Arc::new(Mutex::new(cache))), + ..Self::from_config(config) + } + } + + async fn wait_for(&self, mut receiver: Receiver, Error>>>) -> Result, Error> { + receiver + .wait_for(|v| v.is_some()) + .await + .map_err(|_| Error::RecvError) + .and_then(|r| r.clone().unwrap()) + } + + async fn insert_and_execute Fut, Fut: Future>(&self, id: Id, func: F) -> Result, Error> { + let (send, recv) = watch_channel(None); + + self.watchers.write().await.insert(id.clone(), recv); + + let value = Ok(Arc::new(func().await)); + + send.send_modify(|opt| { + opt.replace(value.clone()); + }); + + #[cfg(feature = "cache")] + if let Some(cache) = self.cache.as_ref() { + if let Ok(value) = &value { + cache.lock().await.push(id.clone(), value.clone()); + } + }; + + self.watchers.write().await.remove(&id); + + value + } + + pub async fn execute Fut, Fut: Future>(&self, id: Id, func: F) -> Result, Error> { + #[cfg(feature = "cache")] + if let Some(cache) = self.cache.as_ref() { + if let Some(value) = cache.lock().await.get(&id) { + return Ok(value.clone()) + } + }; + + let (receiver, length) = { + let watchers = self.watchers.read().await; + let length = watchers.len(); + + (watchers.get(&id).cloned(), length) + }; + + if let Some(receiver) = receiver { + self.wait_for(receiver).await + } else { + match self.config.max_concurrent { + Some(max_concurrent) if length >= max_concurrent => { + #[cfg(feature = "queue")] + if self.config.queue_requests { + let (receiver, length) = { + let queue = self.queue.read().await; + + (queue.get(&id).cloned(), queue.len()) + }; + + if let Some(receiver) = receiver { + return self.wait_for(receiver).await + } else { + if self.config.max_queue.is_some_and(|max_queue| max_queue >= length) { + return Err(Error::MaxQueue) + }; + + let (send, recv) = watch_channel(None); + + self.queue.write().await.insert(id.clone(), recv); + + loop { + let length = self.watchers.read().await.len(); + + if length < max_concurrent { + let first_key = { + let queue = self.queue.read().await; + queue.first().map(|v| v.0).cloned() + }; + + if first_key == Some(id.clone()) { + self.queue.write().await.shift_remove(&id); + + let response = self.insert_and_execute(id, func).await; + + send.send_modify(|opt| { + opt.replace(response.clone()); + }); + + return response + } + } + } + } + } else { + Err(Error::MaxConcurrent) + } + + #[cfg(not(feature = "queue"))] + Err(Error::MaxConcurrent) + } + _ => { + self.insert_and_execute(id, func).await + } + } + } + } + + pub async fn current_task_count(&self) -> usize { + self.watchers.read().await.len() + } + + pub async fn current_queue_len(&self) -> usize { + self.queue.read().await.len() + } +} + +impl Default for CoalescionService { + fn default() -> Self { + Self::from_config(CoalescionServiceConfig::default()) + } +} diff --git a/crates/core/config/Revolt.toml b/crates/core/config/Revolt.toml index e3a04f2ae..0f2644577 100644 --- a/crates/core/config/Revolt.toml +++ b/crates/core/config/Revolt.toml @@ -56,6 +56,8 @@ voso_legacy_token = "" trust_cloudflare = false # easypwned endpoint easypwned = "" +# Tenor API Key +tenor_key = "" [api.security.captcha] # hCaptcha configuration @@ -277,3 +279,4 @@ files = "" proxy = "" pushd = "" crond = "" +gifbox = "" \ No newline at end of file diff --git a/crates/core/config/src/lib.rs b/crates/core/config/src/lib.rs index 6c4d58de5..5863cbc4d 100644 --- a/crates/core/config/src/lib.rs +++ b/crates/core/config/src/lib.rs @@ -190,6 +190,7 @@ pub struct ApiSecurity { pub captcha: ApiSecurityCaptcha, pub trust_cloudflare: bool, pub easypwned: String, + pub tenor_key: String, } #[derive(Deserialize, Debug, Clone)] @@ -365,6 +366,7 @@ pub struct Sentry { pub proxy: String, pub pushd: String, pub crond: String, + pub gifbox: String, } #[derive(Deserialize, Debug, Clone)] diff --git a/crates/services/gifbox/Cargo.toml b/crates/services/gifbox/Cargo.toml new file mode 100644 index 000000000..d2e651459 --- /dev/null +++ b/crates/services/gifbox/Cargo.toml @@ -0,0 +1,40 @@ +[package] +name = "revolt-gifbox" +version = "0.8.8" +edition = "2021" +license = "AGPL-3.0-or-later" + +[dependencies] +# Serialisation +serde = { version = "1.0", features = ["derive", "rc"] } +serde_json = "1.0.68" + +# Async runtime +tokio = { version = "1.0", features = ["full"] } + +# Web requests +reqwest = { version = "0.12", features = ["json"] } + +# Core crates +revolt-config = { version = "0.8.8", path = "../../core/config" } +revolt-models = { version = "0.8.8", path = "../../core/models" } +revolt-result = { version = "0.8.8", path = "../../core/result", features = [ + "utoipa", + "axum", +] } +revolt-coalesced = { version = "0.8.8", path = "../../core/coalesced" } + +# Axum / web server +axum = { version = "0.7.5" } +axum-extra = { version = "0.9", features = ["typed-header"] } + +# OpenAPI & documentation generation +utoipa-scalar = { version = "0.1.0", features = ["axum"] } +utoipa = { version = "4.2.3", features = ["axum_extras", "ulid"] } + +# Logging +tracing = "0.1" + +# Utils +lru_time_cache = "0.11.11" +urlencoding = "2.1.3" \ No newline at end of file diff --git a/crates/services/gifbox/Dockerfile b/crates/services/gifbox/Dockerfile new file mode 100644 index 000000000..5668448fd --- /dev/null +++ b/crates/services/gifbox/Dockerfile @@ -0,0 +1,12 @@ +# Build Stage +FROM ghcr.io/revoltchat/base:latest AS builder + +# Bundle Stage +FROM gcr.io/distroless/cc-debian12:nonroot +COPY --from=builder /home/rust/src/target/release/revolt-gifbox ./ +COPY --from=mwader/static-ffmpeg:7.0.2 /ffmpeg /usr/local/bin/ +COPY --from=mwader/static-ffmpeg:7.0.2 /ffprobe /usr/local/bin/ + +EXPOSE 14706 +USER nonroot +CMD ["./revolt-gifbox"] diff --git a/crates/services/gifbox/src/api.rs b/crates/services/gifbox/src/api.rs new file mode 100644 index 000000000..c137e7a3d --- /dev/null +++ b/crates/services/gifbox/src/api.rs @@ -0,0 +1,64 @@ +use std::sync::Arc; + +use axum::{extract::{Query, State}, routing::get, Json, Router}; +use revolt_result::{create_error, Result}; +use serde::{Deserialize, Serialize}; +use utoipa::ToSchema; + +use crate::tenor::{Tenor, types}; + +pub async fn router() -> Router { + Router::new() + .route("/", get(root)) + .route("/search", get(search)) +} + +/// Successful root response +#[derive(Serialize, Debug, ToSchema)] +pub struct RootResponse { + message: &'static str, + version: &'static str, +} + +/// Capture crate version from Cargo +static CRATE_VERSION: &str = env!("CARGO_PKG_VERSION"); + +/// Root response from service +#[utoipa::path( + get, + path = "/", + responses( + (status = 200, description = "Echo response", body = RootResponse) + ) +)] +async fn root() -> Json { + Json(RootResponse { + message: "Gifbox lives on!", + version: CRATE_VERSION, + }) +} + +#[derive(Deserialize)] +struct SearchQueryParams { + pub query: String, + pub locale: String, + pub position: Option +} + +#[utoipa::path( + get, + path = "/search", + responses( + (status = 200, description = "Search results", body = SearchResponse) + ) +)] +async fn search( + Query(params): Query, + State(tenor): State, +) -> Result>> { + // Todo + tenor.search(¶ms.query, ¶ms.locale, params.position.as_deref()) + .await + .map_err(|_| create_error!(InternalError)) + .map(Json) +} \ No newline at end of file diff --git a/crates/services/gifbox/src/main.rs b/crates/services/gifbox/src/main.rs new file mode 100644 index 000000000..32d1ea58a --- /dev/null +++ b/crates/services/gifbox/src/main.rs @@ -0,0 +1,65 @@ +use std::net::{Ipv4Addr, SocketAddr}; + +use axum::Router; + +use revolt_config::config; +use tokio::net::TcpListener; +use utoipa::{ + openapi::security::{Http, HttpAuthScheme, SecurityScheme}, + Modify, OpenApi, +}; +use utoipa_scalar::{Scalar, Servable as ScalarServable}; + +mod api; +mod tenor; + +#[tokio::main] +async fn main() -> Result<(), std::io::Error> { + // Configure logging and environment + revolt_config::configure!(gifbox); + + // Configure API schema + #[derive(OpenApi)] + #[openapi( + modifiers(&SecurityAddon), + paths( + api::root, + ), + components( + schemas( + revolt_result::Error, + revolt_result::ErrorType, + ) + ) + )] + struct ApiDoc; + + struct SecurityAddon; + + impl Modify for SecurityAddon { + fn modify(&self, openapi: &mut utoipa::openapi::OpenApi) { + if let Some(components) = openapi.components.as_mut() { + components.add_security_scheme( + "api_key", + SecurityScheme::Http(Http::new(HttpAuthScheme::Bearer)), + ) + } + } + } + + let config = config().await; + let tenor = tenor::Tenor::new(&config.api.security.tenor_key); + + // Configure Axum and router + let app = Router::new() + .merge(Scalar::with_url("/scalar", ApiDoc::openapi())) + .nest("/", api::router().await) + .with_state(tenor); + + // Configure TCP listener and bind + tracing::info!("Listening on 0.0.0.0:14706"); + tracing::info!("Play around with the API: http://localhost:14706/scalar"); + let address = SocketAddr::from((Ipv4Addr::UNSPECIFIED, 14706)); + let listener = TcpListener::bind(&address).await?; + axum::serve(listener, app.into_make_service()).await +} diff --git a/crates/services/gifbox/src/tenor/mod.rs b/crates/services/gifbox/src/tenor/mod.rs new file mode 100644 index 000000000..56db62698 --- /dev/null +++ b/crates/services/gifbox/src/tenor/mod.rs @@ -0,0 +1,129 @@ +use std::{sync::Arc, time::Duration}; + +use reqwest::Client; +use tokio::sync::RwLock; +use lru_time_cache::LruCache; +use urlencoding::encode as url_encode; +use revolt_coalesced::{CoalescionService, CoalescionServiceConfig}; + +pub mod types; + +const TENOR_API_BASE_URL: &str = "https://tenor.googleapis.com/v2"; + +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum TenorError { + HttpError, +} + +#[derive(Clone)] +pub struct Tenor { + pub key: Arc, + pub client: Client, + pub coalescion: CoalescionService, TenorError>>, + pub cache: Arc>>> +} + +impl Tenor { + pub fn new(key: &str) -> Self { + // 1 hour, 1k queries + let cache = LruCache::with_expiry_duration_and_capacity(Duration::from_secs(60*60), 1000); + + Self { + key: Arc::from(key), + client: Client::new(), + coalescion: CoalescionService::from_config(CoalescionServiceConfig { + max_concurrent: Some(100), + queue_requests: true, + max_queue: None + }), + cache: Arc::new(RwLock::new(cache)), + } + } + + pub async fn search(&self, query: &str, locale: &str, position: Option<&str>) -> Result, TenorError> { + let unique_key = format!("{query}:{locale}:{position:?}"); + + if self.cache.read().await.contains_key(&unique_key) { + if let Some(response) = self.cache.write().await.get(&unique_key) { + return Ok(response.clone()) + } + } + + let res = self.coalescion.execute(unique_key.clone(), || { + let client = self.client.clone(); + + async move { + let mut url = format!( + "{TENOR_API_BASE_URL}/search?key={}&q={}&client_key=Gifbox&locale={}&contentfilter=medium&limit=1", + &self.key, + url_encode(query), + url_encode(locale), + ); + + if let Some(position) = position { + url.push_str("&pos="); + url.push_str(position); + }; + + let response = client.get(url) + .send() + .await + .inspect_err(|e| { revolt_config::capture_error(e); }) + .map_err(|_| TenorError::HttpError)?; + + let text = response.text().await.map_err(|e| { println!("{e:?}"); TenorError::HttpError })?; + + Ok(Arc::new(serde_json::from_str(&text).unwrap())) + } + }) + .await + .unwrap(); + + if let Ok(resp) = &*res { + self.cache.write().await.insert(unique_key, resp.clone()); + } + + (*res).clone() + } +} + +#[cfg(test)] +mod tests { + use super::*; + use revolt_config::config; + + #[tokio::test(flavor = "current_thread")] + async fn test() { + let config = config().await; + + let tenor = Tenor::new(&config.api.security.tenor_key); + + let results =tenor.search("amog", "en_US", None).await.unwrap(); + + let result = &results.results[0]; + + println!("{:?}", result.media_formats.iter().next().unwrap()); + } + + #[tokio::test(flavor = "current_thread")] + async fn test_2() { + let config = config().await; + let tenor = Tenor::new(&config.api.security.tenor_key); + + let mut tasks = Vec::new(); + + for i in 1..1001 { + let tenor = tenor.clone(); + println!("creating search task {i}"); + + tasks.push((i, tokio::spawn(async move { + tenor.search(&format!("amog-{i}"), "en_US", None).await + }))); + }; + + for (i, task) in tasks { + task.await.unwrap().unwrap(); + println!("Got result for {i}"); + }; + } +} \ No newline at end of file diff --git a/crates/services/gifbox/src/tenor/types.rs b/crates/services/gifbox/src/tenor/types.rs new file mode 100644 index 000000000..a712fcb7b --- /dev/null +++ b/crates/services/gifbox/src/tenor/types.rs @@ -0,0 +1,36 @@ +use std::collections::HashMap; + +use serde::{Serialize, Deserialize}; + + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct SearchResponse { + pub results: Vec, + pub next: String +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct MediaObject { + pub url: String, + pub dims: Vec, + pub duration: f64, + pub size: f64 +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct TenorResult { + pub created: f64, + #[serde(default)] + pub hasaudio: bool, + pub id: String, + pub media_formats: HashMap, + pub tags: Vec, + pub title: String, + pub content_description: String, + pub itemurl: String, + #[serde(default)] + pub hascaption: bool, + pub flags: Vec, + pub bg_color: Option, + pub url: String +} \ No newline at end of file diff --git a/scripts/build-image-layer.sh b/scripts/build-image-layer.sh index 0a0fa32b7..064cee896 100644 --- a/scripts/build-image-layer.sh +++ b/scripts/build-image-layer.sh @@ -32,8 +32,10 @@ deps() { crates/core/permissions/src \ crates/core/presence/src \ crates/core/result/src \ + crates/core/coalesced/src \ crates/services/autumn/src \ crates/services/january/src \ + crates/services/gifbox/src \ crates/daemons/crond/src \ crates/daemons/pushd/src echo 'fn main() { panic!("stub"); }' | @@ -41,6 +43,7 @@ deps() { tee crates/delta/src/main.rs | tee crates/services/autumn/src/main.rs | tee crates/services/january/src/main.rs | + tee crates/services/gifbox/src/main.rs | tee crates/daemons/crond/src/main.rs | tee crates/daemons/pushd/src/main.rs echo '' | @@ -51,7 +54,8 @@ deps() { tee crates/core/parser/src/lib.rs | tee crates/core/permissions/src/lib.rs | tee crates/core/presence/src/lib.rs | - tee crates/core/result/src/lib.rs + tee crates/core/result/src/lib.rs | + tee crates/core/coalesced/src/lib.rs if [ -z "$TARGETARCH" ]; then cargo build -j 10 --locked --release @@ -72,7 +76,8 @@ apps() { crates/core/parser/src/lib.rs \ crates/core/permissions/src/lib.rs \ crates/core/presence/src/lib.rs \ - crates/core/result/src/lib.rs + crates/core/result/src/lib.rs \ + crates/core/coalesced/src/lib .rs if [ -z "$TARGETARCH" ]; then cargo build -j 10 --locked --release diff --git a/scripts/publish-debug-image.sh b/scripts/publish-debug-image.sh index 6686344cb..cc67d9fdc 100755 --- a/scripts/publish-debug-image.sh +++ b/scripts/publish-debug-image.sh @@ -25,6 +25,7 @@ docker build -t ghcr.io/revoltchat/server:$TAG - < crates/delta/Dockerfile docker build -t ghcr.io/revoltchat/bonfire:$TAG - < crates/bonfire/Dockerfile docker build -t ghcr.io/revoltchat/autumn:$TAG - < crates/services/autumn/Dockerfile docker build -t ghcr.io/revoltchat/january:$TAG - < crates/services/january/Dockerfile +docker build -t ghcr.io/revoltchat/gifbox:$TAG - < crates/services/gifbox/Dockerfile docker build -t ghcr.io/revoltchat/crond:$TAG - < crates/daemons/crond/Dockerfile docker build -t ghcr.io/revoltchat/pushd:$TAG - < crates/daemons/pushd/Dockerfile @@ -36,5 +37,6 @@ docker push ghcr.io/revoltchat/server:$TAG docker push ghcr.io/revoltchat/bonfire:$TAG docker push ghcr.io/revoltchat/autumn:$TAG docker push ghcr.io/revoltchat/january:$TAG +docker push ghcr.io/revoltchat/gifbox:$TAG docker push ghcr.io/revoltchat/crond:$TAG docker push ghcr.io/revoltchat/pushd:$TAG diff --git a/scripts/start.sh b/scripts/start.sh index 466d56071..ef485d22a 100755 --- a/scripts/start.sh +++ b/scripts/start.sh @@ -4,10 +4,12 @@ cargo build \ --bin revolt-delta \ --bin revolt-bonfire \ --bin revolt-autumn \ - --bin revolt-january + --bin revolt-january \ + --bin revolt-gifbox trap 'pkill -f revolt-' SIGINT cargo run --bin revolt-delta & cargo run --bin revolt-bonfire & cargo run --bin revolt-autumn & -cargo run --bin revolt-january +cargo run --bin revolt-january & +cargo run --bin revolt-gifbox From b5cd5e30ef7d5e56e8964fb7c543965fa6bf5a4a Mon Sep 17 00:00:00 2001 From: Zomatree Date: Fri, 8 Aug 2025 00:44:01 +0100 Subject: [PATCH 009/211] feat: require auth for search --- Cargo.lock | 1 + crates/core/database/src/models/users/axum.rs | 9 +++--- crates/services/gifbox/Cargo.toml | 2 +- crates/services/gifbox/src/api.rs | 6 ++-- crates/services/gifbox/src/main.rs | 30 +++++++++++++++++-- 5 files changed, 37 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index efcf2cb1a..1274b75ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6517,6 +6517,7 @@ dependencies = [ "reqwest 0.12.23", "revolt-coalesced", "revolt-config", + "revolt-database", "revolt-models", "revolt-result", "serde", diff --git a/crates/core/database/src/models/users/axum.rs b/crates/core/database/src/models/users/axum.rs index a6d8b5a3b..6b1f2f322 100644 --- a/crates/core/database/src/models/users/axum.rs +++ b/crates/core/database/src/models/users/axum.rs @@ -1,21 +1,20 @@ -use axum::{ - extract::{FromRef, FromRequestParts}, - http::request::Parts, -}; +use axum::{extract::{FromRef, FromRequestParts}, http::request::Parts}; use revolt_result::{create_error, Error, Result}; use crate::{Database, User}; #[async_trait::async_trait] -impl FromRequestParts for User +impl FromRequestParts for User where Database: FromRef, + S: Send + Sync { type Rejection = Error; async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { let db = Database::from_ref(state); + if let Some(Ok(bot_token)) = parts.headers.get("x-bot-token").map(|v| v.to_str()) { let bot = db.fetch_bot_by_token(bot_token).await?; db.fetch_user(&bot.id).await diff --git a/crates/services/gifbox/Cargo.toml b/crates/services/gifbox/Cargo.toml index d2e651459..94cd07321 100644 --- a/crates/services/gifbox/Cargo.toml +++ b/crates/services/gifbox/Cargo.toml @@ -23,7 +23,7 @@ revolt-result = { version = "0.8.8", path = "../../core/result", features = [ "axum", ] } revolt-coalesced = { version = "0.8.8", path = "../../core/coalesced" } - +revolt-database = { version = "0.8.8", path = "../../core/database", features = ["axum-impl"] } # Axum / web server axum = { version = "0.7.5" } axum-extra = { version = "0.9", features = ["typed-header"] } diff --git a/crates/services/gifbox/src/api.rs b/crates/services/gifbox/src/api.rs index c137e7a3d..07883652f 100644 --- a/crates/services/gifbox/src/api.rs +++ b/crates/services/gifbox/src/api.rs @@ -4,10 +4,11 @@ use axum::{extract::{Query, State}, routing::get, Json, Router}; use revolt_result::{create_error, Result}; use serde::{Deserialize, Serialize}; use utoipa::ToSchema; +use revolt_database::User; -use crate::tenor::{Tenor, types}; +use crate::{AppState, tenor::{Tenor, types}}; -pub async fn router() -> Router { +pub async fn router() -> Router { Router::new() .route("/", get(root)) .route("/search", get(search)) @@ -53,6 +54,7 @@ struct SearchQueryParams { ) )] async fn search( + _user: User, Query(params): Query, State(tenor): State, ) -> Result>> { diff --git a/crates/services/gifbox/src/main.rs b/crates/services/gifbox/src/main.rs index 32d1ea58a..3cfb2e95b 100644 --- a/crates/services/gifbox/src/main.rs +++ b/crates/services/gifbox/src/main.rs @@ -1,8 +1,9 @@ use std::net::{Ipv4Addr, SocketAddr}; -use axum::Router; +use axum::{extract::FromRef, Router}; use revolt_config::config; +use revolt_database::{Database, DatabaseInfo}; use tokio::net::TcpListener; use utoipa::{ openapi::security::{Http, HttpAuthScheme, SecurityScheme}, @@ -10,9 +11,29 @@ use utoipa::{ }; use utoipa_scalar::{Scalar, Servable as ScalarServable}; +use crate::tenor::Tenor; + mod api; mod tenor; +#[derive(Clone)] +struct AppState { + pub database: Database, + pub tenor: Tenor +} + +impl FromRef for Database { + fn from_ref(state: &AppState) -> Self { + state.database.clone() + } +} + +impl FromRef for Tenor { + fn from_ref(state: &AppState) -> Self { + state.tenor.clone() + } +} + #[tokio::main] async fn main() -> Result<(), std::io::Error> { // Configure logging and environment @@ -48,13 +69,16 @@ async fn main() -> Result<(), std::io::Error> { } let config = config().await; - let tenor = tenor::Tenor::new(&config.api.security.tenor_key); + let state = AppState { + database: DatabaseInfo::Auto.connect().await.expect("Unable to connect to database"), + tenor: tenor::Tenor::new(&config.api.security.tenor_key) + }; // Configure Axum and router let app = Router::new() .merge(Scalar::with_url("/scalar", ApiDoc::openapi())) .nest("/", api::router().await) - .with_state(tenor); + .with_state(state); // Configure TCP listener and bind tracing::info!("Listening on 0.0.0.0:14706"); From a92152d86da136997817e797c7af8e38731cdde8 Mon Sep 17 00:00:00 2001 From: Zomatree Date: Fri, 8 Aug 2025 03:10:30 +0100 Subject: [PATCH 010/211] fix: use our own result types instead of tenors types add user auth --- crates/services/gifbox/src/api.rs | 28 +++++---- crates/services/gifbox/src/main.rs | 14 ++++- crates/services/gifbox/src/tenor/mod.rs | 62 +++++--------------- crates/services/gifbox/src/tenor/types.rs | 15 +++-- crates/services/gifbox/src/types.rs | 69 +++++++++++++++++++++++ 5 files changed, 118 insertions(+), 70 deletions(-) create mode 100644 crates/services/gifbox/src/types.rs diff --git a/crates/services/gifbox/src/api.rs b/crates/services/gifbox/src/api.rs index 07883652f..36a29757a 100644 --- a/crates/services/gifbox/src/api.rs +++ b/crates/services/gifbox/src/api.rs @@ -1,12 +1,18 @@ -use std::sync::Arc; - -use axum::{extract::{Query, State}, routing::get, Json, Router}; +use axum::{ + extract::{Query, State}, + routing::get, + Json, Router, +}; +use revolt_database::User; use revolt_result::{create_error, Result}; use serde::{Deserialize, Serialize}; use utoipa::ToSchema; -use revolt_database::User; -use crate::{AppState, tenor::{Tenor, types}}; +use crate::{ + tenor, + types, + AppState, +}; pub async fn router() -> Router { Router::new() @@ -43,7 +49,7 @@ async fn root() -> Json { struct SearchQueryParams { pub query: String, pub locale: String, - pub position: Option + pub position: Option, } #[utoipa::path( @@ -56,11 +62,13 @@ struct SearchQueryParams { async fn search( _user: User, Query(params): Query, - State(tenor): State, -) -> Result>> { + State(tenor): State, +) -> Result> { // Todo - tenor.search(¶ms.query, ¶ms.locale, params.position.as_deref()) + tenor + .search(¶ms.query, ¶ms.locale, params.position.as_deref()) .await .map_err(|_| create_error!(InternalError)) + .map(|results| results.as_ref().clone().into()) .map(Json) -} \ No newline at end of file +} diff --git a/crates/services/gifbox/src/main.rs b/crates/services/gifbox/src/main.rs index 3cfb2e95b..a3339078f 100644 --- a/crates/services/gifbox/src/main.rs +++ b/crates/services/gifbox/src/main.rs @@ -15,11 +15,12 @@ use crate::tenor::Tenor; mod api; mod tenor; +mod types; #[derive(Clone)] struct AppState { pub database: Database, - pub tenor: Tenor + pub tenor: Tenor, } impl FromRef for Database { @@ -45,11 +46,15 @@ async fn main() -> Result<(), std::io::Error> { modifiers(&SecurityAddon), paths( api::root, + api::search, ), components( schemas( revolt_result::Error, revolt_result::ErrorType, + types::SearchResponse, + types::MediaObject, + types::MediaResult, ) ) )] @@ -70,8 +75,11 @@ async fn main() -> Result<(), std::io::Error> { let config = config().await; let state = AppState { - database: DatabaseInfo::Auto.connect().await.expect("Unable to connect to database"), - tenor: tenor::Tenor::new(&config.api.security.tenor_key) + database: DatabaseInfo::Auto + .connect() + .await + .expect("Unable to connect to database"), + tenor: tenor::Tenor::new(&config.api.security.tenor_key), }; // Configure Axum and router diff --git a/crates/services/gifbox/src/tenor/mod.rs b/crates/services/gifbox/src/tenor/mod.rs index 56db62698..2ff3785c4 100644 --- a/crates/services/gifbox/src/tenor/mod.rs +++ b/crates/services/gifbox/src/tenor/mod.rs @@ -1,10 +1,10 @@ use std::{sync::Arc, time::Duration}; +use lru_time_cache::LruCache; use reqwest::Client; +use revolt_coalesced::{CoalescionService, CoalescionServiceConfig}; use tokio::sync::RwLock; -use lru_time_cache::LruCache; use urlencoding::encode as url_encode; -use revolt_coalesced::{CoalescionService, CoalescionServiceConfig}; pub mod types; @@ -20,13 +20,13 @@ pub struct Tenor { pub key: Arc, pub client: Client, pub coalescion: CoalescionService, TenorError>>, - pub cache: Arc>>> + pub cache: Arc>>>, } impl Tenor { pub fn new(key: &str) -> Self { // 1 hour, 1k queries - let cache = LruCache::with_expiry_duration_and_capacity(Duration::from_secs(60*60), 1000); + let cache = LruCache::with_expiry_duration_and_capacity(Duration::from_secs(60 * 60), 1000); Self { key: Arc::from(key), @@ -34,18 +34,23 @@ impl Tenor { coalescion: CoalescionService::from_config(CoalescionServiceConfig { max_concurrent: Some(100), queue_requests: true, - max_queue: None + max_queue: None, }), cache: Arc::new(RwLock::new(cache)), } } - pub async fn search(&self, query: &str, locale: &str, position: Option<&str>) -> Result, TenorError> { + pub async fn search( + &self, + query: &str, + locale: &str, + position: Option<&str>, + ) -> Result, TenorError> { let unique_key = format!("{query}:{locale}:{position:?}"); if self.cache.read().await.contains_key(&unique_key) { if let Some(response) = self.cache.write().await.get(&unique_key) { - return Ok(response.clone()) + return Ok(response.clone()); } } @@ -54,7 +59,7 @@ impl Tenor { async move { let mut url = format!( - "{TENOR_API_BASE_URL}/search?key={}&q={}&client_key=Gifbox&locale={}&contentfilter=medium&limit=1", + "{TENOR_API_BASE_URL}/search?key={}&q={}&client_key=Gifbox&media_filter=webm,tinywebm&locale={}&contentfilter=medium&limit=1", &self.key, url_encode(query), url_encode(locale), @@ -86,44 +91,3 @@ impl Tenor { (*res).clone() } } - -#[cfg(test)] -mod tests { - use super::*; - use revolt_config::config; - - #[tokio::test(flavor = "current_thread")] - async fn test() { - let config = config().await; - - let tenor = Tenor::new(&config.api.security.tenor_key); - - let results =tenor.search("amog", "en_US", None).await.unwrap(); - - let result = &results.results[0]; - - println!("{:?}", result.media_formats.iter().next().unwrap()); - } - - #[tokio::test(flavor = "current_thread")] - async fn test_2() { - let config = config().await; - let tenor = Tenor::new(&config.api.security.tenor_key); - - let mut tasks = Vec::new(); - - for i in 1..1001 { - let tenor = tenor.clone(); - println!("creating search task {i}"); - - tasks.push((i, tokio::spawn(async move { - tenor.search(&format!("amog-{i}"), "en_US", None).await - }))); - }; - - for (i, task) in tasks { - task.await.unwrap().unwrap(); - println!("Got result for {i}"); - }; - } -} \ No newline at end of file diff --git a/crates/services/gifbox/src/tenor/types.rs b/crates/services/gifbox/src/tenor/types.rs index a712fcb7b..b4ad4a084 100644 --- a/crates/services/gifbox/src/tenor/types.rs +++ b/crates/services/gifbox/src/tenor/types.rs @@ -1,12 +1,11 @@ use std::collections::HashMap; -use serde::{Serialize, Deserialize}; - +use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] pub struct SearchResponse { - pub results: Vec, - pub next: String + pub results: Vec, + pub next: String, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] @@ -14,11 +13,11 @@ pub struct MediaObject { pub url: String, pub dims: Vec, pub duration: f64, - pub size: f64 + pub size: f64, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -pub struct TenorResult { +pub struct MediaResult { pub created: f64, #[serde(default)] pub hasaudio: bool, @@ -32,5 +31,5 @@ pub struct TenorResult { pub hascaption: bool, pub flags: Vec, pub bg_color: Option, - pub url: String -} \ No newline at end of file + pub url: String, +} diff --git a/crates/services/gifbox/src/types.rs b/crates/services/gifbox/src/types.rs new file mode 100644 index 000000000..d42676023 --- /dev/null +++ b/crates/services/gifbox/src/types.rs @@ -0,0 +1,69 @@ +use std::collections::HashMap; + +use utoipa::ToSchema; +use serde::{Serialize, Deserialize}; + +use crate::tenor::types; + +#[derive(Serialize, Deserialize, ToSchema, Clone, Debug, PartialEq)] +/// Response containing the current results and the id of the next result for pagination. +pub struct SearchResponse { + /// Current gif results. + pub results: Vec, + #[serde(skip_serializing_if = "Option::is_none")] + /// Id of the next result. + pub next: Option, +} + +#[derive(Serialize, Deserialize, ToSchema, Clone, Debug, PartialEq)] +/// Indivual gif result. +pub struct MediaResult { + /// Unique Tenor id. + pub id: String, + /// Mapping of each file format and url of the file. + pub media_formats: HashMap, + /// Public Tenor web url for the gif. + pub url: String +} + +#[derive(Serialize, Deserialize, ToSchema, Clone, Debug, PartialEq)] +/// Represents the gif in a certain file format. +pub struct MediaObject { + /// File url of the gif in a certain format. + pub url: String, + /// Width and height of the file in px. + pub dimensions: Vec, +} + + +impl From for SearchResponse { + fn from(value: types::SearchResponse) -> Self { + Self { + results: value.results.into_iter().map(|result| result.into()).collect(), + next: if value.next.is_empty() { + None + } else { + Some(value.next) + } + } + } +} + +impl From for MediaResult { + fn from(value: types::MediaResult) -> Self { + Self { + id: value.id, + media_formats: value.media_formats.into_iter().map(|(k, v)| (k, v.into())).collect(), + url: value.url + } + } +} + +impl From for MediaObject { + fn from(value: types::MediaObject) -> Self { + Self { + url: value.url, + dimensions: value.dims + } + } +} \ No newline at end of file From 5885e067a627b8fff1c8ce2bf9e852ff8cf3f07a Mon Sep 17 00:00:00 2001 From: Zomatree Date: Thu, 11 Sep 2025 14:18:28 +0100 Subject: [PATCH 011/211] feat: trending and categories routes --- crates/services/gifbox/src/api.rs | 74 ------- crates/services/gifbox/src/main.rs | 56 +++--- .../services/gifbox/src/routes/categories.rs | 47 +++++ crates/services/gifbox/src/routes/mod.rs | 15 ++ crates/services/gifbox/src/routes/root.rs | 22 +++ crates/services/gifbox/src/routes/search.rs | 51 +++++ crates/services/gifbox/src/routes/trending.rs | 45 +++++ crates/services/gifbox/src/tenor/mod.rs | 181 +++++++++++++++--- crates/services/gifbox/src/tenor/types.rs | 20 +- crates/services/gifbox/src/types.rs | 64 +++++-- 10 files changed, 432 insertions(+), 143 deletions(-) delete mode 100644 crates/services/gifbox/src/api.rs create mode 100644 crates/services/gifbox/src/routes/categories.rs create mode 100644 crates/services/gifbox/src/routes/mod.rs create mode 100644 crates/services/gifbox/src/routes/root.rs create mode 100644 crates/services/gifbox/src/routes/search.rs create mode 100644 crates/services/gifbox/src/routes/trending.rs diff --git a/crates/services/gifbox/src/api.rs b/crates/services/gifbox/src/api.rs deleted file mode 100644 index 36a29757a..000000000 --- a/crates/services/gifbox/src/api.rs +++ /dev/null @@ -1,74 +0,0 @@ -use axum::{ - extract::{Query, State}, - routing::get, - Json, Router, -}; -use revolt_database::User; -use revolt_result::{create_error, Result}; -use serde::{Deserialize, Serialize}; -use utoipa::ToSchema; - -use crate::{ - tenor, - types, - AppState, -}; - -pub async fn router() -> Router { - Router::new() - .route("/", get(root)) - .route("/search", get(search)) -} - -/// Successful root response -#[derive(Serialize, Debug, ToSchema)] -pub struct RootResponse { - message: &'static str, - version: &'static str, -} - -/// Capture crate version from Cargo -static CRATE_VERSION: &str = env!("CARGO_PKG_VERSION"); - -/// Root response from service -#[utoipa::path( - get, - path = "/", - responses( - (status = 200, description = "Echo response", body = RootResponse) - ) -)] -async fn root() -> Json { - Json(RootResponse { - message: "Gifbox lives on!", - version: CRATE_VERSION, - }) -} - -#[derive(Deserialize)] -struct SearchQueryParams { - pub query: String, - pub locale: String, - pub position: Option, -} - -#[utoipa::path( - get, - path = "/search", - responses( - (status = 200, description = "Search results", body = SearchResponse) - ) -)] -async fn search( - _user: User, - Query(params): Query, - State(tenor): State, -) -> Result> { - // Todo - tenor - .search(¶ms.query, ¶ms.locale, params.position.as_deref()) - .await - .map_err(|_| create_error!(InternalError)) - .map(|results| results.as_ref().clone().into()) - .map(Json) -} diff --git a/crates/services/gifbox/src/main.rs b/crates/services/gifbox/src/main.rs index a3339078f..865885182 100644 --- a/crates/services/gifbox/src/main.rs +++ b/crates/services/gifbox/src/main.rs @@ -6,14 +6,14 @@ use revolt_config::config; use revolt_database::{Database, DatabaseInfo}; use tokio::net::TcpListener; use utoipa::{ - openapi::security::{Http, HttpAuthScheme, SecurityScheme}, + openapi::security::{ApiKey, ApiKeyValue, SecurityScheme}, Modify, OpenApi, }; use utoipa_scalar::{Scalar, Servable as ScalarServable}; use crate::tenor::Tenor; -mod api; +mod routes; mod tenor; mod types; @@ -35,6 +35,26 @@ impl FromRef for Tenor { } } +struct TokenAddon; + +impl Modify for TokenAddon { + fn modify(&self, openapi: &mut utoipa::openapi::OpenApi) { + let components = openapi.components.get_or_insert_default(); + + components.add_security_scheme( + "User Token", + SecurityScheme::ApiKey(ApiKey::Header(ApiKeyValue::new( + "X-Session-Token".to_string(), + ))), + ); + + components.add_security_scheme( + "Bot Token", + SecurityScheme::ApiKey(ApiKey::Header(ApiKeyValue::new("X-Bot-Token".to_string()))), + ); + } +} + #[tokio::main] async fn main() -> Result<(), std::io::Error> { // Configure logging and environment @@ -43,36 +63,28 @@ async fn main() -> Result<(), std::io::Error> { // Configure API schema #[derive(OpenApi)] #[openapi( - modifiers(&SecurityAddon), + modifiers(&TokenAddon), paths( - api::root, - api::search, + routes::categories::categories, + routes::root::root, + routes::search::search, + routes::trending::trending, + ), + tags( + (name = "Misc", description = "Misc routes for microservice."), + (name = "GIFs", description = "All routes for requesting GIFs from tenor.") ), components( schemas( revolt_result::Error, revolt_result::ErrorType, - types::SearchResponse, - types::MediaObject, types::MediaResult, + types::MediaObject, ) - ) + ), )] struct ApiDoc; - struct SecurityAddon; - - impl Modify for SecurityAddon { - fn modify(&self, openapi: &mut utoipa::openapi::OpenApi) { - if let Some(components) = openapi.components.as_mut() { - components.add_security_scheme( - "api_key", - SecurityScheme::Http(Http::new(HttpAuthScheme::Bearer)), - ) - } - } - } - let config = config().await; let state = AppState { database: DatabaseInfo::Auto @@ -85,7 +97,7 @@ async fn main() -> Result<(), std::io::Error> { // Configure Axum and router let app = Router::new() .merge(Scalar::with_url("/scalar", ApiDoc::openapi())) - .nest("/", api::router().await) + .nest("/", routes::router()) .with_state(state); // Configure TCP listener and bind diff --git a/crates/services/gifbox/src/routes/categories.rs b/crates/services/gifbox/src/routes/categories.rs new file mode 100644 index 000000000..ae85126d0 --- /dev/null +++ b/crates/services/gifbox/src/routes/categories.rs @@ -0,0 +1,47 @@ +use axum::{ + extract::{Query, State}, + Json, +}; +use revolt_database::User; +use revolt_result::{create_error, Result}; +use serde::Deserialize; +use utoipa::IntoParams; + +use crate::{tenor, types}; + +#[derive(Deserialize, IntoParams)] +pub struct CategoriesQueryParams { + #[param(example = "en_US")] + pub locale: String, +} + +/// Trending GIF categories +#[utoipa::path( + get, + path = "/categories", + tag = "GIFs", + security(("User Token" = []), ("Bot Token" = [])), + params(CategoriesQueryParams), + responses( + (status = 200, description = "Categories results", body = inline(Vec)) + ) +)] +pub async fn categories( + _user: User, + Query(params): Query, + State(tenor): State, +) -> Result>> { + tenor + .categories(¶ms.locale) + .await + .map_err(|_| create_error!(InternalError)) + .map(|results| { + (*results) + .clone() + .tags + .into_iter() + .map(|cat| cat.into()) + .collect() + }) + .map(Json) +} diff --git a/crates/services/gifbox/src/routes/mod.rs b/crates/services/gifbox/src/routes/mod.rs new file mode 100644 index 000000000..efee317f6 --- /dev/null +++ b/crates/services/gifbox/src/routes/mod.rs @@ -0,0 +1,15 @@ +use crate::AppState; +use axum::routing::{get, Router}; + +pub mod categories; +pub mod root; +pub mod search; +pub mod trending; + +pub fn router() -> Router { + Router::new() + .route("/", get(root::root)) + .route("/categories", get(categories::categories)) + .route("/search", get(search::search)) + .route("/trending", get(trending::trending)) +} diff --git a/crates/services/gifbox/src/routes/root.rs b/crates/services/gifbox/src/routes/root.rs new file mode 100644 index 000000000..36acb877d --- /dev/null +++ b/crates/services/gifbox/src/routes/root.rs @@ -0,0 +1,22 @@ +use axum::Json; + +use crate::types; + +/// Capture crate version from Cargo +static CRATE_VERSION: &str = env!("CARGO_PKG_VERSION"); + +/// Root response from service +#[utoipa::path( + get, + path = "/", + tag = "Misc", + responses( + (status = 200, description = "Root response", body = inline(types::RootResponse)) + ) +)] +pub async fn root() -> Json> { + Json(types::RootResponse { + message: "Gifbox lives on!", + version: CRATE_VERSION, + }) +} \ No newline at end of file diff --git a/crates/services/gifbox/src/routes/search.rs b/crates/services/gifbox/src/routes/search.rs new file mode 100644 index 000000000..ec0e6c6ed --- /dev/null +++ b/crates/services/gifbox/src/routes/search.rs @@ -0,0 +1,51 @@ +use axum::{ + extract::{Query, State}, + Json, +}; +use revolt_database::User; +use revolt_result::{create_error, Result}; +use serde::Deserialize; +use utoipa::IntoParams; + +use crate::{tenor, types}; + +#[derive(Deserialize, IntoParams)] +pub struct SearchQueryParams { + #[param(example = "Wave")] + pub query: String, + #[param(example = "en_US")] + pub locale: String, + pub limit: Option, + pub is_category: Option, + pub position: Option, +} + +/// Searches for GIFs with a query +#[utoipa::path( + get, + path = "/search", + tag = "GIFs", + security(("User Token" = []), ("Bot Token" = [])), + params(SearchQueryParams), + responses( + (status = 200, description = "Search results", body = inline(types::PaginatedMediaResponse)) + ) +)] +pub async fn search( + _user: User, + Query(params): Query, + State(tenor): State, +) -> Result> { + tenor + .search( + ¶ms.query, + ¶ms.locale, + params.limit.unwrap_or(50), + params.is_category.unwrap_or_default(), + params.position.as_deref().unwrap_or_default(), + ) + .await + .map_err(|_| create_error!(InternalError)) + .map(|results| results.as_ref().clone().into()) + .map(Json) +} diff --git a/crates/services/gifbox/src/routes/trending.rs b/crates/services/gifbox/src/routes/trending.rs new file mode 100644 index 000000000..f08ed2429 --- /dev/null +++ b/crates/services/gifbox/src/routes/trending.rs @@ -0,0 +1,45 @@ +use axum::{ + extract::{Query, State}, + Json, +}; +use revolt_database::User; +use revolt_result::{create_error, Result}; +use serde::{Deserialize}; +use utoipa::{IntoParams}; + +use crate::{ + tenor, + types, +}; + +#[derive(Deserialize, IntoParams)] +pub struct TrendingQueryParams { + #[param(example = "en_US")] + pub locale: String, + pub limit: Option, + pub position: Option +} + +/// Trending GIFs +#[utoipa::path( + get, + path = "/featured", + tag = "GIFs", + security(("User Token" = []), ("Bot Token" = [])), + params(TrendingQueryParams), + responses( + (status = 200, description = "Trending results", body = inline(types::PaginatedMediaResponse)) + ) +)] +pub async fn trending( + _user: User, + Query(params): Query, + State(tenor): State, +) -> Result> { + tenor + .featured(¶ms.locale, params.limit.unwrap_or(50), params.position.as_deref().unwrap_or_default()) + .await + .map_err(|_| create_error!(InternalError)) + .map(|results| results.as_ref().clone().into()) + .map(Json) +} diff --git a/crates/services/gifbox/src/tenor/mod.rs b/crates/services/gifbox/src/tenor/mod.rs index 2ff3785c4..da9b97aad 100644 --- a/crates/services/gifbox/src/tenor/mod.rs +++ b/crates/services/gifbox/src/tenor/mod.rs @@ -3,6 +3,7 @@ use std::{sync::Arc, time::Duration}; use lru_time_cache::LruCache; use reqwest::Client; use revolt_coalesced::{CoalescionService, CoalescionServiceConfig}; +use serde::de::DeserializeOwned; use tokio::sync::RwLock; use urlencoding::encode as url_encode; @@ -19,34 +20,89 @@ pub enum TenorError { pub struct Tenor { pub key: Arc, pub client: Client, - pub coalescion: CoalescionService, TenorError>>, - pub cache: Arc>>>, + + pub cache: Arc>>>, + pub cache_coalescion: + CoalescionService, TenorError>>, + + pub categories: Arc>>>, + pub categories_coalescion: + CoalescionService, TenorError>>, + + pub featured: Arc>>>, + pub featured_coalescion: + CoalescionService, TenorError>>, } impl Tenor { pub fn new(key: &str) -> Self { - // 1 hour, 1k queries - let cache = LruCache::with_expiry_duration_and_capacity(Duration::from_secs(60 * 60), 1000); - Self { key: Arc::from(key), client: Client::new(), - coalescion: CoalescionService::from_config(CoalescionServiceConfig { + + // 1 hour, 1k requests + cache: Arc::new(RwLock::new(LruCache::with_expiry_duration_and_capacity( + Duration::from_secs(60 * 60), + 1000, + ))), + cache_coalescion: CoalescionService::from_config(CoalescionServiceConfig { + max_concurrent: Some(100), + queue_requests: true, + max_queue: None, + }), + + // 1 day, 1k requests + categories: Arc::new(RwLock::new(LruCache::with_expiry_duration_and_capacity( + Duration::from_secs(60 * 60 * 24), + 1000, + ))), + categories_coalescion: CoalescionService::from_config(CoalescionServiceConfig { + max_concurrent: Some(100), + queue_requests: true, + max_queue: None, + }), + + // 1 day, 1k requests + featured: Arc::new(RwLock::new(LruCache::with_expiry_duration_and_capacity( + Duration::from_secs(60 * 60 * 24), + 1000, + ))), + featured_coalescion: CoalescionService::from_config(CoalescionServiceConfig { max_concurrent: Some(100), queue_requests: true, max_queue: None, }), - cache: Arc::new(RwLock::new(cache)), } } + pub async fn request(&self, path: String) -> Result, TenorError> { + let response = self + .client + .get(format!("{TENOR_API_BASE_URL}{path}")) + .send() + .await + .inspect_err(|e| { + revolt_config::capture_error(e); + }) + .map_err(|_| TenorError::HttpError)?; + + let text = response.text().await.map_err(|e| { + println!("{e:?}"); + TenorError::HttpError + })?; + + Ok(Arc::new(serde_json::from_str(&text).unwrap())) + } + pub async fn search( &self, query: &str, locale: &str, - position: Option<&str>, - ) -> Result, TenorError> { - let unique_key = format!("{query}:{locale}:{position:?}"); + limit: u32, + is_category: bool, + position: &str, + ) -> Result, TenorError> { + let unique_key = format!("s:{query}:{locale}:{is_category}:{position}"); if self.cache.read().await.contains_key(&unique_key) { if let Some(response) = self.cache.write().await.get(&unique_key) { @@ -54,38 +110,107 @@ impl Tenor { } } - let res = self.coalescion.execute(unique_key.clone(), || { - let client = self.client.clone(); + let res = self.cache_coalescion.execute(unique_key.clone(), || { + let mut path = format!( + "/search?key={}&q={}&client_key=Gifbox&media_filter=webm,tinywebm&locale={}&contentfilter=high&limit={limit}", + &self.key, + url_encode(query), + url_encode(locale), + ); + + if !position.is_empty() { + path.push_str("&pos="); + path.push_str(position); + }; + + if is_category { + path.push_str("&component=categories"); + } + + self.request(path) + }) + .await + .unwrap(); - async move { - let mut url = format!( - "{TENOR_API_BASE_URL}/search?key={}&q={}&client_key=Gifbox&media_filter=webm,tinywebm&locale={}&contentfilter=medium&limit=1", + if let Ok(resp) = &*res { + self.cache.write().await.insert(unique_key, resp.clone()); + } + + (*res).clone() + } + + pub async fn categories( + &self, + locale: &str, + ) -> Result, TenorError> { + let unique_key = format!("c-{locale}"); + + if self.categories.read().await.contains_key(&unique_key) { + if let Some(response) = self.categories.write().await.get(&unique_key) { + return Ok(response.clone()); + } + } + + let res = self + .categories_coalescion + .execute(unique_key.clone(), || { + let path = format!( + "/categories?key={}&client_key=Gifbox&locale={}&contentfilter=high", &self.key, - url_encode(query), url_encode(locale), ); - if let Some(position) = position { - url.push_str("&pos="); - url.push_str(position); - }; + self.request(path) + }) + .await + .unwrap(); + + if let Ok(resp) = &*res { + self.categories + .write() + .await + .insert(unique_key, resp.clone()); + } - let response = client.get(url) - .send() - .await - .inspect_err(|e| { revolt_config::capture_error(e); }) - .map_err(|_| TenorError::HttpError)?; + (*res).clone() + } - let text = response.text().await.map_err(|e| { println!("{e:?}"); TenorError::HttpError })?; + pub async fn featured( + &self, + locale: &str, + limit: u32, + position: &str, + ) -> Result, TenorError> { + let unique_key = format!("f-{locale}-{limit}-{position}"); - Ok(Arc::new(serde_json::from_str(&text).unwrap())) + if self.categories.read().await.contains_key(&unique_key) { + if let Some(response) = self.featured.write().await.get(&unique_key) { + return Ok(response.clone()); } + } + + let res = self.featured_coalescion.execute(unique_key.clone(), || { + let mut path = format!( + "/featured?key={}&client_key=Gifbox&media_filter=webm,tinywebm&locale={}&contentfilter=high&limit={limit}", + &self.key, + url_encode(locale), + ); + + if !position.is_empty() { + path.push_str("&pos="); + path.push_str(position); + }; + + self.request(path) }) .await .unwrap(); if let Ok(resp) = &*res { - self.cache.write().await.insert(unique_key, resp.clone()); + self.featured + .write() + .await + .insert(unique_key, resp.clone()); } (*res).clone() diff --git a/crates/services/gifbox/src/tenor/types.rs b/crates/services/gifbox/src/tenor/types.rs index b4ad4a084..8165e4b4a 100644 --- a/crates/services/gifbox/src/tenor/types.rs +++ b/crates/services/gifbox/src/tenor/types.rs @@ -3,8 +3,8 @@ use std::collections::HashMap; use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -pub struct SearchResponse { - pub results: Vec, +pub struct PaginatedMediaResponse { + pub results: Vec, pub next: String, } @@ -17,7 +17,7 @@ pub struct MediaObject { } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -pub struct MediaResult { +pub struct MediaResponse { pub created: f64, #[serde(default)] pub hasaudio: bool, @@ -33,3 +33,17 @@ pub struct MediaResult { pub bg_color: Option, pub url: String, } + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct CategoriesResponse { + pub locale: String, + pub tags: Vec, +} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct CategoryResponse { + pub searchterm: String, + pub path: String, + pub image: String, + pub name: String, +} diff --git a/crates/services/gifbox/src/types.rs b/crates/services/gifbox/src/types.rs index d42676023..1ee07e8a4 100644 --- a/crates/services/gifbox/src/types.rs +++ b/crates/services/gifbox/src/types.rs @@ -1,13 +1,20 @@ use std::collections::HashMap; +use serde::{Deserialize, Serialize}; use utoipa::ToSchema; -use serde::{Serialize, Deserialize}; use crate::tenor::types; -#[derive(Serialize, Deserialize, ToSchema, Clone, Debug, PartialEq)] +/// Successful root response +#[derive(Serialize, Debug, ToSchema)] +pub struct RootResponse<'a> { + pub message: &'a str, + pub version: &'a str, +} + /// Response containing the current results and the id of the next result for pagination. -pub struct SearchResponse { +#[derive(Serialize, Deserialize, ToSchema, Clone, Debug, PartialEq)] +pub struct PaginatedMediaResponse { /// Current gif results. pub results: Vec, #[serde(skip_serializing_if = "Option::is_none")] @@ -15,19 +22,19 @@ pub struct SearchResponse { pub next: Option, } -#[derive(Serialize, Deserialize, ToSchema, Clone, Debug, PartialEq)] /// Indivual gif result. +#[derive(Serialize, Deserialize, ToSchema, Clone, Debug, PartialEq)] pub struct MediaResult { /// Unique Tenor id. pub id: String, /// Mapping of each file format and url of the file. pub media_formats: HashMap, /// Public Tenor web url for the gif. - pub url: String + pub url: String, } -#[derive(Serialize, Deserialize, ToSchema, Clone, Debug, PartialEq)] /// Represents the gif in a certain file format. +#[derive(Serialize, Deserialize, ToSchema, Clone, Debug, PartialEq)] pub struct MediaObject { /// File url of the gif in a certain format. pub url: String, @@ -35,26 +42,42 @@ pub struct MediaObject { pub dimensions: Vec, } +/// Represents a GIF category +#[derive(Serialize, Deserialize, ToSchema, Clone, Debug, PartialEq)] +pub struct CategoryResponse { + /// Category title + pub title: String, + /// Category image + pub image: String, +} -impl From for SearchResponse { - fn from(value: types::SearchResponse) -> Self { +impl From for PaginatedMediaResponse { + fn from(value: types::PaginatedMediaResponse) -> Self { Self { - results: value.results.into_iter().map(|result| result.into()).collect(), + results: value + .results + .into_iter() + .map(|result| result.into()) + .collect(), next: if value.next.is_empty() { None } else { Some(value.next) - } + }, } } } -impl From for MediaResult { - fn from(value: types::MediaResult) -> Self { +impl From for MediaResult { + fn from(value: types::MediaResponse) -> Self { Self { id: value.id, - media_formats: value.media_formats.into_iter().map(|(k, v)| (k, v.into())).collect(), - url: value.url + media_formats: value + .media_formats + .into_iter() + .map(|(k, v)| (k, v.into())) + .collect(), + url: value.url, } } } @@ -63,7 +86,16 @@ impl From for MediaObject { fn from(value: types::MediaObject) -> Self { Self { url: value.url, - dimensions: value.dims + dimensions: value.dims, } } -} \ No newline at end of file +} + +impl From for CategoryResponse { + fn from(value: types::CategoryResponse) -> Self { + Self { + title: value.searchterm, + image: value.image, + } + } +} From db559985465fdd04dc7864a443b727f19d5711c5 Mon Sep 17 00:00:00 2001 From: Zomatree Date: Mon, 15 Sep 2025 01:44:21 +0100 Subject: [PATCH 012/211] docs: document `revolt-coalesced` --- crates/core/coalesced/Cargo.toml | 2 +- crates/core/coalesced/src/config.rs | 1 + crates/core/coalesced/src/error.rs | 15 +++- crates/core/coalesced/src/lib.rs | 34 ++++++- crates/core/coalesced/src/service.rs | 88 ++++++++++++++----- crates/services/gifbox/Cargo.toml | 11 ++- .../services/gifbox/src/routes/categories.rs | 1 + crates/services/gifbox/src/routes/root.rs | 2 +- crates/services/gifbox/src/routes/search.rs | 5 ++ crates/services/gifbox/src/routes/trending.rs | 20 +++-- crates/services/gifbox/src/tenor/mod.rs | 48 ++++------ crates/services/gifbox/src/tenor/types.rs | 2 + 12 files changed, 154 insertions(+), 75 deletions(-) diff --git a/crates/core/coalesced/Cargo.toml b/crates/core/coalesced/Cargo.toml index 4485d65db..cb23a8adb 100644 --- a/crates/core/coalesced/Cargo.toml +++ b/crates/core/coalesced/Cargo.toml @@ -11,7 +11,7 @@ tokio = ["dep:tokio"] queue = ["dep:indexmap"] cache = ["dep:lru"] -default = ["tokio", "queue", "cache"] +default = ["tokio"] [dependencies] tokio = { version = "1.47.0", features = ["sync"], optional = true } diff --git a/crates/core/coalesced/src/config.rs b/crates/core/coalesced/src/config.rs index 00ef7990b..23da16989 100644 --- a/crates/core/coalesced/src/config.rs +++ b/crates/core/coalesced/src/config.rs @@ -1,4 +1,5 @@ #[derive(Clone, PartialEq, Eq, Debug)] +/// Config values for [`CoalescionService`]. pub struct CoalescionServiceConfig { /// How many tasks are running at once pub max_concurrent: Option, diff --git a/crates/core/coalesced/src/error.rs b/crates/core/coalesced/src/error.rs index a53955971..6be897858 100644 --- a/crates/core/coalesced/src/error.rs +++ b/crates/core/coalesced/src/error.rs @@ -1,18 +1,25 @@ -use std::fmt::Display; +use std::fmt; -#[derive(Clone, PartialEq, Eq, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] +/// Coalescion service error. pub enum Error { + /// Failed to receive the actions return from the channel for unknown reason RecvError, + /// Reached the `max_concurrent` amount of actions running at once and could not queue the action MaxConcurrent, + /// Reached the `max_queue` amount of actions in the queue MaxQueue, + /// Failed to downcast the type to the current type being returned, this will be most likely an ID collision + DowncastError, } -impl Display for Error { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Error::RecvError => write!(f, "Unable to receive data from the channel"), Error::MaxConcurrent => write!(f, "Max number of tasks running at once"), Error::MaxQueue => write!(f, "Max number of tasks in queue"), + Error::DowncastError => write!(f, "Failed to downcast type, possible key collision with different types") } } } diff --git a/crates/core/coalesced/src/lib.rs b/crates/core/coalesced/src/lib.rs index 6fd18267a..89839e23a 100644 --- a/crates/core/coalesced/src/lib.rs +++ b/crates/core/coalesced/src/lib.rs @@ -1,7 +1,39 @@ +//! # Coalesced +//! +//! Coalescion service to group, caching and queue duplicate actions. +//! useful for deduplicating web requests, database lookups and other similar resource +//! intensive or rate-limited actions. +//! +//! ## Features +//! - `tokio`: Uses tokio for the async backend, this is currently the only backend. +//! - `queue`: Whether to support queueing requests to only allow X amount of actions running at once. +//! - `cache`: Whether to cache the actions results for future actions with the same id, uses an LRU cache internally. +//! +//! [`CoalescionService`] uses both [`Arc`] and [`RwLock`] internally and can be cheaply cloned to +//! use in your codebase. +//! +//! It is common practice to wrap the service and in your own which delegates the executions to ensure all ids are tracked in one location across your codebase. +//! +//! All values are stored using [`Any`] and must be [`'static`] + [`Send`] + [`Sync`], if there is an id mismatch +//! and a type is wrong the library will return an error, values returned from the service are also +//! wrapped in an [`Arc`] as they are shared to each duplicate action. +//! +//! ## Example: +//! ```rs +//! use revolt_coalesced::CoalescionService; +//! +//! let service = CoalescionService::new(); +//! +//! let user_id = "my_user_id"; +//! let user = service.execute(user_id, || async move { +//! database.fetch_user(user_id).await.unwrap() +//! }).await; +//! ``` + mod config; mod error; mod service; pub use config::CoalescionServiceConfig; pub use error::Error; -pub use service::CoalescionService; \ No newline at end of file +pub use service::CoalescionService; diff --git a/crates/core/coalesced/src/service.rs b/crates/core/coalesced/src/service.rs index 3d3b1c9b0..aadadc8a0 100644 --- a/crates/core/coalesced/src/service.rs +++ b/crates/core/coalesced/src/service.rs @@ -1,6 +1,9 @@ -use std::{collections::{HashMap}, fmt::Debug, hash::Hash, sync::Arc, future::Future}; +use std::{any::Any, collections::HashMap, fmt::Debug, future::Future, hash::Hash, sync::Arc}; -use tokio::{sync::{watch::{channel as watch_channel, Receiver}, RwLock, Mutex}}; +use tokio::sync::{ + watch::{channel as watch_channel, Receiver}, + RwLock, +}; #[cfg(feature = "cache")] use lru::LruCache; @@ -10,20 +13,23 @@ use indexmap::IndexMap; use crate::{CoalescionServiceConfig, Error}; -#[derive(Clone, Debug)] +#[derive(Debug, Clone)] #[allow(clippy::type_complexity)] -pub struct CoalescionService { +/// # Coalescion service +/// +/// See module description for example usage. +pub struct CoalescionService { config: Arc, - watchers: Arc, Error>>>>>>, + watchers: Arc, Error>>>>>>, #[cfg(feature = "queue")] - queue: Arc, Error>>>>>>, + queue: Arc, Error>>>>>>, #[cfg(feature = "cache")] - cache: Option>>>>, + cache: Option>>>>, } -impl CoalescionService { +impl CoalescionService { pub fn new() -> Self { - Self::default() + Default::default() } pub fn from_config(config: CoalescionServiceConfig) -> Self { @@ -38,22 +44,37 @@ impl CoalescionService>) -> Self { + pub fn from_cache( + config: CoalescionServiceConfig, + cache: LruCache>, + ) -> Self { Self { cache: Some(Arc::new(Mutex::new(cache))), ..Self::from_config(config) } } - async fn wait_for(&self, mut receiver: Receiver, Error>>>) -> Result, Error> { + async fn wait_for( + &self, + mut receiver: Receiver, Error>>>, + ) -> Result, Error> { receiver .wait_for(|v| v.is_some()) .await .map_err(|_| Error::RecvError) .and_then(|r| r.clone().unwrap()) + .and_then(|arc| Arc::downcast(arc).map_err(|_| Error::DowncastError)) } - async fn insert_and_execute Fut, Fut: Future>(&self, id: Id, func: F) -> Result, Error> { + async fn insert_and_execute< + Value: Send + Sync + 'static, + F: FnOnce() -> Fut, + Fut: Future, + >( + &self, + id: Id, + func: F, + ) -> Result, Error> { let (send, recv) = watch_channel(None); self.watchers.write().await.insert(id.clone(), recv); @@ -61,7 +82,7 @@ impl CoalescionService)); }); #[cfg(feature = "cache")] @@ -76,11 +97,21 @@ impl CoalescionService Fut, Fut: Future>(&self, id: Id, func: F) -> Result, Error> { + /// Coalesces an function, the actual function may not run if one with the same id is already running, + /// queued to be ran, or cached, the id should be globally unique for this specific action. + pub async fn execute< + Value: Send + Sync + 'static, + F: FnOnce() -> Fut, + Fut: Future, + >( + &self, + id: Id, + func: F, + ) -> Result, Error> { #[cfg(feature = "cache")] if let Some(cache) = self.cache.as_ref() { if let Some(value) = cache.lock().await.get(&id) { - return Ok(value.clone()) + return Arc::downcast::(value.clone()).map_err(|_| Error::DowncastError); } }; @@ -105,10 +136,14 @@ impl CoalescionService= length) { - return Err(Error::MaxQueue) + if self + .config + .max_queue + .is_some_and(|max_queue| max_queue >= length) + { + return Err(Error::MaxQueue); }; let (send, recv) = watch_channel(None); @@ -130,10 +165,14 @@ impl CoalescionService), + ); }); - return response + return response; } } } @@ -145,23 +184,24 @@ impl CoalescionService { - self.insert_and_execute(id, func).await - } + _ => self.insert_and_execute(id, func).await, } } } + /// Fetches the amount of currently running tasks pub async fn current_task_count(&self) -> usize { self.watchers.read().await.len() } + #[cfg(feature = "queue")] + /// Fetches the current length of the queue pub async fn current_queue_len(&self) -> usize { self.queue.read().await.len() } } -impl Default for CoalescionService { +impl Default for CoalescionService { fn default() -> Self { Self::from_config(CoalescionServiceConfig::default()) } diff --git a/crates/services/gifbox/Cargo.toml b/crates/services/gifbox/Cargo.toml index 94cd07321..f67a04e82 100644 --- a/crates/services/gifbox/Cargo.toml +++ b/crates/services/gifbox/Cargo.toml @@ -22,8 +22,13 @@ revolt-result = { version = "0.8.8", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-coalesced = { version = "0.8.8", path = "../../core/coalesced" } -revolt-database = { version = "0.8.8", path = "../../core/database", features = ["axum-impl"] } +revolt-coalesced = { version = "0.8.8", path = "../../core/coalesced", features = [ + "queue", +] } +revolt-database = { version = "0.8.8", path = "../../core/database", features = [ + "axum-impl", +] } + # Axum / web server axum = { version = "0.7.5" } axum-extra = { version = "0.9", features = ["typed-header"] } @@ -37,4 +42,4 @@ tracing = "0.1" # Utils lru_time_cache = "0.11.11" -urlencoding = "2.1.3" \ No newline at end of file +urlencoding = "2.1.3" diff --git a/crates/services/gifbox/src/routes/categories.rs b/crates/services/gifbox/src/routes/categories.rs index ae85126d0..a79f03c0a 100644 --- a/crates/services/gifbox/src/routes/categories.rs +++ b/crates/services/gifbox/src/routes/categories.rs @@ -11,6 +11,7 @@ use crate::{tenor, types}; #[derive(Deserialize, IntoParams)] pub struct CategoriesQueryParams { + /// Users locale #[param(example = "en_US")] pub locale: String, } diff --git a/crates/services/gifbox/src/routes/root.rs b/crates/services/gifbox/src/routes/root.rs index 36acb877d..4bf3aed56 100644 --- a/crates/services/gifbox/src/routes/root.rs +++ b/crates/services/gifbox/src/routes/root.rs @@ -19,4 +19,4 @@ pub async fn root() -> Json> { message: "Gifbox lives on!", version: CRATE_VERSION, }) -} \ No newline at end of file +} diff --git a/crates/services/gifbox/src/routes/search.rs b/crates/services/gifbox/src/routes/search.rs index ec0e6c6ed..ac541dc2b 100644 --- a/crates/services/gifbox/src/routes/search.rs +++ b/crates/services/gifbox/src/routes/search.rs @@ -11,12 +11,17 @@ use crate::{tenor, types}; #[derive(Deserialize, IntoParams)] pub struct SearchQueryParams { + /// Search query #[param(example = "Wave")] pub query: String, + /// Users locale #[param(example = "en_US")] pub locale: String, + /// Amount of results to respond with pub limit: Option, + /// Flag for if searching in a gif category pub is_category: Option, + /// Value of `next` for getting the next page of results with the current search query pub position: Option, } diff --git a/crates/services/gifbox/src/routes/trending.rs b/crates/services/gifbox/src/routes/trending.rs index f08ed2429..b81055242 100644 --- a/crates/services/gifbox/src/routes/trending.rs +++ b/crates/services/gifbox/src/routes/trending.rs @@ -4,20 +4,20 @@ use axum::{ }; use revolt_database::User; use revolt_result::{create_error, Result}; -use serde::{Deserialize}; -use utoipa::{IntoParams}; +use serde::Deserialize; +use utoipa::IntoParams; -use crate::{ - tenor, - types, -}; +use crate::{tenor, types}; #[derive(Deserialize, IntoParams)] pub struct TrendingQueryParams { #[param(example = "en_US")] + /// Users locale pub locale: String, + /// Amount of results to respond with pub limit: Option, - pub position: Option + /// Value of `next` for getting the next page of results of featured gifs + pub position: Option, } /// Trending GIFs @@ -37,7 +37,11 @@ pub async fn trending( State(tenor): State, ) -> Result> { tenor - .featured(¶ms.locale, params.limit.unwrap_or(50), params.position.as_deref().unwrap_or_default()) + .featured( + ¶ms.locale, + params.limit.unwrap_or(50), + params.position.as_deref().unwrap_or_default(), + ) .await .map_err(|_| create_error!(InternalError)) .map(|results| results.as_ref().clone().into()) diff --git a/crates/services/gifbox/src/tenor/mod.rs b/crates/services/gifbox/src/tenor/mod.rs index da9b97aad..c90b74ced 100644 --- a/crates/services/gifbox/src/tenor/mod.rs +++ b/crates/services/gifbox/src/tenor/mod.rs @@ -1,3 +1,5 @@ +//! Interal Tenor API wrapper + use std::{sync::Arc, time::Duration}; use lru_time_cache::LruCache; @@ -20,18 +22,11 @@ pub enum TenorError { pub struct Tenor { pub key: Arc, pub client: Client, - + pub coalescion: CoalescionService, pub cache: Arc>>>, - pub cache_coalescion: - CoalescionService, TenorError>>, pub categories: Arc>>>, - pub categories_coalescion: - CoalescionService, TenorError>>, - pub featured: Arc>>>, - pub featured_coalescion: - CoalescionService, TenorError>>, } impl Tenor { @@ -39,39 +34,29 @@ impl Tenor { Self { key: Arc::from(key), client: Client::new(), + coalescion: CoalescionService::from_config(CoalescionServiceConfig { + max_concurrent: Some(100), + queue_requests: true, + max_queue: None, + }), // 1 hour, 1k requests cache: Arc::new(RwLock::new(LruCache::with_expiry_duration_and_capacity( Duration::from_secs(60 * 60), 1000, ))), - cache_coalescion: CoalescionService::from_config(CoalescionServiceConfig { - max_concurrent: Some(100), - queue_requests: true, - max_queue: None, - }), // 1 day, 1k requests categories: Arc::new(RwLock::new(LruCache::with_expiry_duration_and_capacity( Duration::from_secs(60 * 60 * 24), 1000, ))), - categories_coalescion: CoalescionService::from_config(CoalescionServiceConfig { - max_concurrent: Some(100), - queue_requests: true, - max_queue: None, - }), // 1 day, 1k requests featured: Arc::new(RwLock::new(LruCache::with_expiry_duration_and_capacity( Duration::from_secs(60 * 60 * 24), 1000, ))), - featured_coalescion: CoalescionService::from_config(CoalescionServiceConfig { - max_concurrent: Some(100), - queue_requests: true, - max_queue: None, - }), } } @@ -110,7 +95,7 @@ impl Tenor { } } - let res = self.cache_coalescion.execute(unique_key.clone(), || { + let res = self.coalescion.execute(unique_key.clone(), || { let mut path = format!( "/search?key={}&q={}&client_key=Gifbox&media_filter=webm,tinywebm&locale={}&contentfilter=high&limit={limit}", &self.key, @@ -127,7 +112,7 @@ impl Tenor { path.push_str("&component=categories"); } - self.request(path) + self.request::(path) }) .await .unwrap(); @@ -152,7 +137,7 @@ impl Tenor { } let res = self - .categories_coalescion + .coalescion .execute(unique_key.clone(), || { let path = format!( "/categories?key={}&client_key=Gifbox&locale={}&contentfilter=high", @@ -160,7 +145,7 @@ impl Tenor { url_encode(locale), ); - self.request(path) + self.request::(path) }) .await .unwrap(); @@ -189,7 +174,7 @@ impl Tenor { } } - let res = self.featured_coalescion.execute(unique_key.clone(), || { + let res = self.coalescion.execute(unique_key.clone(), || { let mut path = format!( "/featured?key={}&client_key=Gifbox&media_filter=webm,tinywebm&locale={}&contentfilter=high&limit={limit}", &self.key, @@ -201,16 +186,13 @@ impl Tenor { path.push_str(position); }; - self.request(path) + self.request::(path) }) .await .unwrap(); if let Ok(resp) = &*res { - self.featured - .write() - .await - .insert(unique_key, resp.clone()); + self.featured.write().await.insert(unique_key, resp.clone()); } (*res).clone() diff --git a/crates/services/gifbox/src/tenor/types.rs b/crates/services/gifbox/src/tenor/types.rs index 8165e4b4a..15658252f 100644 --- a/crates/services/gifbox/src/tenor/types.rs +++ b/crates/services/gifbox/src/tenor/types.rs @@ -1,3 +1,5 @@ +//! Tenor API models + use std::collections::HashMap; use serde::{Deserialize, Serialize}; From 154204742d21cbeff6e2577b00f50b495ea44631 Mon Sep 17 00:00:00 2001 From: Zomatree Date: Thu, 18 Sep 2025 21:46:08 +0100 Subject: [PATCH 013/211] feat: add ratelimits to gifbox --- Cargo.lock | 1 + crates/services/gifbox/Cargo.toml | 3 ++ crates/services/gifbox/src/main.rs | 47 +++++++++++++----------- crates/services/gifbox/src/ratelimits.rs | 32 ++++++++++++++++ 4 files changed, 61 insertions(+), 22 deletions(-) create mode 100644 crates/services/gifbox/src/ratelimits.rs diff --git a/Cargo.lock b/Cargo.lock index 1274b75ac..3270fbf34 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6519,6 +6519,7 @@ dependencies = [ "revolt-config", "revolt-database", "revolt-models", + "revolt-ratelimits", "revolt-result", "serde", "serde_json", diff --git a/crates/services/gifbox/Cargo.toml b/crates/services/gifbox/Cargo.toml index f67a04e82..b640766e6 100644 --- a/crates/services/gifbox/Cargo.toml +++ b/crates/services/gifbox/Cargo.toml @@ -28,6 +28,9 @@ revolt-coalesced = { version = "0.8.8", path = "../../core/coalesced", features revolt-database = { version = "0.8.8", path = "../../core/database", features = [ "axum-impl", ] } +revolt-ratelimits = { version = "0.8.8", path = "../../core/ratelimits", features = [ + "axum", +] } # Axum / web server axum = { version = "0.7.5" } diff --git a/crates/services/gifbox/src/main.rs b/crates/services/gifbox/src/main.rs index 865885182..059cb22f1 100644 --- a/crates/services/gifbox/src/main.rs +++ b/crates/services/gifbox/src/main.rs @@ -1,9 +1,10 @@ use std::net::{Ipv4Addr, SocketAddr}; -use axum::{extract::FromRef, Router}; +use axum::{extract::FromRef, middleware::from_fn_with_state, Router}; use revolt_config::config; use revolt_database::{Database, DatabaseInfo}; +use revolt_ratelimits::axum as ratelimiter; use tokio::net::TcpListener; use utoipa::{ openapi::security::{ApiKey, ApiKeyValue, SecurityScheme}, @@ -13,31 +14,21 @@ use utoipa_scalar::{Scalar, Servable as ScalarServable}; use crate::tenor::Tenor; +mod ratelimits; mod routes; mod tenor; mod types; -#[derive(Clone)] +#[derive(Clone, FromRef)] struct AppState { pub database: Database, pub tenor: Tenor, + pub ratelimit_storage: ratelimiter::RatelimitStorage, } -impl FromRef for Database { - fn from_ref(state: &AppState) -> Self { - state.database.clone() - } -} - -impl FromRef for Tenor { - fn from_ref(state: &AppState) -> Self { - state.tenor.clone() - } -} +struct SecurityAddon; -struct TokenAddon; - -impl Modify for TokenAddon { +impl Modify for SecurityAddon { fn modify(&self, openapi: &mut utoipa::openapi::OpenApi) { let components = openapi.components.get_or_insert_default(); @@ -63,7 +54,7 @@ async fn main() -> Result<(), std::io::Error> { // Configure API schema #[derive(OpenApi)] #[openapi( - modifiers(&TokenAddon), + modifiers(&SecurityAddon), paths( routes::categories::categories, routes::root::root, @@ -86,18 +77,30 @@ async fn main() -> Result<(), std::io::Error> { struct ApiDoc; let config = config().await; + + let database = DatabaseInfo::Auto + .connect() + .await + .expect("Unable to connect to database"); + + let tenor = tenor::Tenor::new(&config.api.security.tenor_key); + + let ratelimit_storage = ratelimiter::RatelimitStorage::new(ratelimits::GifboxRatelimits); + let state = AppState { - database: DatabaseInfo::Auto - .connect() - .await - .expect("Unable to connect to database"), - tenor: tenor::Tenor::new(&config.api.security.tenor_key), + database, + tenor, + ratelimit_storage, }; // Configure Axum and router let app = Router::new() .merge(Scalar::with_url("/scalar", ApiDoc::openapi())) .nest("/", routes::router()) + .layer(from_fn_with_state( + state.clone(), + ratelimiter::ratelimit_middleware, + )) .with_state(state); // Configure TCP listener and bind diff --git a/crates/services/gifbox/src/ratelimits.rs b/crates/services/gifbox/src/ratelimits.rs new file mode 100644 index 000000000..10c904d4e --- /dev/null +++ b/crates/services/gifbox/src/ratelimits.rs @@ -0,0 +1,32 @@ +use axum::http::request::Parts; +use revolt_ratelimits::ratelimiter::RatelimitResolver; + +pub struct GifboxRatelimits; + +impl RatelimitResolver for GifboxRatelimits { + fn resolve_bucket<'a>(&self, parts: &'a Parts) -> (&'a str, Option<&'a str>) { + let path = parts + .uri + .path() + .trim_matches('/') + .split_terminator("/") + .next(); + + match path { + Some("categories") => ("categories", None), + Some("trending") => ("trending", None), + Some("search") => ("search", None), + _ => ("any", None), + } + } + + fn resolve_bucket_limit(&self, bucket: &str) -> u32 { + match bucket { + "categories" => 2, + "trending" => 5, + "search" => 10, + "any" => u32::MAX, + _ => unreachable!("Bucket defined but no limit set"), + } + } +} From 38dd4d10797b3e6e397fc219e818f379bdff19f2 Mon Sep 17 00:00:00 2001 From: Zomatree Date: Fri, 19 Sep 2025 01:48:23 +0100 Subject: [PATCH 014/211] fix: swap to using reqwest for query building --- Cargo.lock | 1 - crates/services/gifbox/Cargo.toml | 1 - crates/services/gifbox/Dockerfile | 2 - crates/services/gifbox/src/tenor/mod.rs | 85 ++++++++++++------------- 4 files changed, 42 insertions(+), 47 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3270fbf34..01223df48 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6525,7 +6525,6 @@ dependencies = [ "serde_json", "tokio 1.47.1", "tracing", - "urlencoding", "utoipa", "utoipa-scalar", ] diff --git a/crates/services/gifbox/Cargo.toml b/crates/services/gifbox/Cargo.toml index b640766e6..3e2b41736 100644 --- a/crates/services/gifbox/Cargo.toml +++ b/crates/services/gifbox/Cargo.toml @@ -45,4 +45,3 @@ tracing = "0.1" # Utils lru_time_cache = "0.11.11" -urlencoding = "2.1.3" diff --git a/crates/services/gifbox/Dockerfile b/crates/services/gifbox/Dockerfile index 5668448fd..196409b70 100644 --- a/crates/services/gifbox/Dockerfile +++ b/crates/services/gifbox/Dockerfile @@ -4,8 +4,6 @@ FROM ghcr.io/revoltchat/base:latest AS builder # Bundle Stage FROM gcr.io/distroless/cc-debian12:nonroot COPY --from=builder /home/rust/src/target/release/revolt-gifbox ./ -COPY --from=mwader/static-ffmpeg:7.0.2 /ffmpeg /usr/local/bin/ -COPY --from=mwader/static-ffmpeg:7.0.2 /ffprobe /usr/local/bin/ EXPOSE 14706 USER nonroot diff --git a/crates/services/gifbox/src/tenor/mod.rs b/crates/services/gifbox/src/tenor/mod.rs index c90b74ced..a9971b17c 100644 --- a/crates/services/gifbox/src/tenor/mod.rs +++ b/crates/services/gifbox/src/tenor/mod.rs @@ -1,4 +1,4 @@ -//! Interal Tenor API wrapper +//! Internal Tenor API wrapper use std::{sync::Arc, time::Duration}; @@ -7,7 +7,6 @@ use reqwest::Client; use revolt_coalesced::{CoalescionService, CoalescionServiceConfig}; use serde::de::DeserializeOwned; use tokio::sync::RwLock; -use urlencoding::encode as url_encode; pub mod types; @@ -60,10 +59,11 @@ impl Tenor { } } - pub async fn request(&self, path: String) -> Result, TenorError> { + pub async fn request(&self, path: &str, query: &[Option<(&str, &str)>]) -> Result, TenorError> { let response = self .client .get(format!("{TENOR_API_BASE_URL}{path}")) + .query(query) .send() .await .inspect_err(|e| { @@ -72,7 +72,7 @@ impl Tenor { .map_err(|_| TenorError::HttpError)?; let text = response.text().await.map_err(|e| { - println!("{e:?}"); + revolt_config::capture_error(&e); TenorError::HttpError })?; @@ -95,24 +95,21 @@ impl Tenor { } } - let res = self.coalescion.execute(unique_key.clone(), || { - let mut path = format!( - "/search?key={}&q={}&client_key=Gifbox&media_filter=webm,tinywebm&locale={}&contentfilter=high&limit={limit}", - &self.key, - url_encode(query), - url_encode(locale), - ); - - if !position.is_empty() { - path.push_str("&pos="); - path.push_str(position); - }; - - if is_category { - path.push_str("&component=categories"); - } - - self.request::(path) + let res = self.coalescion.execute(unique_key.clone(), || async move { + self.request::( + "/search", + &[ + Some(("key", &self.key)), + Some(("q", query)), + Some(("client_key", "Gifbox")), + Some(("media_filter", "webm,tinywebm")), + Some(("locale", locale)), + Some(("contentfilter", "high")), + Some(("limit", &limit.to_string())), + position.is_empty().then_some(("pos", position)), + is_category.then_some(("component", "categories")) + ] + ).await }) .await .unwrap(); @@ -138,14 +135,16 @@ impl Tenor { let res = self .coalescion - .execute(unique_key.clone(), || { - let path = format!( - "/categories?key={}&client_key=Gifbox&locale={}&contentfilter=high", - &self.key, - url_encode(locale), - ); - - self.request::(path) + .execute(unique_key.clone(), || async move { + self.request::( + "/categories", + &[ + Some(("key", &self.key)), + Some(("client_key", "Gifbox")), + Some(("locale", locale)), + Some(("contentfilter", "high")), + ] + ).await }) .await .unwrap(); @@ -174,19 +173,19 @@ impl Tenor { } } - let res = self.coalescion.execute(unique_key.clone(), || { - let mut path = format!( - "/featured?key={}&client_key=Gifbox&media_filter=webm,tinywebm&locale={}&contentfilter=high&limit={limit}", - &self.key, - url_encode(locale), - ); - - if !position.is_empty() { - path.push_str("&pos="); - path.push_str(position); - }; - - self.request::(path) + let res = self.coalescion.execute(unique_key.clone(), || async move { + self.request::( + "/featured", + &[ + Some(("key", &self.key)), + Some(("client_key", "Gifbox")), + Some(("media_filter", "webm,tinywebm")), + Some(("locale", locale)), + Some(("contentfilter", "high")), + Some(("limit", &limit.to_string())), + position.is_empty().then_some(("pos", position)), + ] + ).await }) .await .unwrap(); From 6f1c715b8cb83762fe60c86af1a4b4bd3c86cfe1 Mon Sep 17 00:00:00 2001 From: izzy Date: Tue, 23 Sep 2025 12:02:35 -0500 Subject: [PATCH 015/211] chore: bump version to 0.8.9 --- Cargo.lock | 47 ++++++++++++------------------ crates/bonfire/Cargo.toml | 4 +-- crates/core/coalesced/Cargo.toml | 2 +- crates/core/config/Cargo.toml | 4 +-- crates/core/database/Cargo.toml | 14 ++++----- crates/core/files/Cargo.toml | 6 ++-- crates/core/models/Cargo.toml | 6 ++-- crates/core/parser/Cargo.toml | 2 +- crates/core/permissions/Cargo.toml | 4 +-- crates/core/presence/Cargo.toml | 4 +-- crates/core/ratelimits/Cargo.toml | 8 ++--- crates/core/result/Cargo.toml | 2 +- crates/daemons/crond/Cargo.toml | 10 +++---- crates/daemons/pushd/Cargo.toml | 12 ++++---- crates/delta/Cargo.toml | 2 +- crates/services/autumn/Cargo.toml | 12 ++++---- crates/services/gifbox/Cargo.toml | 14 ++++----- crates/services/january/Cargo.toml | 10 +++---- default.nix | 1 + 19 files changed, 78 insertions(+), 86 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 01223df48..be9eef940 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4435,15 +4435,6 @@ dependencies = [ "hashbrown 0.15.5", ] -[[package]] -name = "lru" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfe949189f46fabb938b3a9a0be30fdd93fd8a09260da863399a8cf3db756ec8" -dependencies = [ - "hashbrown 0.15.5", -] - [[package]] name = "lru-cache" version = "0.1.2" @@ -6284,7 +6275,7 @@ dependencies = [ [[package]] name = "revolt-autumn" -version = "0.8.8" +version = "0.8.9" dependencies = [ "axum", "axum-macros", @@ -6322,7 +6313,7 @@ dependencies = [ [[package]] name = "revolt-bonfire" -version = "0.8.8" +version = "0.8.9" dependencies = [ "async-channel 2.5.0", "async-std", @@ -6353,16 +6344,16 @@ dependencies = [ [[package]] name = "revolt-coalesced" -version = "0.8.8" +version = "0.8.9" dependencies = [ - "indexmap 2.11.1", - "lru 0.16.1", + "indexmap 1.9.3", + "lru 0.7.8", "tokio 1.47.1", ] [[package]] name = "revolt-config" -version = "0.8.8" +version = "0.8.9" dependencies = [ "async-std", "cached", @@ -6379,7 +6370,7 @@ dependencies = [ [[package]] name = "revolt-crond" -version = "0.8.8" +version = "0.8.9" dependencies = [ "log", "revolt-config", @@ -6391,7 +6382,7 @@ dependencies = [ [[package]] name = "revolt-database" -version = "0.8.8" +version = "0.8.9" dependencies = [ "amqprs", "async-lock 2.8.0", @@ -6438,7 +6429,7 @@ dependencies = [ [[package]] name = "revolt-delta" -version = "0.8.8" +version = "0.8.9" dependencies = [ "amqprs", "async-channel 1.9.0", @@ -6486,7 +6477,7 @@ dependencies = [ [[package]] name = "revolt-files" -version = "0.8.8" +version = "0.8.9" dependencies = [ "aes-gcm", "aws-config", @@ -6509,7 +6500,7 @@ dependencies = [ [[package]] name = "revolt-gifbox" -version = "0.8.8" +version = "0.8.9" dependencies = [ "axum", "axum-extra", @@ -6531,7 +6522,7 @@ dependencies = [ [[package]] name = "revolt-january" -version = "0.8.8" +version = "0.8.9" dependencies = [ "async-recursion", "axum", @@ -6559,7 +6550,7 @@ dependencies = [ [[package]] name = "revolt-models" -version = "0.8.8" +version = "0.8.9" dependencies = [ "indexmap 1.9.3", "iso8601-timestamp", @@ -6578,14 +6569,14 @@ dependencies = [ [[package]] name = "revolt-parser" -version = "0.8.8" +version = "0.8.9" dependencies = [ "logos", ] [[package]] name = "revolt-permissions" -version = "0.8.8" +version = "0.8.9" dependencies = [ "async-std", "async-trait", @@ -6600,7 +6591,7 @@ dependencies = [ [[package]] name = "revolt-presence" -version = "0.8.8" +version = "0.8.9" dependencies = [ "async-std", "log", @@ -6612,7 +6603,7 @@ dependencies = [ [[package]] name = "revolt-pushd" -version = "0.8.8" +version = "0.8.9" dependencies = [ "amqprs", "anyhow", @@ -6640,7 +6631,7 @@ dependencies = [ [[package]] name = "revolt-ratelimits" -version = "0.8.8" +version = "0.8.9" dependencies = [ "async-trait", "authifier", @@ -6657,7 +6648,7 @@ dependencies = [ [[package]] name = "revolt-result" -version = "0.8.8" +version = "0.8.9" dependencies = [ "axum", "revolt_okapi", diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index c01602706..1928fb467 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-bonfire" -version = "0.8.8" +version = "0.8.9" license = "AGPL-3.0-or-later" edition = "2021" @@ -42,7 +42,7 @@ revolt-result = { path = "../core/result" } revolt-models = { path = "../core/models" } revolt-config = { path = "../core/config" } revolt-database = { path = "../core/database" } -revolt-permissions = { version = "0.8.8", path = "../core/permissions" } +revolt-permissions = { version = "0.8.9", path = "../core/permissions" } revolt-presence = { path = "../core/presence", features = ["redis-is-patched"] } # redis diff --git a/crates/core/coalesced/Cargo.toml b/crates/core/coalesced/Cargo.toml index cb23a8adb..32dad1325 100644 --- a/crates/core/coalesced/Cargo.toml +++ b/crates/core/coalesced/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-coalesced" -version = "0.8.8" +version = "0.8.9" edition = "2021" license = "MIT" authors = ["Paul Makles ", "Zomatree "] diff --git a/crates/core/config/Cargo.toml b/crates/core/config/Cargo.toml index 26cc1c25f..2a6dbb9ee 100644 --- a/crates/core/config/Cargo.toml +++ b/crates/core/config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-config" -version = "0.8.8" +version = "0.8.9" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -37,4 +37,4 @@ sentry = { version = "0.31.5", optional = true } sentry-anyhow = { version = "0.38.1", optional = true } # Core -revolt-result = { version = "0.8.8", path = "../result", optional = true } +revolt-result = { version = "0.8.9", path = "../result", optional = true } diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index 02e554118..47095e3da 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-database" -version = "0.8.8" +version = "0.8.9" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -24,19 +24,19 @@ default = ["mongodb", "async-std-runtime", "tasks"] [dependencies] # Core -revolt-config = { version = "0.8.8", path = "../config", features = [ +revolt-config = { version = "0.8.9", path = "../config", features = [ "report-macros", ] } -revolt-result = { version = "0.8.8", path = "../result" } -revolt-models = { version = "0.8.8", path = "../models", features = [ +revolt-result = { version = "0.8.9", path = "../result" } +revolt-models = { version = "0.8.9", path = "../models", features = [ "validator", ] } -revolt-presence = { version = "0.8.8", path = "../presence" } -revolt-permissions = { version = "0.8.8", path = "../permissions", features = [ +revolt-presence = { version = "0.8.9", path = "../presence" } +revolt-permissions = { version = "0.8.9", path = "../permissions", features = [ "serde", "bson", ] } -revolt-parser = { version = "0.8.8", path = "../parser" } +revolt-parser = { version = "0.8.9", path = "../parser" } # Utility log = "0.4" diff --git a/crates/core/files/Cargo.toml b/crates/core/files/Cargo.toml index 7cc219f1c..e65451922 100644 --- a/crates/core/files/Cargo.toml +++ b/crates/core/files/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-files" -version = "0.8.8" +version = "0.8.9" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -20,10 +20,10 @@ typenum = "1.17.0" aws-config = "1.5.5" aws-sdk-s3 = { version = "1.46.0", features = ["behavior-version-latest"] } -revolt-config = { version = "0.8.8", path = "../config", features = [ +revolt-config = { version = "0.8.9", path = "../config", features = [ "report-macros", ] } -revolt-result = { version = "0.8.8", path = "../result" } +revolt-result = { version = "0.8.9", path = "../result" } # image processing jxl-oxide = "0.8.1" diff --git a/crates/core/models/Cargo.toml b/crates/core/models/Cargo.toml index e232fd6cc..4821ec75b 100644 --- a/crates/core/models/Cargo.toml +++ b/crates/core/models/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-models" -version = "0.8.8" +version = "0.8.9" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -20,8 +20,8 @@ default = ["serde", "partials", "rocket"] [dependencies] # Core -revolt-config = { version = "0.8.8", path = "../config" } -revolt-permissions = { version = "0.8.8", path = "../permissions" } +revolt-config = { version = "0.8.9", path = "../config" } +revolt-permissions = { version = "0.8.9", path = "../permissions" } # Utility regex = "1.11" diff --git a/crates/core/parser/Cargo.toml b/crates/core/parser/Cargo.toml index a6e1869b7..aa6b7fc2e 100644 --- a/crates/core/parser/Cargo.toml +++ b/crates/core/parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-parser" -version = "0.8.8" +version = "0.8.9" edition = "2021" license = "MIT" authors = ["Zomatree ", "Paul Makles "] diff --git a/crates/core/permissions/Cargo.toml b/crates/core/permissions/Cargo.toml index d5ee32165..6fcc38287 100644 --- a/crates/core/permissions/Cargo.toml +++ b/crates/core/permissions/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-permissions" -version = "0.8.8" +version = "0.8.9" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -21,7 +21,7 @@ async-std = { version = "1.8.0", features = ["attributes"] } [dependencies] # Core -revolt-result = { version = "0.8.8", path = "../result" } +revolt-result = { version = "0.8.9", path = "../result" } # Utility auto_ops = "0.3.0" diff --git a/crates/core/presence/Cargo.toml b/crates/core/presence/Cargo.toml index 2e53c3e70..b2e232228 100644 --- a/crates/core/presence/Cargo.toml +++ b/crates/core/presence/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-presence" -version = "0.8.8" +version = "0.8.9" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -16,7 +16,7 @@ redis-is-patched = [] async-std = { version = "1.8.0", features = ["attributes"] } # Config for loading Redis URI -revolt-config = { version = "0.8.8", path = "../config" } +revolt-config = { version = "0.8.9", path = "../config" } [dependencies] # Utility diff --git a/crates/core/ratelimits/Cargo.toml b/crates/core/ratelimits/Cargo.toml index 05e1e362d..a41952bb9 100644 --- a/crates/core/ratelimits/Cargo.toml +++ b/crates/core/ratelimits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-ratelimits" -version = "0.8.8" +version = "0.8.9" edition = "2024" [features] @@ -10,9 +10,9 @@ axum = ["dep:axum", "revolt-database/axum-impl"] default = ["rocket", "axum"] [dependencies] -revolt-database = { version = "0.8.8", path = "../database"} -revolt-result = { version = "0.8.8", path = "../result" } -revolt-config = { version = "0.8.8", path = "../config" } +revolt-database = { version = "0.8.9", path = "../database"} +revolt-result = { version = "0.8.9", path = "../result" } +revolt-config = { version = "0.8.9", path = "../config" } rocket = { version = "0.5.1", optional = true } revolt_rocket_okapi = { version = "0.10.0", optional = true } diff --git a/crates/core/result/Cargo.toml b/crates/core/result/Cargo.toml index 3a25d206f..b8ce0c59e 100644 --- a/crates/core/result/Cargo.toml +++ b/crates/core/result/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-result" -version = "0.8.8" +version = "0.8.9" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/daemons/crond/Cargo.toml b/crates/daemons/crond/Cargo.toml index 2c55f2f76..1e070e38b 100644 --- a/crates/daemons/crond/Cargo.toml +++ b/crates/daemons/crond/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-crond" -version = "0.8.8" +version = "0.8.9" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2021" @@ -16,7 +16,7 @@ log = "0.4" tokio = { version = "1" } # Core -revolt-database = { version = "0.8.8", path = "../../core/database" } -revolt-result = { version = "0.8.8", path = "../../core/result" } -revolt-config = { version = "0.8.8", path = "../../core/config" } -revolt-files = { version = "0.8.8", path = "../../core/files" } +revolt-database = { version = "0.8.9", path = "../../core/database" } +revolt-result = { version = "0.8.9", path = "../../core/result" } +revolt-config = { version = "0.8.9", path = "../../core/config" } +revolt-files = { version = "0.8.9", path = "../../core/files" } diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index 40a280081..71fc002bf 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -1,20 +1,20 @@ [package] name = "revolt-pushd" -version = "0.8.8" +version = "0.8.9" edition = "2021" license = "AGPL-3.0-or-later" [dependencies] -revolt-result = { version = "0.8.8", path = "../../core/result" } -revolt-config = { version = "0.8.8", path = "../../core/config", features = [ +revolt-result = { version = "0.8.9", path = "../../core/result" } +revolt-config = { version = "0.8.9", path = "../../core/config", features = [ "report-macros", "anyhow" ] } -revolt-database = { version = "0.8.8", path = "../../core/database" } -revolt-models = { version = "0.8.8", path = "../../core/models", features = [ +revolt-database = { version = "0.8.9", path = "../../core/database" } +revolt-models = { version = "0.8.9", path = "../../core/models", features = [ "validator", ] } -revolt-presence = { version = "0.8.8", path = "../../core/presence", features = [ +revolt-presence = { version = "0.8.9", path = "../../core/presence", features = [ "redis-is-patched", ] } diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index 889b11672..fa4bc806f 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-delta" -version = "0.8.8" +version = "0.8.9" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2018" diff --git a/crates/services/autumn/Cargo.toml b/crates/services/autumn/Cargo.toml index 3514f501d..e15fbf0e6 100644 --- a/crates/services/autumn/Cargo.toml +++ b/crates/services/autumn/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-autumn" -version = "0.8.8" +version = "0.8.9" edition = "2021" license = "AGPL-3.0-or-later" @@ -43,16 +43,16 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # Core crates -revolt-files = { version = "0.8.8", path = "../../core/files" } -revolt-config = { version = "0.8.8", path = "../../core/config" } -revolt-database = { version = "0.8.8", path = "../../core/database", features = [ +revolt-files = { version = "0.8.9", path = "../../core/files" } +revolt-config = { version = "0.8.9", path = "../../core/config" } +revolt-database = { version = "0.8.9", path = "../../core/database", features = [ "axum-impl", ] } -revolt-result = { version = "0.8.8", path = "../../core/result", features = [ +revolt-result = { version = "0.8.9", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-ratelimits = { version = "0.8.8", path = "../../core/ratelimits", features = ["axum"] } +revolt-ratelimits = { version = "0.8.9", path = "../../core/ratelimits", features = ["axum"] } # Axum / web server tempfile = "3.12.0" diff --git a/crates/services/gifbox/Cargo.toml b/crates/services/gifbox/Cargo.toml index 3e2b41736..c611f59d9 100644 --- a/crates/services/gifbox/Cargo.toml +++ b/crates/services/gifbox/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-gifbox" -version = "0.8.8" +version = "0.8.9" edition = "2021" license = "AGPL-3.0-or-later" @@ -16,19 +16,19 @@ tokio = { version = "1.0", features = ["full"] } reqwest = { version = "0.12", features = ["json"] } # Core crates -revolt-config = { version = "0.8.8", path = "../../core/config" } -revolt-models = { version = "0.8.8", path = "../../core/models" } -revolt-result = { version = "0.8.8", path = "../../core/result", features = [ +revolt-config = { version = "0.8.9", path = "../../core/config" } +revolt-models = { version = "0.8.9", path = "../../core/models" } +revolt-result = { version = "0.8.9", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-coalesced = { version = "0.8.8", path = "../../core/coalesced", features = [ +revolt-coalesced = { version = "0.8.9", path = "../../core/coalesced", features = [ "queue", ] } -revolt-database = { version = "0.8.8", path = "../../core/database", features = [ +revolt-database = { version = "0.8.9", path = "../../core/database", features = [ "axum-impl", ] } -revolt-ratelimits = { version = "0.8.8", path = "../../core/ratelimits", features = [ +revolt-ratelimits = { version = "0.8.9", path = "../../core/ratelimits", features = [ "axum", ] } diff --git a/crates/services/january/Cargo.toml b/crates/services/january/Cargo.toml index 80b5e5228..b549882aa 100644 --- a/crates/services/january/Cargo.toml +++ b/crates/services/january/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-january" -version = "0.8.8" +version = "0.8.9" edition = "2021" license = "AGPL-3.0-or-later" @@ -32,13 +32,13 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # Core crates -revolt-config = { version = "0.8.8", path = "../../core/config" } -revolt-models = { version = "0.8.8", path = "../../core/models" } -revolt-result = { version = "0.8.8", path = "../../core/result", features = [ +revolt-config = { version = "0.8.9", path = "../../core/config" } +revolt-models = { version = "0.8.9", path = "../../core/models" } +revolt-result = { version = "0.8.9", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-files = { version = "0.8.8", path = "../../core/files" } +revolt-files = { version = "0.8.9", path = "../../core/files" } # Axum / web server axum = { version = "0.7.5" } diff --git a/default.nix b/default.nix index dad66fc2e..06d2e319c 100644 --- a/default.nix +++ b/default.nix @@ -11,6 +11,7 @@ pkgs.mkShell rec { # Cargo pkgs.cargo pkgs.cargo-nextest + pkgs.cargo-release # Rust pkgs.rustc From f0a83abcfafaf9062635bc866a17e73d4a38dd70 Mon Sep 17 00:00:00 2001 From: izzy Date: Tue, 23 Sep 2025 12:09:19 -0500 Subject: [PATCH 016/211] ci: add missing src copies for Docker build --- Dockerfile | 2 ++ Dockerfile.useCurrentArch | 2 ++ scripts/build-image-layer.sh | 7 +++++-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 524e7e0e9..9ea6ea893 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,6 +27,8 @@ COPY crates/core/parser/Cargo.toml ./crates/core/parser/ COPY crates/core/permissions/Cargo.toml ./crates/core/permissions/ COPY crates/core/presence/Cargo.toml ./crates/core/presence/ COPY crates/core/result/Cargo.toml ./crates/core/result/ +COPY crates/core/coalesced/Cargo.toml ./crates/core/coalesced/ +COPY crates/core/ratelimits/Cargo.toml ./crates/core/ratelimits/ COPY crates/services/autumn/Cargo.toml ./crates/services/autumn/ COPY crates/services/january/Cargo.toml ./crates/services/january/ COPY crates/daemons/crond/Cargo.toml ./crates/daemons/crond/ diff --git a/Dockerfile.useCurrentArch b/Dockerfile.useCurrentArch index f36c08081..c8a8bb147 100644 --- a/Dockerfile.useCurrentArch +++ b/Dockerfile.useCurrentArch @@ -23,6 +23,8 @@ COPY crates/core/parser/Cargo.toml ./crates/core/parser/ COPY crates/core/permissions/Cargo.toml ./crates/core/permissions/ COPY crates/core/presence/Cargo.toml ./crates/core/presence/ COPY crates/core/result/Cargo.toml ./crates/core/result/ +COPY crates/core/coalesced/Cargo.toml ./crates/core/coalesced/ +COPY crates/core/ratelimits/Cargo.toml ./crates/core/ratelimits/ COPY crates/services/autumn/Cargo.toml ./crates/services/autumn/ COPY crates/services/january/Cargo.toml ./crates/services/january/ COPY crates/daemons/crond/Cargo.toml ./crates/daemons/crond/ diff --git a/scripts/build-image-layer.sh b/scripts/build-image-layer.sh index 064cee896..613cd32d4 100644 --- a/scripts/build-image-layer.sh +++ b/scripts/build-image-layer.sh @@ -33,6 +33,7 @@ deps() { crates/core/presence/src \ crates/core/result/src \ crates/core/coalesced/src \ + crates/core/ratelimits/src \ crates/services/autumn/src \ crates/services/january/src \ crates/services/gifbox/src \ @@ -55,7 +56,8 @@ deps() { tee crates/core/permissions/src/lib.rs | tee crates/core/presence/src/lib.rs | tee crates/core/result/src/lib.rs | - tee crates/core/coalesced/src/lib.rs + tee crates/core/coalesced/src/lib.rs | + tee crates/core/ratelimits/src/lib.rs if [ -z "$TARGETARCH" ]; then cargo build -j 10 --locked --release @@ -77,7 +79,8 @@ apps() { crates/core/permissions/src/lib.rs \ crates/core/presence/src/lib.rs \ crates/core/result/src/lib.rs \ - crates/core/coalesced/src/lib .rs + crates/core/coalesced/src/lib.rs \ + crates/core/ratelimits/src/lib.rs if [ -z "$TARGETARCH" ]; then cargo build -j 10 --locked --release From 4fb99e3bd0ccc9bce35070140066edbd38a372b2 Mon Sep 17 00:00:00 2001 From: izzy Date: Tue, 23 Sep 2025 12:12:33 -0500 Subject: [PATCH 017/211] ci: also include gifbox src --- Dockerfile | 1 + Dockerfile.useCurrentArch | 1 + 2 files changed, 2 insertions(+) diff --git a/Dockerfile b/Dockerfile index 9ea6ea893..7c9a1e44b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -31,6 +31,7 @@ COPY crates/core/coalesced/Cargo.toml ./crates/core/coalesced/ COPY crates/core/ratelimits/Cargo.toml ./crates/core/ratelimits/ COPY crates/services/autumn/Cargo.toml ./crates/services/autumn/ COPY crates/services/january/Cargo.toml ./crates/services/january/ +COPY crates/services/gifbox/Cargo.toml ./crates/services/gifbox/ COPY crates/daemons/crond/Cargo.toml ./crates/daemons/crond/ COPY crates/daemons/pushd/Cargo.toml ./crates/daemons/pushd/ RUN sh /tmp/build-image-layer.sh deps diff --git a/Dockerfile.useCurrentArch b/Dockerfile.useCurrentArch index c8a8bb147..ac9a438f5 100644 --- a/Dockerfile.useCurrentArch +++ b/Dockerfile.useCurrentArch @@ -27,6 +27,7 @@ COPY crates/core/coalesced/Cargo.toml ./crates/core/coalesced/ COPY crates/core/ratelimits/Cargo.toml ./crates/core/ratelimits/ COPY crates/services/autumn/Cargo.toml ./crates/services/autumn/ COPY crates/services/january/Cargo.toml ./crates/services/january/ +COPY crates/services/gifbox/Cargo.toml ./crates/services/gifbox/ COPY crates/daemons/crond/Cargo.toml ./crates/daemons/crond/ COPY crates/daemons/pushd/Cargo.toml ./crates/daemons/pushd/ RUN sh /tmp/build-image-layer.sh deps From d65c1a1ab3bdc7e5684b03f280af77d881661a3d Mon Sep 17 00:00:00 2001 From: Zomatree Date: Sat, 11 Oct 2025 23:01:35 +0100 Subject: [PATCH 018/211] fix(ci): publish images under stoatchat and remove docker hub --- .github/workflows/docker.yaml | 42 ++++++++++++----------------------- 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index f0a79f53d..5a63353a7 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -49,13 +49,6 @@ jobs: uses: docker/setup-buildx-action@v2 # Authenticate with Docker Hub and GHCR - - name: Login to DockerHub - uses: docker/login-action@v2 - with: - registry: docker.io - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Login to Github Container Registry uses: docker/login-action@v2 with: @@ -72,14 +65,13 @@ jobs: platforms: linux/amd64,linux/arm64 tags: ghcr.io/${{ github.repository_owner }}/base:latest - # revoltchat/server + # stoatchat/api - name: Docker meta id: meta-delta uses: docker/metadata-action@v4 with: images: | - docker.io/revoltchat/server - ghcr.io/revoltchat/server + ghcr.io/stoatchat/api - name: Publish uses: docker/build-push-action@v4 with: @@ -92,14 +84,13 @@ jobs: BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest labels: ${{ steps.meta-delta.outputs.labels }} - # revoltchat/bonfire + # stoatchat/events - name: Docker meta id: meta-bonfire uses: docker/metadata-action@v4 with: images: | - docker.io/revoltchat/bonfire - ghcr.io/revoltchat/bonfire + ghcr.io/stoatchat/events - name: Publish uses: docker/build-push-action@v4 with: @@ -112,14 +103,13 @@ jobs: BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest labels: ${{ steps.meta-bonfire.outputs.labels }} - # revoltchat/autumn + # stoatchat/file-server - name: Docker meta id: meta-autumn uses: docker/metadata-action@v4 with: images: | - docker.io/revoltchat/autumn - ghcr.io/revoltchat/autumn + ghcr.io/stoatchat/file-server - name: Publish uses: docker/build-push-action@v4 with: @@ -132,14 +122,13 @@ jobs: BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest labels: ${{ steps.meta-autumn.outputs.labels }} - # revoltchat/january + # stoatchat/proxy - name: Docker meta id: meta-january uses: docker/metadata-action@v4 with: images: | - docker.io/revoltchat/january - ghcr.io/revoltchat/january + ghcr.io/stoatchat/proxy - name: Publish uses: docker/build-push-action@v4 with: @@ -152,14 +141,13 @@ jobs: BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest labels: ${{ steps.meta-january.outputs.labels }} - # revoltchat/gifbox + # stoatchat/gifbox - name: Docker meta id: meta-gifbox uses: docker/metadata-action@v4 with: images: | - docker.io/revoltchat/gifbox - ghcr.io/revoltchat/gifbox + ghcr.io/stoatchat/gifbox - name: Publish uses: docker/build-push-action@v4 with: @@ -172,14 +160,13 @@ jobs: BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest labels: ${{ steps.meta-gifbox.outputs.labels }} - # revoltchat/crond + # stoatchat/crond - name: Docker meta id: meta-crond uses: docker/metadata-action@v4 with: images: | - docker.io/revoltchat/crond - ghcr.io/revoltchat/crond + ghcr.io/stoatchat/crond - name: Publish uses: docker/build-push-action@v4 with: @@ -192,14 +179,13 @@ jobs: BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest labels: ${{ steps.meta-crond.outputs.labels }} - # revoltchat/pushd + # stoatchat/pushd - name: Docker meta id: meta-pushd uses: docker/metadata-action@v4 with: images: | - docker.io/revoltchat/pushd - ghcr.io/revoltchat/pushd + ghcr.io/stoatchat/pushd - name: Publish uses: docker/build-push-action@v4 with: From af78ac05867fd1a75638fe29059fead483bc8c74 Mon Sep 17 00:00:00 2001 From: Zomatree Date: Sat, 11 Oct 2025 23:22:41 +0100 Subject: [PATCH 019/211] chore(ci): move to stoatchat --- .github/workflows/rust.yaml | 2 +- .github/workflows/triage_issue.yml | 2 +- .github/workflows/triage_pr.yml | 2 +- crates/bonfire/Dockerfile | 2 +- crates/daemons/crond/Dockerfile | 2 +- crates/daemons/pushd/Dockerfile | 2 +- crates/delta/Dockerfile | 2 +- crates/services/autumn/Dockerfile | 2 +- crates/services/gifbox/Dockerfile | 2 +- crates/services/january/Dockerfile | 2 +- scripts/publish-debug-image.sh | 30 +++++++++++++++--------------- 11 files changed, 25 insertions(+), 25 deletions(-) diff --git a/.github/workflows/rust.yaml b/.github/workflows/rust.yaml index f0bd33894..ad6fa7add 100644 --- a/.github/workflows/rust.yaml +++ b/.github/workflows/rust.yaml @@ -73,7 +73,7 @@ jobs: if: github.event_name != 'pull_request' && github.ref_name == 'main' uses: actions/checkout@v3 with: - repository: revoltchat/api + repository: stoatchat/api path: api token: ${{ secrets.PAT }} diff --git a/.github/workflows/triage_issue.yml b/.github/workflows/triage_issue.yml index ecc69f590..b74d8bed7 100644 --- a/.github/workflows/triage_issue.yml +++ b/.github/workflows/triage_issue.yml @@ -14,7 +14,7 @@ jobs: run: | gh api graphql -f query=' query { - organization(login: "revoltchat"){ + organization(login: "stoatchat"){ projectV2(number: 3) { id fields(first:20) { diff --git a/.github/workflows/triage_pr.yml b/.github/workflows/triage_pr.yml index 3010d2e5e..64523ffe9 100644 --- a/.github/workflows/triage_pr.yml +++ b/.github/workflows/triage_pr.yml @@ -14,7 +14,7 @@ jobs: run: | gh api graphql -f query=' query { - organization(login: "revoltchat"){ + organization(login: "stoatchat"){ projectV2(number: 5) { id fields(first:20) { diff --git a/crates/bonfire/Dockerfile b/crates/bonfire/Dockerfile index d1829137b..9a608d930 100644 --- a/crates/bonfire/Dockerfile +++ b/crates/bonfire/Dockerfile @@ -1,5 +1,5 @@ # Build Stage -FROM ghcr.io/revoltchat/base:latest AS builder +FROM ghcr.io/stoatchat/base:latest AS builder FROM debian:12 AS debian # Bundle Stage diff --git a/crates/daemons/crond/Dockerfile b/crates/daemons/crond/Dockerfile index 8a4c915a9..c1bdf80f5 100644 --- a/crates/daemons/crond/Dockerfile +++ b/crates/daemons/crond/Dockerfile @@ -1,5 +1,5 @@ # Build Stage -FROM ghcr.io/revoltchat/base:latest AS builder +FROM ghcr.io/stoatchat/base:latest AS builder FROM debian:12 AS debian # Bundle Stage diff --git a/crates/daemons/pushd/Dockerfile b/crates/daemons/pushd/Dockerfile index 8123002a0..38bfbc0ee 100644 --- a/crates/daemons/pushd/Dockerfile +++ b/crates/daemons/pushd/Dockerfile @@ -1,5 +1,5 @@ # Build Stage -FROM ghcr.io/revoltchat/base:latest AS builder +FROM ghcr.io/stoatchat/base:latest AS builder FROM debian:12 AS debian # Bundle Stage diff --git a/crates/delta/Dockerfile b/crates/delta/Dockerfile index 79d41cf27..7537ec510 100644 --- a/crates/delta/Dockerfile +++ b/crates/delta/Dockerfile @@ -1,5 +1,5 @@ # Build Stage -FROM ghcr.io/revoltchat/base:latest AS builder +FROM ghcr.io/stoatchat/base:latest AS builder FROM debian:12 AS debian # Bundle Stage diff --git a/crates/services/autumn/Dockerfile b/crates/services/autumn/Dockerfile index 40548e2c1..7d139122e 100644 --- a/crates/services/autumn/Dockerfile +++ b/crates/services/autumn/Dockerfile @@ -1,5 +1,5 @@ # Build Stage -FROM ghcr.io/revoltchat/base:latest AS builder +FROM ghcr.io/stoatchat/base:latest AS builder FROM debian:12 AS debian # Bundle Stage diff --git a/crates/services/gifbox/Dockerfile b/crates/services/gifbox/Dockerfile index 196409b70..a6af49ee6 100644 --- a/crates/services/gifbox/Dockerfile +++ b/crates/services/gifbox/Dockerfile @@ -1,5 +1,5 @@ # Build Stage -FROM ghcr.io/revoltchat/base:latest AS builder +FROM ghcr.io/stoatchat/base:latest AS builder # Bundle Stage FROM gcr.io/distroless/cc-debian12:nonroot diff --git a/crates/services/january/Dockerfile b/crates/services/january/Dockerfile index 0848291a9..f1a0fc3cd 100644 --- a/crates/services/january/Dockerfile +++ b/crates/services/january/Dockerfile @@ -1,5 +1,5 @@ # Build Stage -FROM ghcr.io/revoltchat/base:latest AS builder +FROM ghcr.io/stoatchat/base:latest AS builder FROM debian:12 AS debian # Bundle Stage diff --git a/scripts/publish-debug-image.sh b/scripts/publish-debug-image.sh index cc67d9fdc..1b07c8926 100755 --- a/scripts/publish-debug-image.sh +++ b/scripts/publish-debug-image.sh @@ -20,23 +20,23 @@ fi TAG=$1-debug echo "Building images, will tag for ghcr.io with $TAG!" -docker build -t ghcr.io/revoltchat/base:latest -f Dockerfile.useCurrentArch . -docker build -t ghcr.io/revoltchat/server:$TAG - < crates/delta/Dockerfile -docker build -t ghcr.io/revoltchat/bonfire:$TAG - < crates/bonfire/Dockerfile -docker build -t ghcr.io/revoltchat/autumn:$TAG - < crates/services/autumn/Dockerfile -docker build -t ghcr.io/revoltchat/january:$TAG - < crates/services/january/Dockerfile -docker build -t ghcr.io/revoltchat/gifbox:$TAG - < crates/services/gifbox/Dockerfile -docker build -t ghcr.io/revoltchat/crond:$TAG - < crates/daemons/crond/Dockerfile -docker build -t ghcr.io/revoltchat/pushd:$TAG - < crates/daemons/pushd/Dockerfile +docker build -t ghcr.io/stoatchat/base:latest -f Dockerfile.useCurrentArch . +docker build -t ghcr.io/stoatchat/server:$TAG - < crates/delta/Dockerfile +docker build -t ghcr.io/stoatchat/bonfire:$TAG - < crates/bonfire/Dockerfile +docker build -t ghcr.io/stoatchat/autumn:$TAG - < crates/services/autumn/Dockerfile +docker build -t ghcr.io/stoatchat/january:$TAG - < crates/services/january/Dockerfile +docker build -t ghcr.io/stoatchat/gifbox:$TAG - < crates/services/gifbox/Dockerfile +docker build -t ghcr.io/stoatchat/crond:$TAG - < crates/daemons/crond/Dockerfile +docker build -t ghcr.io/stoatchat/pushd:$TAG - < crates/daemons/pushd/Dockerfile if [ "$DEBUG" = "true" ]; then git restore Cargo.toml fi -docker push ghcr.io/revoltchat/server:$TAG -docker push ghcr.io/revoltchat/bonfire:$TAG -docker push ghcr.io/revoltchat/autumn:$TAG -docker push ghcr.io/revoltchat/january:$TAG -docker push ghcr.io/revoltchat/gifbox:$TAG -docker push ghcr.io/revoltchat/crond:$TAG -docker push ghcr.io/revoltchat/pushd:$TAG +docker push ghcr.io/stoatchat/server:$TAG +docker push ghcr.io/stoatchat/bonfire:$TAG +docker push ghcr.io/stoatchat/autumn:$TAG +docker push ghcr.io/stoatchat/january:$TAG +docker push ghcr.io/stoatchat/gifbox:$TAG +docker push ghcr.io/stoatchat/crond:$TAG +docker push ghcr.io/stoatchat/pushd:$TAG From 657a3f08e5d652814bbf0647e089ed9ebb139bbf Mon Sep 17 00:00:00 2001 From: Aeledfyr <45501007+Aeledfyr@users.noreply.github.com> Date: Sun, 26 Oct 2025 19:10:07 -0500 Subject: [PATCH 020/211] fix: preserve order of replies in message (#447) Signed-off-by: Aeledfyr --- .../core/database/src/models/messages/model.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/crates/core/database/src/models/messages/model.rs b/crates/core/database/src/models/messages/model.rs index 53d380122..f9d0d1017 100644 --- a/crates/core/database/src/models/messages/model.rs +++ b/crates/core/database/src/models/messages/model.rs @@ -440,7 +440,8 @@ impl Message { } // Verify replies are valid. - let mut replies = HashSet::new(); + let mut replies = Vec::new(); + if let Some(entries) = data.replies { if entries.len() > config.features.limits.global.message_replies { return Err(create_error!(TooManyReplies { @@ -448,6 +449,8 @@ impl Message { })); } + replies.reserve(entries.len()); + for ReplyIntent { id, mention, @@ -461,7 +464,12 @@ impl Message { user_mentions.insert(message.author.to_owned()); } - replies.insert(message.id); + // This is O(n^2), but this is faster than a HashSet + // when n < 20; as long as the message_replies limit + // is reasonable, this will be fast. + if !replies.contains(&message.id) { + replies.push(message.id); + } } // If the referenced message doesn't exist and fail_if_not_exists // is set to false, send the message without the reply. @@ -534,9 +542,7 @@ impl Message { } if !replies.is_empty() { - message - .replies - .replace(replies.into_iter().collect::>()); + message.replies.replace(replies); } // Calculate final message flags From e36fc9738bac0de4f3fcbccba521f1e3754f7ae7 Mon Sep 17 00:00:00 2001 From: Zomatree Date: Thu, 6 Nov 2025 20:26:31 +0000 Subject: [PATCH 021/211] fix: prevent timing out members which have TimeoutMembers permission --- crates/core/result/src/axum.rs | 1 + crates/core/result/src/lib.rs | 1 + crates/core/result/src/rocket.rs | 1 + crates/delta/src/routes/servers/member_edit.rs | 15 +++++++++++++-- 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/crates/core/result/src/axum.rs b/crates/core/result/src/axum.rs index e4caf8183..08ad0b41b 100644 --- a/crates/core/result/src/axum.rs +++ b/crates/core/result/src/axum.rs @@ -62,6 +62,7 @@ impl IntoResponse for Error { ErrorType::NotPrivileged => StatusCode::FORBIDDEN, ErrorType::CannotGiveMissingPermissions => StatusCode::FORBIDDEN, ErrorType::NotOwner => StatusCode::FORBIDDEN, + ErrorType::IsElevated => StatusCode::FORBIDDEN, ErrorType::DatabaseError { .. } => StatusCode::INTERNAL_SERVER_ERROR, ErrorType::InternalError => StatusCode::INTERNAL_SERVER_ERROR, diff --git a/crates/core/result/src/lib.rs b/crates/core/result/src/lib.rs index 10b56d5d4..5ae2ac2a0 100644 --- a/crates/core/result/src/lib.rs +++ b/crates/core/result/src/lib.rs @@ -138,6 +138,7 @@ pub enum ErrorType { NotPrivileged, CannotGiveMissingPermissions, NotOwner, + IsElevated, // ? General errors DatabaseError { diff --git a/crates/core/result/src/rocket.rs b/crates/core/result/src/rocket.rs index 1d996a173..f450d88ba 100644 --- a/crates/core/result/src/rocket.rs +++ b/crates/core/result/src/rocket.rs @@ -69,6 +69,7 @@ impl<'r> Responder<'r, 'static> for Error { ErrorType::NotPrivileged => Status::Forbidden, ErrorType::CannotGiveMissingPermissions => Status::Forbidden, ErrorType::NotOwner => Status::Forbidden, + ErrorType::IsElevated => Status::Forbidden, ErrorType::DatabaseError { .. } => Status::InternalServerError, ErrorType::InternalError => Status::InternalServerError, diff --git a/crates/delta/src/routes/servers/member_edit.rs b/crates/delta/src/routes/servers/member_edit.rs index e33935e86..74ac5d72a 100644 --- a/crates/delta/src/routes/servers/member_edit.rs +++ b/crates/delta/src/routes/servers/member_edit.rs @@ -32,12 +32,17 @@ pub async fn edit( // Fetch server and member let mut server = server.as_server(db).await?; + let target_user = member.as_user(db).await?; let mut member = member.as_member(db, &server.id).await?; // Fetch our currrent permissions let mut query = DatabasePermissionQuery::new(db, &user).server(&server); let permissions = calculate_server_permissions(&mut query).await; + // Fetch target permissions + let mut target_query = DatabasePermissionQuery::new(db, &target_user).server(&server).member(&member); + let target_permissions = calculate_server_permissions(&mut target_query).await; + // Check permissions in server if data.nickname.is_some() || data.remove.contains(&v0::FieldsMember::Nickname) { if user.id == member.id.user { @@ -60,8 +65,14 @@ pub async fn edit( } if data.timeout.is_some() || data.remove.contains(&v0::FieldsMember::Timeout) { - if data.timeout.is_some() && member.id.user == user.id { - return Err(create_error!(CannotTimeoutYourself)); + if data.timeout.is_some() { + if member.id.user == user.id { + return Err(create_error!(CannotTimeoutYourself)); + } + + if target_permissions.has_channel_permission(ChannelPermission::TimeoutMembers) { + return Err(create_error!(IsElevated)) + } } permissions.throw_if_lacking_channel_permission(ChannelPermission::TimeoutMembers)?; From 5b534242c4f4246804fe9758240670b2dc741282 Mon Sep 17 00:00:00 2001 From: Zomatree Date: Sat, 8 Nov 2025 01:21:24 +0000 Subject: [PATCH 022/211] chore: update ci --- .github/workflows/rust.yaml | 2 +- doc/book.toml | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/rust.yaml b/.github/workflows/rust.yaml index ad6fa7add..a77cf676e 100644 --- a/.github/workflows/rust.yaml +++ b/.github/workflows/rust.yaml @@ -73,7 +73,7 @@ jobs: if: github.event_name != 'pull_request' && github.ref_name == 'main' uses: actions/checkout@v3 with: - repository: stoatchat/api + repository: stoatchat/javascript-client-api path: api token: ${{ secrets.PAT }} diff --git a/doc/book.toml b/doc/book.toml index 5ef489b50..830614c78 100644 --- a/doc/book.toml +++ b/doc/book.toml @@ -1,6 +1,5 @@ [book] authors = [] language = "en" -multilingual = false src = "src" title = "Revolt Backend" From 27ea7345eaf498cde4db6c99a4ffcc495f2c1e0a Mon Sep 17 00:00:00 2001 From: izzy Date: Tue, 11 Nov 2025 20:07:18 +0000 Subject: [PATCH 023/211] ci: update api token; add validate PR title --- .github/workflows/rust.yaml | 4 +- .github/workflows/triage_issue.yml | 54 ----------------- .github/workflows/triage_pr.yml | 79 ------------------------- .github/workflows/validate-pr-title.yml | 20 +++++++ STYLE_GUIDE.md | 73 ----------------------- 5 files changed, 22 insertions(+), 208 deletions(-) delete mode 100644 .github/workflows/triage_issue.yml delete mode 100644 .github/workflows/triage_pr.yml create mode 100644 .github/workflows/validate-pr-title.yml delete mode 100644 STYLE_GUIDE.md diff --git a/.github/workflows/rust.yaml b/.github/workflows/rust.yaml index a77cf676e..503ec3710 100644 --- a/.github/workflows/rust.yaml +++ b/.github/workflows/rust.yaml @@ -32,7 +32,7 @@ jobs: uses: baptiste0928/cargo-install@v1 with: crate: cargo-nextest - locked: true + args: --locked - name: Run cargo build uses: actions-rs/cargo@v1 @@ -75,7 +75,7 @@ jobs: with: repository: stoatchat/javascript-client-api path: api - token: ${{ secrets.PAT }} + ssh-key: ${{ secrets.DEPLOY_KEY_JAVASCRIPT_CLIENT_API }} - name: Download OpenAPI specification if: github.event_name != 'pull_request' && github.ref_name == 'main' diff --git a/.github/workflows/triage_issue.yml b/.github/workflows/triage_issue.yml deleted file mode 100644 index b74d8bed7..000000000 --- a/.github/workflows/triage_issue.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: Add Issue to Board - -on: - issues: - types: [opened] - -jobs: - track_issue: - runs-on: ubuntu-latest - steps: - - name: Get project data - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - run: | - gh api graphql -f query=' - query { - organization(login: "stoatchat"){ - projectV2(number: 3) { - id - fields(first:20) { - nodes { - ... on ProjectV2SingleSelectField { - id - name - options { - id - name - } - } - } - } - } - } - }' > project_data.json - - echo 'PROJECT_ID='$(jq '.data.organization.projectV2.id' project_data.json) >> $GITHUB_ENV - echo 'STATUS_FIELD_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Status") | .id' project_data.json) >> $GITHUB_ENV - echo 'TODO_OPTION_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Status") | .options[] | select(.name=="Todo") |.id' project_data.json) >> $GITHUB_ENV - - - name: Add issue to project - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - ISSUE_ID: ${{ github.event.issue.node_id }} - run: | - item_id="$( gh api graphql -f query=' - mutation($project:ID!, $issue:ID!) { - addProjectV2ItemById(input: {projectId: $project, contentId: $issue}) { - item { - id - } - } - }' -f project=$PROJECT_ID -f issue=$ISSUE_ID --jq '.data.addProjectV2ItemById.item.id')" - - echo 'ITEM_ID='$item_id >> $GITHUB_ENV diff --git a/.github/workflows/triage_pr.yml b/.github/workflows/triage_pr.yml deleted file mode 100644 index 64523ffe9..000000000 --- a/.github/workflows/triage_pr.yml +++ /dev/null @@ -1,79 +0,0 @@ -name: Add PR to Board - -on: - pull_request_target: - types: [opened, synchronize, ready_for_review, review_requested] - -jobs: - track_pr: - runs-on: ubuntu-latest - steps: - - name: Get project data - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - run: | - gh api graphql -f query=' - query { - organization(login: "stoatchat"){ - projectV2(number: 5) { - id - fields(first:20) { - nodes { - ... on ProjectV2SingleSelectField { - id - name - options { - id - name - } - } - } - } - } - } - }' > project_data.json - - echo 'PROJECT_ID='$(jq '.data.organization.projectV2.id' project_data.json) >> $GITHUB_ENV - echo 'STATUS_FIELD_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Status") | .id' project_data.json) >> $GITHUB_ENV - echo 'INCOMING_OPTION_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Status") | .options[] | select(.name=="🆕 Untriaged") |.id' project_data.json) >> $GITHUB_ENV - - - name: Add PR to project - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - PR_ID: ${{ github.event.pull_request.node_id }} - run: | - item_id="$( gh api graphql -f query=' - mutation($project:ID!, $pr:ID!) { - addProjectV2ItemById(input: {projectId: $project, contentId: $pr}) { - item { - id - } - } - }' -f project=$PROJECT_ID -f pr=$PR_ID --jq '.data.addProjectV2ItemById.item.id')" - - echo 'ITEM_ID='$item_id >> $GITHUB_ENV - - - name: Set fields - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - run: | - gh api graphql -f query=' - mutation ( - $project: ID! - $item: ID! - $status_field: ID! - $status_value: String! - ) { - set_status: updateProjectV2ItemFieldValue(input: { - projectId: $project - itemId: $item - fieldId: $status_field - value: { - singleSelectOptionId: $status_value - } - }) { - projectV2Item { - id - } - } - }' -f project=$PROJECT_ID -f item=$ITEM_ID -f status_field=$STATUS_FIELD_ID -f status_value=${{ env.INCOMING_OPTION_ID }} --silent diff --git a/.github/workflows/validate-pr-title.yml b/.github/workflows/validate-pr-title.yml new file mode 100644 index 000000000..b72cc236a --- /dev/null +++ b/.github/workflows/validate-pr-title.yml @@ -0,0 +1,20 @@ +name: "Lint PR" + +on: + pull_request_target: + types: + - opened + - reopened + - edited + - synchronize + +jobs: + main: + name: Validate PR title + runs-on: ubuntu-latest + permissions: + pull-requests: read + steps: + - uses: amannn/action-semantic-pull-request@v6 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/STYLE_GUIDE.md b/STYLE_GUIDE.md deleted file mode 100644 index 7999b388a..000000000 --- a/STYLE_GUIDE.md +++ /dev/null @@ -1,73 +0,0 @@ -# Code Style Guide - -Beyond using Cargo format and Clippy, there are some specific code style guidelines laid out in this document for different parts of the project. - -## Writing Style - -- Shorten "identifier" to "Id" with that exact casing, i.e. Server Id. - -## `core/database` crate - -w.r.t. `model.rs` files - -- All struct definitions must be commented. - ```rust - /// Server - pub struct Server { - /// Name of the server - pub name: String, - ``` -- Struct definitions should not include derives unless necessary (if additional traits such as Hash are required) and instead use `auto_derived!` and `auto_derived_partial!`. - ```rust - auto_derived_partial!( - /// Server - pub struct Server { .. }, - "PartialServer" - ); - ``` -- `auto_derived!` macro accepts multiple entries and should be used as such: - - ```rust - auto_derived!( - /// Optional fields on server object - pub enum FieldsServer { .. } - - /// Optional fields on server object - pub enum FieldsRole { .. } - ); - ``` - -- If special serialisation conditions are required, such as checking if a boolean is false, use the existing definitions for these functions from the crate root: - ```rust - #[serde(skip_serializing_if = "crate::if_false", default)] - ``` -- `impl` blocks may be defined below the struct definitions and should be ordered in the same order of definition. Methods in the block must follow the same guidelines as traits where-in: methods are ordered in terms of CRUD, there are empty line breaks, and methods are commented. - -w.r.t. `ops` module for models - -- All traits must use a the name format `AbstractPlural` where Plural is the plural form of the collection. e.g. Servers -- Traits defined must follow these guidelines: - - - Methods are ordered in terms of CRUD, create-read-update-delete ordering. - - ```rust - #[async_trait] - pub trait AbstractServerMembers: Sync + Send { - /// Insert a new server member into the database - async fn insert_member(&self, member: &Member) -> Result<()>; - - /// Fetch a server member by their id - async fn fetch_member(&self, server_id: &str, user_id: &str) -> Result; - - /// Update information for a server member - async fn update_member(&self, .. ) -> Result<()>; - - /// Delete a server member by their id - async fn delete_member(&self, id: &MemberCompositeKey) -> Result<()>; - } - ``` - - - There should be an empty line break between each method declaration. - - All methods must have an appropriate comment. - -- When implementing the trait defined in `ops.rs` with each driver, the method declaration style should be the same for ease of searching: same ordering, same comments, same line breaks. From d567155f124e4da74115b1a8f810062f7c6559d9 Mon Sep 17 00:00:00 2001 From: Angelo Kontaxis Date: Wed, 12 Nov 2025 21:27:04 +0000 Subject: [PATCH 024/211] feat: voice chats v2 (#414) * initial livekit support fix up code undo changes to compose file add back .env.example * move voice states to global * track current state * more stuff * fix redis key inconsistancy * split voice ops into its own library * feat(livekit): more permission handling * feat(livekit): push unfinished code * fix: include voice states in servercreate event feat: call started system message in dms * feat: implement missing permission syncs * fix: remove locked rocket version * fix: remove local testing values from config * chore: switch to ids for parameter * feat: make Channel::server return a reference * feat: support multiple voice nodes * fix: expose list of nodes * fix: respond with the url when joining a voice channel * feat: being moved between voice channels * fix: use existing node if someone is already in the voice channel * refactor: Remove VoiceChannel * chore: add pushd to debug image script * refactor: add error messages for Rabbit issues * docs: add some notes on overrides; fix defaults * fix: ensure limit is always at least 1 when sent to database * fix: change permission check for fetching channel webhooks * chore: mount API at /0.8/ as well * fix: ensure ratelimiter adjusts for version prefix * chore: bump version to 0.8.2 * chore: disable LTO because it likely overloads GitHub worker * fix: don't allow users to time themselves out closes #376 * fix: match new error type for status code * feat: init crond crate * feat: file deletion implementation * chore: fix version references * feat: add crond container definitions * chore: clarify cargo deny / tomls * feat: add company information to email footers * chore: bump version to 0.8.3 * fix: don't bump the lockfile version * fix: include `production` default value for config * chore: ignore python venv and dev script for user generation Signed-off-by: IAmTomahawkx * test: Add tests for invite/fetch Signed-off-by: phazeschift <51278042+phazeschift@users.noreply.github.com> * test: add utilities for common setup Signed-off-by: phazeschift <51278042+phazeschift@users.noreply.github.com> * test: add delete server channel test Signed-off-by: phazeschift <51278042+phazeschift@users.noreply.github.com> * feat: allow to set an icon when creating a group Signed-off-by: Nils Ponsard * fix: allow message pinning and unpinning for DM-like channels Signed-off-by: Bradlee Barnes <69256931+StupidRepo@users.noreply.github.com> * fix: remove SavedMessages and Group due to given permissions Signed-off-by: Bradlee Barnes <69256931+StupidRepo@users.noreply.github.com> * feat: allow bots to manage emojis (#407) * Remove bot check on emoji create Signed-off-by: Builderb * Remove bot check on emoji delete Signed-off-by: Builderb --------- Signed-off-by: Builderb * feat: add option to send message with missing replies Signed-off-by: ShaksterNano <54268387+shaksternano@users.noreply.github.com> * chore: bump version to 0.8.4 chore: enable webhooks in test builds * ci: downgrade lockfile * feat: Add Mass Mentions to the backend (#394) * feat: create base of push daemon Signed-off-by: IAmTomahawkx * Add outbound senders * Make web_push send to rabbit instead (temp stuff) * feat: stability and friend requests * make vapid fr stuff not suck * swap naming of queue * move pushd into daemons folder * fix cargo file for move into daemons folder * feat: probably working fcm push notifs * comment out fcm webpush stuff since the config keys dont exist * fix fcm, name queues according to their prod status and configure routing keys * add pushd to docker * mix: Remove old code, add stuff to pushd * fix: lockfile * feat: update rocket to 5.0.1 * fix: fix queues and ack bugs * Move rabbit messsage processing into ack queue * chore: update readme * chore: optimizations for ack database hits * pushd flowchart * misc: update flowchart * exit dependancy hell * add rocket_impl flag to authifier * make the tests file of delta actually compile * fix: don't silence every push message * fix: don't silence all messages * add debug logging for sending data to rabbit from message events * validate mentions at a server membership level * put back that import that was actually important * minor fix to lockfile * update delta authifier * feat: proper permissions for push notifications * add unit test for mention sanitization * remove local file dependancy on authifier * update ports to proper defaults * fixTM the node bindings * Theoretically configure docker releases for pushd Signed-off-by: IAmTomahawkx * declare exchange in pushd and delta * fix createbuckets script Signed-off-by: IAmTomahawkx * fix: reference db implementation Signed-off-by: IAmTomahawkx * fix: remove finally redundant code Signed-off-by: IAmTomahawkx * fix: changes Signed-off-by: IAmTomahawkx * fix: other changes Signed-off-by: IAmTomahawkx * fix: make channel name return result Signed-off-by: IAmTomahawkx * Add role mention parsing * feat: update to mongo 3.1, add member generator. * integrate mass mentions into pushd * patch redis-rs with updated versions * feat: chunk role mentions * move permission bits to 37/38 to avoid livekit conflict * change role mention format to <%id> * fix the lockfile from merge * fix: PR change requests * feat: add tests * fix: i am a dumbass * fix: tests, again --------- Signed-off-by: IAmTomahawkx * fix: show full branch name on github webhook messages * fix: dont leak invisible presence to others * fix: add back missing early adopter badge * fix: update branch from main * fix: update branch from main * Merge remote-tracking branch 'origin/main' into livekit * feat: private livekit nodes * fix: remove node from channel voice state * fix: get_voice_state has incorrect unique_key and allowed_sources should be lowercase * chore: bump livekit dep * feat: ability to force disconnect existing voice connection * chore: cleanup code * feat: - track call length - move voice and video limits to config - seperate VoiceInformation into model and db model - fix build scripts * fix: move call system message to daemon, check max participants when creating a token to avoid giving tokens but erroring when attempting to join, check if the channel actually supports voice * fix: dont set max participants in livekit * fix: remove VoiceChannel channel type fix: calculate user overwrites correctly fix: dont include personal info in livekit user metadata fix: revoke video permissons on denied publish fix: add video to default permissions * fix: update migration * feat: Send push notifications for dm call start/end * chore: cleanup * feat: allow users to specify who is notified when starting a call * feat: track join time * merge: branch 'main' into feat/livekit * fix: include voice-ingress in build * fix: dont presume channel has a node * chore: add error logging to internal errors * chore: add debug logging to voice ingress * refactor: seperate out disconnect logic * fix: return correct error if user is already in a voice channel * fix: dont break on user not still being in channel and force disconnecting * fix: add Speak and Listen to default permissions * fix: include channel ids in UserMoveVoiceChannel * chore: add temp sentry logging system * fix: handle track_muted and track_unmuted * fix: dont set notification recipients when empty vec is passed * fix: only send UserMoveVoiceChannel to the user * fix: preserve order of replies in message (#447) Signed-off-by: Aeledfyr * fix: prevent timing out members which have TimeoutMembers permission * chore: update ci * fix: temporarily disable call started system messages See #457 * fix: update code from review --- .github/workflows/docker.yaml | 19 + .gitignore | 1 + Cargo.lock | 452 ++++++++++--- Dockerfile | 1 + Dockerfile.useCurrentArch | 1 + Revolt.toml | 17 + compose.yml | 9 +- crates/bonfire/Cargo.toml | 2 +- crates/bonfire/src/config.rs | 2 + crates/bonfire/src/events/impl.rs | 86 ++- crates/core/config/Revolt.toml | 35 +- crates/core/config/src/lib.rs | 33 +- crates/core/database/Cargo.toml | 6 + crates/core/database/src/amqp/amqp.rs | 78 ++- crates/core/database/src/drivers/mod.rs | 2 +- crates/core/database/src/drivers/mongodb.rs | 1 + crates/core/database/src/drivers/reference.rs | 2 +- crates/core/database/src/events/client.rs | 37 +- crates/core/database/src/events/rabbit.rs | 15 + crates/core/database/src/lib.rs | 4 + .../admin_migrations/ops/mongodb/scripts.rs | 66 +- .../src/models/channel_invites/model.rs | 2 +- .../database/src/models/channels/model.rs | 118 ++-- .../src/models/channels/ops/mongodb.rs | 2 +- .../src/models/channels/ops/reference.rs | 3 - .../database/src/models/messages/model.rs | 19 +- .../src/models/server_members/model.rs | 37 +- .../src/models/server_members/ops/mongodb.rs | 2 + crates/core/database/src/tasks/ack.rs | 19 +- crates/core/database/src/util/bridge/v0.rs | 77 +-- .../database/src/util/bulk_permissions.rs | 19 +- crates/core/database/src/util/funcs.rs | 24 + crates/core/database/src/util/mod.rs | 3 + crates/core/database/src/util/permissions.rs | 40 +- crates/core/database/src/voice/mod.rs | 598 ++++++++++++++++++ .../core/database/src/voice/voice_client.rs | 156 +++++ crates/core/models/src/v0/channels.rs | 96 +-- crates/core/models/src/v0/messages.rs | 3 + crates/core/models/src/v0/server_members.rs | 23 + crates/core/models/src/v0/users.rs | 14 + crates/core/permissions/src/impl.rs | 9 + crates/core/permissions/src/models/channel.rs | 6 +- crates/core/permissions/src/models/server.rs | 2 +- crates/core/permissions/src/test.rs | 32 + crates/core/permissions/src/trait.rs | 6 + crates/core/result/Cargo.toml | 7 +- crates/core/result/src/axum.rs | 5 + crates/core/result/src/lib.rs | 62 ++ crates/core/result/src/rocket.rs | 7 +- .../pushd/src/consumers/inbound/dm_call.rs | 168 +++++ .../pushd/src/consumers/inbound/mod.rs | 1 + .../pushd/src/consumers/outbound/apn.rs | 59 +- .../pushd/src/consumers/outbound/fcm.rs | 37 +- .../pushd/src/consumers/outbound/vapid.rs | 29 +- crates/daemons/pushd/src/main.rs | 18 +- crates/daemons/voice-ingress/.gitignore | 1 + crates/daemons/voice-ingress/Cargo.toml | 48 ++ crates/daemons/voice-ingress/Dockerfile | 11 + crates/daemons/voice-ingress/src/api.rs | 274 ++++++++ crates/daemons/voice-ingress/src/guard.rs | 28 + crates/daemons/voice-ingress/src/main.rs | 37 ++ crates/delta/Cargo.toml | 5 + crates/delta/src/main.rs | 13 + crates/delta/src/routes/bots/delete.rs | 9 +- .../src/routes/channels/channel_delete.rs | 67 +- .../delta/src/routes/channels/channel_edit.rs | 188 +++--- .../routes/channels/group_remove_member.rs | 62 +- .../src/routes/channels/message_query.rs | 9 +- .../src/routes/channels/message_search.rs | 11 +- .../delta/src/routes/channels/message_send.rs | 6 + crates/delta/src/routes/channels/mod.rs | 2 + .../src/routes/channels/permissions_set.rs | 18 +- .../channels/permissions_set_default.rs | 17 +- .../delta/src/routes/channels/voice_join.rs | 168 ++--- .../src/routes/channels/voice_stop_ring.rs | 69 ++ .../delta/src/routes/invites/invite_fetch.rs | 8 +- crates/delta/src/routes/root.rs | 47 +- crates/delta/src/routes/servers/ban_create.rs | 7 + .../delta/src/routes/servers/member_edit.rs | 123 +++- .../delta/src/routes/servers/member_remove.rs | 11 +- .../src/routes/servers/permissions_set.rs | 60 +- .../routes/servers/permissions_set_default.rs | 10 +- .../delta/src/routes/servers/roles_delete.rs | 27 +- crates/delta/src/routes/servers/roles_edit.rs | 10 +- .../routes/servers/roles_edit_positions.rs | 10 +- .../delta/src/routes/servers/server_delete.rs | 18 +- crates/delta/src/util/test.rs | 1 + livekit.example.yml | 13 + rust-toolchain.toml | 2 + scripts/build-image-layer.sh | 7 +- scripts/publish-debug-image.sh | 2 + 91 files changed, 3321 insertions(+), 650 deletions(-) create mode 100644 crates/core/database/src/util/funcs.rs create mode 100644 crates/core/database/src/voice/mod.rs create mode 100644 crates/core/database/src/voice/voice_client.rs create mode 100644 crates/daemons/pushd/src/consumers/inbound/dm_call.rs create mode 100644 crates/daemons/voice-ingress/.gitignore create mode 100644 crates/daemons/voice-ingress/Cargo.toml create mode 100644 crates/daemons/voice-ingress/Dockerfile create mode 100644 crates/daemons/voice-ingress/src/api.rs create mode 100644 crates/daemons/voice-ingress/src/guard.rs create mode 100644 crates/daemons/voice-ingress/src/main.rs create mode 100644 crates/delta/src/routes/channels/voice_stop_ring.rs create mode 100644 livekit.example.yml create mode 100644 rust-toolchain.toml diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 5a63353a7..8d0d74264 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -197,3 +197,22 @@ jobs: build-args: | BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest labels: ${{ steps.meta-pushd.outputs.labels }} + + # stoatchat/voice-ingress + - name: Docker meta + id: meta-voice-ingress + uses: docker/metadata-action@v4 + with: + images: | + ghcr.io/stoatchat/voice-ingress + - name: Publish + uses: docker/build-push-action@v4 + with: + context: . + push: true + platforms: linux/amd64,linux/arm64 + file: crates/daemons/voice-ingress/Dockerfile + tags: ${{ steps.meta-voice-ingress.outputs.tags }} + build-args: | + BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest + labels: ${{ steps.meta-voice-ingress.outputs.labels }} diff --git a/.gitignore b/.gitignore index 8483bc435..ae3bfadb5 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,5 @@ venv/ .vercel .DS_Store +livekit.yml .idea \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index be9eef940..ee03bf557 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -136,9 +136,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.99" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" dependencies = [ "backtrace", ] @@ -822,11 +822,11 @@ dependencies = [ "hyper-util", "pin-project-lite 0.2.16", "rustls 0.21.12", - "rustls 0.23.31", + "rustls 0.23.32", "rustls-native-certs 0.8.1", "rustls-pki-types", "tokio 1.47.1", - "tokio-rustls 0.26.2", + "tokio-rustls 0.26.3", "tower", "tracing", ] @@ -1067,7 +1067,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11eeb275b20a4c750c9fe7bf5a750e97e7944563003efd1c82e70c229a612ca1" dependencies = [ "darling 0.20.11", - "heck", + "heck 0.5.0", "proc-macro-error", "quote 1.0.40", "syn 2.0.106", @@ -1275,7 +1275,7 @@ dependencies = [ "getrandom 0.2.16", "getrandom 0.3.3", "hex", - "indexmap 2.11.1", + "indexmap 2.11.4", "js-sys", "once_cell", "rand 0.9.2", @@ -1382,9 +1382,9 @@ checksum = "a2698f953def977c68f935bb0dfa959375ad4638570e969e2f1e9f433cbf1af6" [[package]] name = "cc" -version = "1.2.37" +version = "1.2.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65193589c6404eb80b450d618eaf9a2cafaaafd57ecce47370519ef674a7bd44" +checksum = "80f41ae168f955c12fb8960b057d70d0ca153fb83182b57d86380443527be7e9" dependencies = [ "find-msvc-tools", "jobserver", @@ -1874,6 +1874,16 @@ dependencies = [ "darling_macro 0.20.11", ] +[[package]] +name = "darling" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" +dependencies = [ + "darling_core 0.21.3", + "darling_macro 0.21.3", +] + [[package]] name = "darling_core" version = "0.13.4" @@ -1916,6 +1926,20 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "darling_core" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote 1.0.40", + "strsim 0.11.1", + "syn 2.0.106", +] + [[package]] name = "darling_macro" version = "0.13.4" @@ -1949,6 +1973,17 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "darling_macro" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +dependencies = [ + "darling_core 0.21.3", + "quote 1.0.40", + "syn 2.0.106", +] + [[package]] name = "dashmap" version = "5.5.3" @@ -2316,7 +2351,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote 1.0.40", "syn 2.0.106", @@ -2554,9 +2589,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fd99930f64d146689264c637b5af2f0233a933bef0d8570e2526bf9e083192d" +checksum = "1ced73b1dacfc750a6db6c0a0c3a3853c8b41997e2e2c563dc90804ae6867959" [[package]] name = "findshlibs" @@ -2570,6 +2605,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + [[package]] name = "flate2" version = "1.1.2" @@ -2924,7 +2965,7 @@ dependencies = [ "js-sys", "libc", "r-efi", - "wasi 0.14.5+wasi-0.2.4", + "wasi 0.14.7+wasi-0.2.4", "wasm-bindgen", ] @@ -3031,7 +3072,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.11.1", + "indexmap 2.11.4", "slab", "tokio 1.47.1", "tokio-util", @@ -3050,7 +3091,7 @@ dependencies = [ "futures-core", "futures-sink", "http 1.3.1", - "indexmap 2.11.1", + "indexmap 2.11.4", "slab", "tokio 1.47.1", "tokio-util", @@ -3117,6 +3158,12 @@ dependencies = [ "foldhash", ] +[[package]] +name = "hashbrown" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" + [[package]] name = "headers" version = "0.4.1" @@ -3141,6 +3188,12 @@ dependencies = [ "http 1.3.1", ] +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "heck" version = "0.5.0" @@ -3447,11 +3500,11 @@ dependencies = [ "http 1.3.1", "hyper 1.7.0", "hyper-util", - "rustls 0.23.31", + "rustls 0.23.32", "rustls-native-certs 0.8.1", "rustls-pki-types", "tokio 1.47.1", - "tokio-rustls 0.26.2", + "tokio-rustls 0.26.3", "tower-service", ] @@ -3486,9 +3539,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e" +checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" dependencies = [ "base64 0.22.1", "bytes 1.10.1", @@ -3759,13 +3812,14 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.11.1" +version = "2.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "206a8042aec68fa4a62e8d3f7aa4ceb508177d9324faf261e1959e495b7a1921" +checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" dependencies = [ "equivalent", - "hashbrown 0.15.5", + "hashbrown 0.16.0", "serde", + "serde_core", ] [[package]] @@ -3903,6 +3957,15 @@ dependencies = [ "time", ] +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.12.1" @@ -3939,9 +4002,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.78" +version = "0.3.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0b063578492ceec17683ef2f8c5e89121fbd0b172cbc280635ab7567db2738" +checksum = "852f13bec5eba4ba9afbeb93fd7c13fe56147f055939ae21c43a29a0ecb2702e" dependencies = [ "once_cell", "wasm-bindgen", @@ -3958,6 +4021,19 @@ dependencies = [ "serde", ] +[[package]] +name = "jsonwebtoken" +version = "9.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde" +dependencies = [ + "base64 0.22.1", + "js-sys", + "ring", + "serde", + "serde_json", +] + [[package]] name = "jwt-simple" version = "0.11.9" @@ -4318,6 +4394,68 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" +[[package]] +name = "livekit-api" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a17951fa8d398241f4a9503b57a7b38b3f40fb9dc94954f17b9fe99683e6b9b" +dependencies = [ + "base64 0.21.7", + "http 0.2.12", + "jsonwebtoken", + "livekit-protocol", + "log", + "parking_lot", + "pbjson-types", + "prost", + "rand 0.9.2", + "reqwest 0.11.27", + "scopeguard", + "serde", + "serde_json", + "sha2", + "thiserror 1.0.69", + "url", +] + +[[package]] +name = "livekit-protocol" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45c90494efa508ec40228f870affec648826d23e1a9621a4430f67d187901eb4" +dependencies = [ + "futures-util", + "livekit-runtime 0.4.0", + "parking_lot", + "pbjson", + "pbjson-types", + "prost", + "prost-types", + "serde", + "thiserror 1.0.69", + "tokio 1.47.1", +] + +[[package]] +name = "livekit-runtime" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ae53eb874eb86e96e8ccffc31b5a00926d46174cbcb1c24ce4e57b1fcc5c8f6" +dependencies = [ + "tokio 1.47.1", + "tokio-stream", +] + +[[package]] +name = "livekit-runtime" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "532e84c6cdc5fe774f2b5d9912597b5f3bea561927a48296d03e24549d21c3f6" +dependencies = [ + "tokio 1.47.1", + "tokio-stream", +] + [[package]] name = "lock_api" version = "0.4.13" @@ -4723,7 +4861,7 @@ dependencies = [ "percent-encoding", "rand 0.8.5", "rustc_version_runtime", - "rustls 0.23.31", + "rustls 0.23.32", "rustversion", "serde", "serde_bytes", @@ -4736,7 +4874,7 @@ dependencies = [ "take_mut", "thiserror 1.0.69", "tokio 1.47.1", - "tokio-rustls 0.26.2", + "tokio-rustls 0.26.3", "tokio-util", "typed-builder", "uuid", @@ -4784,6 +4922,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "multimap" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" + [[package]] name = "mutate_once" version = "0.1.2" @@ -5171,6 +5315,43 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" +[[package]] +name = "pbjson" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1030c719b0ec2a2d25a5df729d6cff1acf3cc230bf766f4f97833591f7577b90" +dependencies = [ + "base64 0.21.7", + "serde", +] + +[[package]] +name = "pbjson-build" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2580e33f2292d34be285c5bc3dba5259542b083cfad6037b6d70345f24dcb735" +dependencies = [ + "heck 0.4.1", + "itertools 0.11.0", + "prost", + "prost-types", +] + +[[package]] +name = "pbjson-types" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18f596653ba4ac51bdecbb4ef6773bc7f56042dc13927910de1684ad3d32aa12" +dependencies = [ + "bytes 1.10.1", + "chrono", + "pbjson", + "pbjson-build", + "prost", + "prost-build", + "serde", +] + [[package]] name = "pbkdf2" version = "0.11.0" @@ -5292,6 +5473,16 @@ dependencies = [ "sha2", ] +[[package]] +name = "petgraph" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" +dependencies = [ + "fixedbitset", + "indexmap 2.11.4", +] + [[package]] name = "phf" version = "0.10.1" @@ -5477,12 +5668,12 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "plist" -version = "1.7.4" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3af6b589e163c5a788fab00ce0c0366f6efbb9959c2f9874b224936af7fce7e1" +checksum = "740ebea15c5d1428f910cd1a5f52cebf8d25006245ed8ade92702f4943d91e07" dependencies = [ "base64 0.22.1", - "indexmap 2.11.1", + "indexmap 2.11.4", "quick-xml", "serde", "time", @@ -5732,11 +5923,64 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "prost" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" +dependencies = [ + "bytes 1.10.1", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" +dependencies = [ + "bytes 1.10.1", + "heck 0.5.0", + "itertools 0.12.1", + "log", + "multimap", + "once_cell", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn 2.0.106", + "tempfile", +] + +[[package]] +name = "prost-derive" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" +dependencies = [ + "anyhow", + "itertools 0.12.1", + "proc-macro2", + "quote 1.0.40", + "syn 2.0.106", +] + +[[package]] +name = "prost-types" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0" +dependencies = [ + "prost", +] + [[package]] name = "pxfm" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55f4fedc84ed39cb7a489322318976425e42a147e2be79d8f878e2884f94e84" +checksum = "83f9b339b02259ada5c0f4a389b7fb472f933aa17ce176fd2ad98f28bb401fde" dependencies = [ "num-traits", ] @@ -6346,7 +6590,7 @@ dependencies = [ name = "revolt-coalesced" version = "0.8.9" dependencies = [ - "indexmap 1.9.3", + "indexmap 2.11.4", "lru 0.7.8", "tokio 1.47.1", ] @@ -6400,6 +6644,9 @@ dependencies = [ "isahc", "iso8601-timestamp", "linkify 0.8.1", + "livekit-api", + "livekit-protocol", + "livekit-runtime 0.3.1", "log", "lru 0.11.1", "mongodb", @@ -6444,6 +6691,8 @@ dependencies = [ "iso8601-timestamp", "lettre", "linkify 0.6.0", + "livekit-api", + "livekit-protocol", "log", "lru 0.7.8", "nanoid", @@ -6651,15 +6900,45 @@ name = "revolt-result" version = "0.8.9" dependencies = [ "axum", + "log", "revolt_okapi", "revolt_rocket_okapi", "rocket", "schemars 0.8.22", + "sentry", "serde", "serde_json", "utoipa", ] +[[package]] +name = "revolt-voice-ingress" +version = "0.7.1" +dependencies = [ + "amqprs", + "async-std", + "chrono", + "futures", + "livekit-api", + "livekit-protocol", + "livekit-runtime 0.3.1", + "log", + "lru 0.7.8", + "redis-kiss", + "revolt-config", + "revolt-database", + "revolt-models", + "revolt-permissions", + "revolt-result", + "rmp-serde", + "rocket", + "rocket_empty", + "sentry", + "serde", + "serde_json", + "ulid 0.5.0", +] + [[package]] name = "revolt_a2" version = "0.10.1" @@ -6821,7 +7100,7 @@ dependencies = [ "either", "figment", "futures", - "indexmap 2.11.1", + "indexmap 2.11.4", "log", "memchr", "multer", @@ -6869,7 +7148,7 @@ checksum = "575d32d7ec1a9770108c879fc7c47815a80073f96ca07ff9525a94fcede1dd46" dependencies = [ "devise", "glob", - "indexmap 2.11.1", + "indexmap 2.11.4", "proc-macro2", "quote 1.0.40", "rocket_http", @@ -6916,7 +7195,7 @@ dependencies = [ "futures", "http 0.2.12", "hyper 0.14.32", - "indexmap 2.11.1", + "indexmap 2.11.4", "log", "memchr", "pear", @@ -7074,16 +7353,16 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.31" +version = "0.23.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" +checksum = "cd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40" dependencies = [ "aws-lc-rs", "log", "once_cell", "ring", "rustls-pki-types", - "rustls-webpki 0.103.5", + "rustls-webpki 0.103.6", "subtle", "zeroize", ] @@ -7162,9 +7441,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.5" +version = "0.103.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5a37813727b78798e53c2bec3f5e8fe12a6d6f8389bf9ca7802add4c9905ad8" +checksum = "8572f3c2cb9934231157b45499fc41e1f58c589fdfb81a844ba873265e80f8eb" dependencies = [ "aws-lc-rs", "ring", @@ -7564,9 +7843,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.223" +version = "1.0.225" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a505d71960adde88e293da5cb5eda57093379f64e61cf77bf0e6a63af07a7bac" +checksum = "fd6c24dee235d0da097043389623fb913daddf92c76e9f5a1db88607a0bcbd1d" dependencies = [ "serde_core", "serde_derive", @@ -7574,9 +7853,9 @@ dependencies = [ [[package]] name = "serde_bytes" -version = "0.11.18" +version = "0.11.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe07b5d88710e3b807c16a06ccbc9dfecd5fff6a4d2745c59e3e26774f10de6a" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" dependencies = [ "serde", "serde_core", @@ -7593,18 +7872,18 @@ dependencies = [ [[package]] name = "serde_core" -version = "1.0.223" +version = "1.0.225" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20f57cbd357666aa7b3ac84a90b4ea328f1d4ddb6772b430caa5d9e1309bb9e9" +checksum = "659356f9a0cb1e529b24c01e43ad2bdf520ec4ceaf83047b83ddcc2251f96383" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.223" +version = "1.0.225" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d428d07faf17e306e699ec1e91996e5a165ba5d6bce5b5155173e91a8a01a56" +checksum = "0ea936adf78b1f766949a4977b91d2f5595825bd6ec079aa9543ad2685fc4516" dependencies = [ "proc-macro2", "quote 1.0.40", @@ -7628,7 +7907,7 @@ version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ - "indexmap 2.11.1", + "indexmap 2.11.4", "itoa", "memchr", "ryu", @@ -7638,9 +7917,9 @@ dependencies = [ [[package]] name = "serde_path_to_error" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a30a8abed938137c7183c173848e3c9b3517f5e038226849a4ecc9b21a4b4e2a" +checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" dependencies = [ "itoa", "serde", @@ -7670,15 +7949,15 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.14.0" +version = "3.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2c45cd61fefa9db6f254525d46e392b852e0e61d9a1fd36e5bd183450a556d5" +checksum = "c522100790450cf78eeac1507263d0a350d4d5b30df0c8e1fe051a10c22b376e" dependencies = [ "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.11.1", + "indexmap 2.11.4", "schemars 0.9.0", "schemars 1.0.4", "serde", @@ -7690,11 +7969,11 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.14.0" +version = "3.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de90945e6565ce0d9a25098082ed4ee4002e047cb59892c318d66821e14bb30f" +checksum = "327ada00f7d64abaac1e55a6911e90cf665aa051b9a561c7006c157f4633135e" dependencies = [ - "darling 0.20.11", + "darling 0.21.3", "proc-macro2", "quote 1.0.40", "syn 2.0.106", @@ -8009,7 +8288,7 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote 1.0.40", "rustversion", @@ -8175,7 +8454,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" dependencies = [ "cfg-expr", - "heck", + "heck 0.5.0", "pkg-config", "toml 0.8.23", "version-compare", @@ -8303,11 +8582,12 @@ dependencies = [ [[package]] name = "time" -version = "0.3.43" +version = "0.3.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83bde6f1ec10e72d583d91623c939f623002284ef622b87de38cfd546cbf2031" +checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" dependencies = [ "deranged", + "itoa", "libc", "num-conv", "num_threads", @@ -8468,11 +8748,11 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.2" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +checksum = "05f63835928ca123f1bef57abbcd23bb2ba0ac9ae1235f1e65bda0d06e7786bd" dependencies = [ - "rustls 0.23.31", + "rustls 0.23.32", "tokio 1.47.1", ] @@ -8537,7 +8817,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.11.1", + "indexmap 2.11.4", "toml_datetime", "winnow 0.5.40", ] @@ -8548,7 +8828,7 @@ version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 2.11.1", + "indexmap 2.11.4", "serde", "serde_spanned", "toml_datetime", @@ -9026,7 +9306,7 @@ version = "4.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5afb1a60e207dca502682537fefcfd9921e71d0b83e9576060f09abc6efab23" dependencies = [ - "indexmap 2.11.1", + "indexmap 2.11.4", "serde", "serde_json", "utoipa-gen", @@ -9215,18 +9495,18 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasi" -version = "0.14.5+wasi-0.2.4" +version = "0.14.7+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4494f6290a82f5fe584817a676a34b9d6763e8d9d18204009fb31dceca98fd4" +checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" dependencies = [ "wasip2", ] [[package]] name = "wasip2" -version = "1.0.0+wasi-0.2.4" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03fa2761397e5bd52002cd7e73110c71af2109aca4e521a9f40473fe685b0a24" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ "wit-bindgen", ] @@ -9242,9 +9522,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.101" +version = "0.2.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e14915cadd45b529bb8d1f343c4ed0ac1de926144b746e2710f9cd05df6603b" +checksum = "ab10a69fbd0a177f5f649ad4d8d3305499c42bab9aef2f7ff592d0ec8f833819" dependencies = [ "cfg-if", "once_cell", @@ -9255,9 +9535,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.101" +version = "0.2.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28d1ba982ca7923fd01448d5c30c6864d0a14109560296a162f80f305fb93bb" +checksum = "0bb702423545a6007bbc368fde243ba47ca275e549c8a28617f56f6ba53b1d1c" dependencies = [ "bumpalo", "log", @@ -9269,9 +9549,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.51" +version = "0.4.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca85039a9b469b38336411d6d6ced91f3fc87109a2a27b0c197663f5144dffe" +checksum = "a0b221ff421256839509adbb55998214a70d829d3a28c69b4a6672e9d2a42f67" dependencies = [ "cfg-if", "js-sys", @@ -9282,9 +9562,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.101" +version = "0.2.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c3d463ae3eff775b0c45df9da45d68837702ac35af998361e2c84e7c5ec1b0d" +checksum = "fc65f4f411d91494355917b605e1480033152658d71f722a90647f56a70c88a0" dependencies = [ "quote 1.0.40", "wasm-bindgen-macro-support", @@ -9292,9 +9572,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.101" +version = "0.2.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bb4ce89b08211f923caf51d527662b75bdc9c9c7aab40f86dcb9fb85ac552aa" +checksum = "ffc003a991398a8ee604a401e194b6b3a39677b3173d6e74495eb51b82e99a32" dependencies = [ "proc-macro2", "quote 1.0.40", @@ -9305,9 +9585,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.101" +version = "0.2.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f143854a3b13752c6950862c906306adb27c7e839f7414cec8fea35beab624c1" +checksum = "293c37f4efa430ca14db3721dfbe48d8c33308096bd44d80ebaa775ab71ba1cf" dependencies = [ "unicode-ident", ] @@ -9336,9 +9616,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.78" +version = "0.3.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77e4b637749ff0d92b8fad63aa1f7cff3cbe125fd49c175cd6345e7272638b12" +checksum = "fbe734895e869dc429d78c4b433f8d17d95f8d05317440b4fad5ab2d33e596dc" dependencies = [ "js-sys", "wasm-bindgen", @@ -9845,9 +10125,9 @@ dependencies = [ [[package]] name = "wit-bindgen" -version = "0.45.1" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c573471f125075647d03df72e026074b7203790d41351cd6edc96f46bcccd36" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "writeable" diff --git a/Dockerfile b/Dockerfile index 7c9a1e44b..86011e56f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -34,6 +34,7 @@ COPY crates/services/january/Cargo.toml ./crates/services/january/ COPY crates/services/gifbox/Cargo.toml ./crates/services/gifbox/ COPY crates/daemons/crond/Cargo.toml ./crates/daemons/crond/ COPY crates/daemons/pushd/Cargo.toml ./crates/daemons/pushd/ +COPY crates/daemons/voice-ingress/Cargo.toml ./crates/daemons/voice-ingress/ RUN sh /tmp/build-image-layer.sh deps # Build all apps diff --git a/Dockerfile.useCurrentArch b/Dockerfile.useCurrentArch index ac9a438f5..829296902 100644 --- a/Dockerfile.useCurrentArch +++ b/Dockerfile.useCurrentArch @@ -30,6 +30,7 @@ COPY crates/services/january/Cargo.toml ./crates/services/january/ COPY crates/services/gifbox/Cargo.toml ./crates/services/gifbox/ COPY crates/daemons/crond/Cargo.toml ./crates/daemons/crond/ COPY crates/daemons/pushd/Cargo.toml ./crates/daemons/pushd/ +COPY crates/daemons/voice-ingress/Cargo.toml ./crates/daemons/voice-ingress/ RUN sh /tmp/build-image-layer.sh deps # Build all apps diff --git a/Revolt.toml b/Revolt.toml index 33e044348..0a824e2d6 100644 --- a/Revolt.toml +++ b/Revolt.toml @@ -26,6 +26,11 @@ january = "http://local.revolt.chat:14705" voso_legacy = "" voso_legacy_ws = "" +# Public urls for livekit nodes +# each entry here should have a corresponding entry under `api.livekit.nodes` +[hosts.livekit] +worldwide = "ws://local.revolt.chat:14706" + [api] [api.smtp] @@ -40,6 +45,18 @@ port = 14025 use_tls = false use_starttls = false +[api.livekit] + +# Config for livekit nodes +# Make sure to change the secret when deploying +# The key and secret should match the values livekit is using +[api.livekit.nodes.worldwide] +url = "http://livekit" +lat = 0.0 +lon = 0.0 +key = "worldwide" +secret = "ZjCofRlfm6GGtjlifmNpCDkcQbEIIVC0" + [files.s3] # S3 protocol endpoint endpoint = "http://127.0.0.1:14009" diff --git a/compose.yml b/compose.yml index 89b295940..fadc22f84 100644 --- a/compose.yml +++ b/compose.yml @@ -40,7 +40,7 @@ services: # Rabbit rabbit: - image: rabbitmq:3-management + image: rabbitmq:4-management environment: RABBITMQ_DEFAULT_USER: rabbituser RABBITMQ_DEFAULT_PASS: rabbitpass @@ -64,3 +64,10 @@ services: MAILDEV_WEB_PORT: 8080 MAILDEV_INCOMING_USER: smtp MAILDEV_INCOMING_PASS: smtp + + livekit: + image: ghcr.io/stoatchat/livekit-server:v1.9.9 + command: --config /etc/livekit.yml + network_mode: "host" + volumes: + - ./livekit.yml:/etc/livekit.yml \ No newline at end of file diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index 1928fb467..093c04408 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -41,7 +41,7 @@ authifier = { version = "1.0.15" } revolt-result = { path = "../core/result" } revolt-models = { path = "../core/models" } revolt-config = { path = "../core/config" } -revolt-database = { path = "../core/database" } +revolt-database = { path = "../core/database", features = ["voice"] } revolt-permissions = { version = "0.8.9", path = "../core/permissions" } revolt-presence = { path = "../core/presence", features = ["redis-is-patched"] } diff --git a/crates/bonfire/src/config.rs b/crates/bonfire/src/config.rs index 05f7cf5a0..d70a63205 100644 --- a/crates/bonfire/src/config.rs +++ b/crates/bonfire/src/config.rs @@ -136,6 +136,7 @@ impl handshake::server::Callback for WebsocketHandshakeCallback { channels: false, members: false, emojis: false, + voice_states: false, user_settings: Vec::new(), channel_unreads: false, policy_changes: false, @@ -168,6 +169,7 @@ impl handshake::server::Callback for WebsocketHandshakeCallback { "channels" => ready_payload_fields.channels = true, "members" => ready_payload_fields.members = true, "emojis" => ready_payload_fields.emojis = true, + "voice_states" => ready_payload_fields.voice_states = true, "channel_unreads" => ready_payload_fields.channel_unreads = true, "user_settings" => { if let Some(subkey) = captures.get(1) { diff --git a/crates/bonfire/src/events/impl.rs b/crates/bonfire/src/events/impl.rs index 83b0d4c6f..e0e9ac716 100644 --- a/crates/bonfire/src/events/impl.rs +++ b/crates/bonfire/src/events/impl.rs @@ -1,9 +1,10 @@ -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; use futures::future::join_all; use revolt_database::{ events::client::{EventV1, ReadyPayloadFields}, util::permissions::DatabasePermissionQuery, + voice::get_channel_voice_state, Channel, Database, Member, MemberCompositeKey, Presence, RelationshipStatus, }; use revolt_models::v0; @@ -17,8 +18,9 @@ use super::state::{Cache, State}; impl Cache { /// Check whether the current user can view a channel pub async fn can_view_channel(&self, db: &Database, channel: &Channel) -> bool { + #[allow(deprecated)] match &channel { - Channel::TextChannel { server, .. } | Channel::VoiceChannel { server, .. } => { + Channel::TextChannel { server, .. } => { let member = self.members.get(server); let server = self.servers.get(server); let mut query = @@ -122,12 +124,7 @@ impl State { .unwrap_or_default(); // Fetch all memberships with their corresponding servers. - let members: Vec = db.fetch_all_memberships(&user.id).await?; - self.cache.members = members - .iter() - .cloned() - .map(|x| (x.id.server.clone(), x)) - .collect(); + let mut members: Vec = db.fetch_all_memberships(&user.id).await?; let server_ids: Vec = members.iter().map(|x| x.id.server.clone()).collect(); let servers = db.fetch_servers(&server_ids).await?; @@ -156,6 +153,51 @@ impl State { } } + let voice_states = if fields.voice_states { + let mut voice_state_server_members: HashMap> = HashMap::new(); + + // fetch voice states for all the channels we can see + let mut voice_states = Vec::new(); + + for channel in channels.iter().filter(|c| { + matches!( + c, + Channel::DirectMessage { .. } + | Channel::Group { .. } + | Channel::TextChannel { voice: Some(_), .. } + ) + }) { + if let Ok(Some(voice_state)) = get_channel_voice_state(channel).await { + if let Some(server) = channel.server() { + let set = voice_state_server_members.entry(server.to_string()).or_default(); + + for participant in &voice_state.participants { + user_ids.insert(participant.id.clone()); + set.insert(participant.id.clone()); + } + } else { + for participant in &voice_state.participants { + user_ids.insert(participant.id.clone()); + } + } + + voice_states.push(voice_state); + } + } + + // Fetch all the members for for the participants who are in a server + for (server, user_ids) in voice_state_server_members { + let user_ids = user_ids.into_iter().collect::>(); + let voice_members = db.fetch_members(&server, &user_ids).await?; + + members.extend(voice_members); + } + + Some(voice_states) + } else { + None + }; + // Fetch presence data for known users. let online_ids = filter_online(&user_ids.iter().cloned().collect::>()).await; @@ -169,6 +211,12 @@ impl State { ) .await?; + self.cache.members = members + .iter() + .cloned() + .map(|x| (x.id.server.clone(), x)) + .collect(); + // Fetch customisations. let emojis = if fields.emojis { Some( @@ -268,6 +316,8 @@ impl State { } else { None }, + voice_states, + emojis, user_settings, channel_unreads, @@ -285,19 +335,14 @@ impl State { let id = &id.to_string(); for (channel_id, channel) in &self.cache.channels { - match channel { - Channel::TextChannel { server, .. } | Channel::VoiceChannel { server, .. } => { - if server == id { - channel_ids.insert(channel_id.clone()); - - if self.cache.can_view_channel(db, channel).await { - added_channels.push(channel_id.clone()); - } else { - removed_channels.push(channel_id.clone()); - } - } + if channel.server() == Some(id) { + channel_ids.insert(channel_id.clone()); + + if self.cache.can_view_channel(db, channel).await { + added_channels.push(channel_id.clone()); + } else { + removed_channels.push(channel_id.clone()); } - _ => {} } } @@ -465,6 +510,7 @@ impl State { server, channels, emojis: _, + voice_states: _, } => { self.insert_subscription(id.clone()).await; diff --git a/crates/core/config/Revolt.toml b/crates/core/config/Revolt.toml index 0f2644577..9813a27fe 100644 --- a/crates/core/config/Revolt.toml +++ b/crates/core/config/Revolt.toml @@ -22,6 +22,8 @@ january = "http://local.revolt.chat/january" voso_legacy = "" voso_legacy_ws = "" +[hosts.livekit] + [rabbit] host = "rabbit" port = 5672 @@ -68,8 +70,13 @@ hcaptcha_sitekey = "" # Maximum concurrent connections (to proxy server) max_concurrent_connections = 50 -[api.users] +[api.livekit] +# How long to ring devices for when calling in dms/groups, in seconds +call_ring_duration = 30 + +[api.livekit.nodes] +[api.users] [pushd] # this changes the names of the queues to not overlap @@ -87,6 +94,7 @@ message_queue = "notifications.origin.message" mass_mention_queue = "notifications.origin.mass_mention" # handles messages that contain role or everyone mentions fr_accepted_queue = "notifications.ingest.fr_accepted" # friend request accepted fr_received_queue = "notifications.ingest.fr_received" # friend request received +dm_call_queue = "notifications.ingest.dm_call" # direct message voice call generic_queue = "notifications.ingest.generic" # generic messages (title + body) ack_queue = "notifications.process.ack" # updates badges for apple devices @@ -230,6 +238,18 @@ message_attachments = 5 # Maximum number of servers the user can create/join servers = 50 +# Maximum audio frequency (Hz) in voice calls +voice_quality = 16000 + +# Whether the user can use video streams in voice calls +video = true + +# Mamimum resolution (width, height) of video streams in voice calls +video_resolution = [1080, 720] + +# Minimum and maximum aspect ratio of video streams in voice calls +video_aspect_ratio = [0.3, 2.5] + [features.limits.new_user.file_upload_size_limit] # Maximum file size limits (in bytes) attachments = 20_000_000 @@ -257,6 +277,18 @@ message_attachments = 5 # Maximum number of servers the user can create/join servers = 100 +# Maximum audio frequency (Hz) in voice calls +voice_quality = 16000 + +# Whether the user can use video streams in voice calls +video = true + +# Mamimum resolution (width, height) of video streams in voice calls +video_resolution = [1080, 720] + +# Minimum and maximum aspect ratio of video streams in voice calls +video_aspect_ratio = [0.3, 2.5] + [features.limits.default.file_upload_size_limit] # Maximum file size limits (in bytes) attachments = 20_000_000 @@ -275,6 +307,7 @@ process_message_delay_limit = 5 # Configuration for Sentry error reporting api = "" events = "" +voice_ingress = "" files = "" proxy = "" pushd = "" diff --git a/crates/core/config/src/lib.rs b/crates/core/config/src/lib.rs index 5863cbc4d..46b087765 100644 --- a/crates/core/config/src/lib.rs +++ b/crates/core/config/src/lib.rs @@ -125,8 +125,7 @@ pub struct Hosts { pub events: String, pub autumn: String, pub january: String, - pub voso_legacy: String, - pub voso_legacy_ws: String, + pub livekit: HashMap, } #[derive(Deserialize, Debug, Clone)] @@ -198,6 +197,25 @@ pub struct ApiWorkers { pub max_concurrent_connections: usize, } +#[derive(Deserialize, Debug, Clone)] +pub struct ApiLiveKit { + pub call_ring_duration: usize, + pub nodes: HashMap, +} + +#[derive(Deserialize, Debug, Clone)] +pub struct LiveKitNode { + pub url: String, + pub lat: f64, + pub lon: f64, + pub key: String, + pub secret: String, + + // whether to hide the node in the nodes list + #[serde(default)] + pub private: bool, +} + #[derive(Deserialize, Debug, Clone)] pub struct ApiUsers { pub early_adopter_cutoff: Option, @@ -209,6 +227,7 @@ pub struct Api { pub smtp: ApiSmtp, pub security: ApiSecurity, pub workers: ApiWorkers, + pub livekit: ApiLiveKit, pub users: ApiUsers, } @@ -221,6 +240,7 @@ pub struct Pushd { // Queues pub message_queue: String, pub mass_mention_queue: String, + pub dm_call_queue: String, pub fr_accepted_queue: String, pub fr_received_queue: String, pub generic_queue: String, @@ -251,6 +271,10 @@ impl Pushd { self.get_routing_key(self.mass_mention_queue.clone()) } + pub fn get_dm_call_routing_key(&self) -> String { + self.get_routing_key(self.dm_call_queue.clone()) + } + pub fn get_fr_accepted_routing_key(&self) -> String { self.get_routing_key(self.fr_accepted_queue.clone()) } @@ -318,6 +342,10 @@ pub struct FeaturesLimits { pub message_length: usize, pub message_attachments: usize, pub servers: usize, + pub voice_quality: u32, + pub video: bool, + pub video_resolution: [u32; 2], + pub video_aspect_ratio: [f32; 2], pub file_upload_size_limit: HashMap, } @@ -362,6 +390,7 @@ pub struct Features { pub struct Sentry { pub api: String, pub events: String, + pub voice_ingress: String, pub files: String, pub proxy: String, pub pushd: String, diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index 47095e3da..a1bf5189d 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -18,6 +18,7 @@ async-std-runtime = ["async-std", "authifier/async-std-runtime"] rocket-impl = ["rocket", "schemars", "revolt_okapi", "revolt_rocket_okapi", "authifier/rocket_impl"] axum-impl = ["axum"] redis-is-patched = ["revolt-presence/redis-is-patched"] +voice = ["livekit-api", "livekit-protocol", "livekit-runtime"] # Default Features default = ["mongodb", "async-std-runtime", "tasks"] @@ -96,3 +97,8 @@ authifier = { version = "1.0.15" } # RabbitMQ amqprs = { version = "1.7.0" } + +# Voice +livekit-api = { version = "0.4.4", optional = true} +livekit-protocol = { version = "0.4.0", optional = true } +livekit-runtime = { version = "0.3.1", features = ["tokio"], optional = true } diff --git a/crates/core/database/src/amqp/amqp.rs b/crates/core/database/src/amqp/amqp.rs index b567c7f7c..b29105edf 100644 --- a/crates/core/database/src/amqp/amqp.rs +++ b/crates/core/database/src/amqp/amqp.rs @@ -2,7 +2,8 @@ use std::collections::HashSet; use crate::events::rabbit::*; use crate::User; -use amqprs::channel::BasicPublishArguments; +use amqprs::channel::{BasicPublishArguments, ExchangeDeclareArguments}; +use amqprs::connection::OpenConnectionArguments; use amqprs::{channel::Channel, connection::Connection, error::Error as AMQPError}; use amqprs::{BasicProperties, FieldTable}; use revolt_models::v0::PushNotification; @@ -25,6 +26,35 @@ impl AMQP { } } + pub async fn new_auto() -> AMQP { + let config = revolt_config::config().await; + + let connection = Connection::open(&OpenConnectionArguments::new( + &config.rabbit.host, + config.rabbit.port, + &config.rabbit.username, + &config.rabbit.password, + )) + .await + .expect("Failed to connect to RabbitMQ"); + + let channel = connection + .open_channel(None) + .await + .expect("Failed to open RabbitMQ channel"); + + channel + .exchange_declare( + ExchangeDeclareArguments::new(&config.pushd.exchange, "direct") + .durable(true) + .finish(), + ) + .await + .expect("Failed to declare exchange"); + + AMQP::new(connection, channel) + } + pub async fn friend_request_accepted( &self, accepted_request_user: &User, @@ -240,4 +270,50 @@ impl AMQP { ) .await } + + /// # DM Call Update + /// Used to send an update about a DM call, eg. start or end of a call. + /// Recipients can be used to narrow the scope of recipients, otherwise all recipients will be notified. + /// `ended` refers to the ringing period, not necessarily the call itself. + pub async fn dm_call_updated( + &self, + initiator_id: &str, + channel_id: &str, + started_at: Option<&str>, + ended: bool, + recipients: Option>, + ) -> Result<(), AMQPError> { + let config = revolt_config::config().await; + + let payload = InternalDmCallPayload { + payload: DmCallPayload { + initiator_id: initiator_id.to_string(), + channel_id: channel_id.to_string(), + started_at: started_at.map(|f| f.to_string()), + ended, + }, + recipients, + }; + let payload = to_string(&payload).unwrap(); + + debug!( + "Sending dm call update payload on channel {}: {}", + config.pushd.get_dm_call_routing_key(), + payload + ); + + self.channel + .basic_publish( + BasicProperties::default() + .with_content_type("application/json") + .with_persistence(true) + .finish(), + payload.into(), + BasicPublishArguments::new( + &config.pushd.exchange, + &config.pushd.get_dm_call_routing_key(), + ), + ) + .await + } } diff --git a/crates/core/database/src/drivers/mod.rs b/crates/core/database/src/drivers/mod.rs index 2a2c7b851..9618ee13b 100644 --- a/crates/core/database/src/drivers/mod.rs +++ b/crates/core/database/src/drivers/mod.rs @@ -35,7 +35,7 @@ pub enum DatabaseInfo { } /// Database -#[derive(Clone)] +#[derive(Clone, Debug)] pub enum Database { /// Mock database Reference(ReferenceDb), diff --git a/crates/core/database/src/drivers/mongodb.rs b/crates/core/database/src/drivers/mongodb.rs index fc5dbe3c2..baeddb1da 100644 --- a/crates/core/database/src/drivers/mongodb.rs +++ b/crates/core/database/src/drivers/mongodb.rs @@ -11,6 +11,7 @@ use serde::Serialize; database_derived!( /// MongoDB implementation + #[derive(Debug)] pub struct MongoDb(pub ::mongodb::Client, pub String); ); diff --git a/crates/core/database/src/drivers/reference.rs b/crates/core/database/src/drivers/reference.rs index ff18f2533..e02eae644 100644 --- a/crates/core/database/src/drivers/reference.rs +++ b/crates/core/database/src/drivers/reference.rs @@ -10,7 +10,7 @@ use crate::{ database_derived!( /// Reference implementation - #[derive(Default)] + #[derive(Default, Debug)] pub struct ReferenceDb { pub bots: Arc>>, pub channels: Arc>>, diff --git a/crates/core/database/src/events/client.rs b/crates/core/database/src/events/client.rs index 996347cac..4615273d2 100644 --- a/crates/core/database/src/events/client.rs +++ b/crates/core/database/src/events/client.rs @@ -3,10 +3,7 @@ use revolt_result::Error; use serde::{Deserialize, Serialize}; use revolt_models::v0::{ - AppendMessage, Channel, ChannelUnread, Emoji, FieldsChannel, FieldsMember, FieldsMessage, - FieldsRole, FieldsServer, FieldsUser, FieldsWebhook, Member, MemberCompositeKey, Message, - PartialChannel, PartialMember, PartialMessage, PartialRole, PartialServer, PartialUser, - PartialWebhook, PolicyChange, RemovalIntention, Report, Server, User, UserSettings, Webhook, + AppendMessage, Channel, ChannelUnread, ChannelVoiceState, Emoji, FieldsChannel, FieldsMember, FieldsMessage, FieldsRole, FieldsServer, FieldsUser, FieldsWebhook, Member, MemberCompositeKey, Message, PartialChannel, PartialMember, PartialMessage, PartialRole, PartialServer, PartialUser, PartialUserVoiceState, PartialWebhook, PolicyChange, RemovalIntention, Report, Server, User, UserSettings, UserVoiceState, Webhook }; use crate::Database; @@ -27,6 +24,7 @@ pub struct ReadyPayloadFields { pub channels: bool, pub members: bool, pub emojis: bool, + pub voice_states: bool, pub user_settings: Vec, pub channel_unreads: bool, pub policy_changes: bool, @@ -40,6 +38,7 @@ impl Default for ReadyPayloadFields { channels: true, members: true, emojis: true, + voice_states: true, user_settings: Vec::new(), channel_unreads: false, policy_changes: true, @@ -72,6 +71,8 @@ pub enum EventV1 { members: Option>, #[serde(skip_serializing_if = "Option::is_none")] emojis: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + voice_states: Option>, #[serde(skip_serializing_if = "Option::is_none")] user_settings: Option, @@ -138,6 +139,7 @@ pub enum EventV1 { server: Server, channels: Vec, emojis: Vec, + voice_states: Vec }, /// Update existing server @@ -270,6 +272,33 @@ pub enum EventV1 { /// Auth events Auth(AuthifierEvent), + + /// Voice events + VoiceChannelJoin { + id: String, + state: UserVoiceState, + }, + VoiceChannelLeave { + id: String, + user: String, + }, + VoiceChannelMove { + user: String, + from: String, + to: String, + state: UserVoiceState + }, + UserVoiceStateUpdate { + id: String, + channel_id: String, + data: PartialUserVoiceState, + }, + UserMoveVoiceChannel { + node: String, + from: String, + to: String, + token: String, + } } impl EventV1 { diff --git a/crates/core/database/src/events/rabbit.rs b/crates/core/database/src/events/rabbit.rs index 0ae91be11..6f5c9ab3c 100644 --- a/crates/core/database/src/events/rabbit.rs +++ b/crates/core/database/src/events/rabbit.rs @@ -37,6 +37,20 @@ pub struct GenericPayload { pub user: User, } +#[derive(Serialize, Deserialize, Clone)] +pub struct DmCallPayload { + pub initiator_id: String, + pub channel_id: String, + pub started_at: Option, + pub ended: bool, +} + +#[derive(Serialize, Deserialize, Clone)] +pub struct InternalDmCallPayload { + pub payload: DmCallPayload, + pub recipients: Option>, +} + #[derive(Serialize, Deserialize)] #[serde(tag = "type", content = "data")] #[allow(clippy::large_enum_variant)] @@ -46,6 +60,7 @@ pub enum PayloadKind { FRReceived(FRReceivedPayload), BadgeUpdate(usize), Generic(GenericPayload), + DmCallStartEnd(DmCallPayload), } #[derive(Serialize, Deserialize)] diff --git a/crates/core/database/src/lib.rs b/crates/core/database/src/lib.rs index f9827d03c..778206dce 100644 --- a/crates/core/database/src/lib.rs +++ b/crates/core/database/src/lib.rs @@ -112,6 +112,10 @@ pub mod tasks; mod amqp; pub use amqp::amqp::AMQP; +#[cfg(feature = "voice")] +pub mod voice; + + /// Utility function to check if a boolean value is false pub fn if_false(t: &bool) -> bool { !t diff --git a/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs b/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs index d164cab10..472f665e9 100644 --- a/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs +++ b/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs @@ -9,14 +9,13 @@ use crate::{ bson::{doc, from_bson, from_document, to_document, Bson, DateTime, Document}, options::FindOptions, }, - AbstractChannels, AbstractServers, Channel, Invite, MongoDb, User, DISCRIMINATOR_SEARCH_SPACE, + AbstractServers, Invite, MongoDb, User, DISCRIMINATOR_SEARCH_SPACE, }; use bson::{oid::ObjectId, to_bson}; use futures::StreamExt; use iso8601_timestamp::Timestamp; use rand::seq::SliceRandom; -use revolt_permissions::DEFAULT_WEBHOOK_PERMISSIONS; -use revolt_result::{Error, ErrorType}; +use revolt_permissions::{ChannelPermission, DEFAULT_WEBHOOK_PERMISSIONS}; use serde::{Deserialize, Serialize}; use unicode_segmentation::UnicodeSegmentation; @@ -26,7 +25,7 @@ struct MigrationInfo { revision: i32, } -pub const LATEST_REVISION: i32 = 42; // MUST BE +1 to last migration +pub const LATEST_REVISION: i32 = 49; // MUST BE +1 to last migration pub async fn migrate_database(db: &MongoDb) { let migrations = db.col::("migrations"); @@ -914,6 +913,7 @@ pub async fn run_migrations(db: &MongoDb, revision: i32) -> i32 { } if revision <= 26 { + // Need to migrate fields on attachments, change `user_id`, `object_id`, etc to `parent`. info!("Running migration [revision 26 / 15-05-2024]: fix invites being incorrectly serialized with wrong enum tagging."); auto_derived!( @@ -1080,6 +1080,14 @@ pub async fn run_migrations(db: &MongoDb, revision: i32) -> i32 { channel_id: String, } + #[allow(clippy::enum_variant_names)] + #[derive(serde::Serialize, serde::Deserialize)] + enum Channel { + Group { owner: String }, + TextChannel { server: String }, + VoiceChannel { server: String } + } + let webhooks = db .db() .collection::("channel_webhooks") @@ -1091,8 +1099,8 @@ pub async fn run_migrations(db: &MongoDb, revision: i32) -> i32 { .await; for webhook in webhooks { - match db.fetch_channel(&webhook.channel_id).await { - Ok(channel) => { + match db.col::("channels").find_one(doc! { "_id": &webhook.channel_id }).await.unwrap() { + Some(channel) => { let creator_id = match channel { Channel::Group { owner, .. } => owner, Channel::TextChannel { server, .. } @@ -1100,7 +1108,6 @@ pub async fn run_migrations(db: &MongoDb, revision: i32) -> i32 { let server = db.fetch_server(&server).await.expect("server"); server.owner } - _ => unreachable!("not server or group channel!"), }; db.db() @@ -1118,17 +1125,13 @@ pub async fn run_migrations(db: &MongoDb, revision: i32) -> i32 { .await .expect("update webhook"); } - Err(Error { - error_type: ErrorType::NotFound, - .. - }) => { + None => { db.db() .collection::("channel_webhooks") .delete_one(doc! { "_id": webhook._id }) .await .expect("failed to delete invalid webhook"); } - Err(err) => panic!("{err:?}"), } } } @@ -1169,9 +1172,9 @@ pub async fn run_migrations(db: &MongoDb, revision: i32) -> i32 { .expect("failed to update users"); } - if revision <= 41 { + if revision <= 43 { info!( - "Running migration [revision 41 / 05-06-2025]: convert role ranks to uniform numbers." + "Running migration [revision 43 / 05-06-2025]: convert role ranks to uniform numbers." ); #[derive(Serialize, Deserialize, Clone)] @@ -1226,6 +1229,41 @@ pub async fn run_migrations(db: &MongoDb, revision: i32) -> i32 { } } + if revision <= 46 { + info!("Running migration [revision 46 / 29-04-2025]: Convert all `VoiceChannel`'s into `TextChannel`"); + + db.col::("channels") + .update_many( + doc! { "channel_type": "VoiceChannel" }, + doc! { + "$set": { + "channel_type": "TextChannel", + "voice": {} + } + } + ) + .await + .expect("Failed to update voice channels"); + }; + + if revision <= 48 { + info!("Running migration [revision 48 / 22-10-2025]: Add Video + Listen to default permissions"); + + db.col::("servers") + .update_many( + doc! { }, + doc! { + "$bit": { + "default_permissions": { + "or": (ChannelPermission::Video + ChannelPermission::Speak + ChannelPermission::Listen) as i64 + }, + } + } + ) + .await + .expect("Failed to update default_permissions"); + }; + // Reminder to update LATEST_REVISION when adding new migrations. LATEST_REVISION.max(revision) } diff --git a/crates/core/database/src/models/channel_invites/model.rs b/crates/core/database/src/models/channel_invites/model.rs index e3af921ab..a5d877fee 100644 --- a/crates/core/database/src/models/channel_invites/model.rs +++ b/crates/core/database/src/models/channel_invites/model.rs @@ -69,7 +69,7 @@ impl Invite { creator: creator.id.clone(), channel: id.clone(), }), - Channel::TextChannel { id, server, .. } | Channel::VoiceChannel { id, server, .. } => { + Channel::TextChannel { id, server, .. } => { Ok(Invite::Server { code, creator: creator.id.clone(), diff --git a/crates/core/database/src/models/channels/model.rs b/crates/core/database/src/models/channels/model.rs index 673e5e508..d8a485b94 100644 --- a/crates/core/database/src/models/channels/model.rs +++ b/crates/core/database/src/models/channels/model.rs @@ -1,4 +1,5 @@ -use std::collections::HashMap; +#![allow(deprecated)] +use std::{borrow::Cow, collections::HashMap}; use revolt_config::config; use revolt_models::v0::{self, MessageAuthor}; @@ -8,8 +9,7 @@ use serde::{Deserialize, Serialize}; use ulid::Ulid; use crate::{ - events::client::EventV1, Database, File, PartialServer, - Server, SystemMessage, User, AMQP, + events::client::EventV1, Database, File, PartialServer, Server, SystemMessage, User, AMQP, }; #[cfg(feature = "mongodb")] @@ -106,39 +106,19 @@ auto_derived!( /// Whether this channel is marked as not safe for work #[serde(skip_serializing_if = "crate::if_false", default)] nsfw: bool, - }, - /// Voice channel belonging to a server - VoiceChannel { - /// Unique Id - #[serde(rename = "_id")] - id: String, - /// Id of the server this channel belongs to - server: String, - - /// Display name of the channel - name: String, - #[serde(skip_serializing_if = "Option::is_none")] - /// Channel description - description: Option, - /// Custom icon attachment - #[serde(skip_serializing_if = "Option::is_none")] - icon: Option, - /// Default permissions assigned to users in this channel + /// Voice Information for when this channel is also a voice channel #[serde(skip_serializing_if = "Option::is_none")] - default_permissions: Option, - /// Permissions assigned based on role to this channel - #[serde( - default = "HashMap::::new", - skip_serializing_if = "HashMap::::is_empty" - )] - role_permissions: HashMap, - - /// Whether this channel is marked as not safe for work - #[serde(skip_serializing_if = "crate::if_false", default)] - nsfw: bool, + voice: Option, }, } + + #[derive(Default)] + pub struct VoiceInformation { + /// Maximium amount of users allowed in the voice channel at once + #[serde(skip_serializing_if = "Option::is_none")] + pub max_users: Option, + } ); auto_derived!( @@ -164,6 +144,8 @@ auto_derived!( pub default_permissions: Option, #[serde(skip_serializing_if = "Option::is_none")] pub last_message_id: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub voice: Option, } /// Optional fields on channel object @@ -171,6 +153,7 @@ auto_derived!( Description, Icon, DefaultPermissions, + Voice, } ); @@ -222,16 +205,19 @@ impl Channel { default_permissions: None, role_permissions: HashMap::new(), nsfw: data.nsfw.unwrap_or(false), + voice: data.voice.map(|voice| voice.into()), }, - v0::LegacyServerChannelType::Voice => Channel::VoiceChannel { + v0::LegacyServerChannelType::Voice => Channel::TextChannel { id: id.clone(), server: server.id.to_owned(), name: data.name, description: data.description, icon: None, + last_message_id: None, default_permissions: None, role_permissions: HashMap::new(), nsfw: data.nsfw.unwrap_or(false), + voice: Some(data.voice.unwrap_or_default().into()), }, }; @@ -432,8 +418,28 @@ impl Channel { Channel::DirectMessage { id, .. } | Channel::Group { id, .. } | Channel::SavedMessages { id, .. } - | Channel::TextChannel { id, .. } - | Channel::VoiceChannel { id, .. } => id, + | Channel::TextChannel { id, .. } => id, + } + } + + /// Clone this channel's server id + pub fn server(&self) -> Option<&str> { + match self { + Channel::TextChannel { server, .. } => Some(server), + _ => None, + } + } + + /// Gets this channel's voice information + pub fn voice(&self) -> Option> { + match self { + Self::DirectMessage { .. } | Self::Group { .. } => { + Some(Cow::Owned(VoiceInformation::default())) + } + Self::TextChannel { + voice: Some(voice), .. + } => Some(Cow::Borrowed(voice)), + _ => None, } } @@ -450,12 +456,6 @@ impl Channel { server, role_permissions, .. - } - | Channel::VoiceChannel { - id, - server, - role_permissions, - .. } => { db.set_channel_role_permission(id, role_id, permissions) .await?; @@ -502,7 +502,7 @@ impl Channel { clear: remove.into_iter().map(|v| v.into()).collect(), } .p(match self { - Self::TextChannel { server, .. } | Self::VoiceChannel { server, .. } => server.clone(), + Self::TextChannel { server, .. } => server.clone(), _ => id, }) .await; @@ -514,17 +514,13 @@ impl Channel { pub fn remove_field(&mut self, field: &FieldsChannel) { match field { FieldsChannel::Description => match self { - Self::Group { description, .. } - | Self::TextChannel { description, .. } - | Self::VoiceChannel { description, .. } => { + Self::Group { description, .. } | Self::TextChannel { description, .. } => { description.take(); } _ => {} }, FieldsChannel::Icon => match self { - Self::Group { icon, .. } - | Self::TextChannel { icon, .. } - | Self::VoiceChannel { icon, .. } => { + Self::Group { icon, .. } | Self::TextChannel { icon, .. } => { icon.take(); } _ => {} @@ -533,15 +529,17 @@ impl Channel { Self::TextChannel { default_permissions, .. - } - | Self::VoiceChannel { - default_permissions, - .. } => { default_permissions.take(); } _ => {} }, + FieldsChannel::Voice => match self { + Self::TextChannel { voice, .. } => { + voice.take(); + } + _ => {} + }, } } @@ -553,6 +551,7 @@ impl Channel { } /// Apply partial channel to channel + #[allow(deprecated)] pub fn apply_options(&mut self, partial: PartialChannel) { match self { Self::SavedMessages { .. } => {} @@ -601,15 +600,7 @@ impl Channel { nsfw, default_permissions, role_permissions, - .. - } - | Self::VoiceChannel { - name, - description, - icon, - nsfw, - default_permissions, - role_permissions, + voice, .. } => { if let Some(v) = partial.name { @@ -635,6 +626,10 @@ impl Channel { if let Some(v) = partial.default_permissions { default_permissions.replace(v); } + + if let Some(v) = partial.voice { + voice.replace(v); + } } } } @@ -777,6 +772,7 @@ impl IntoDocumentPath for FieldsChannel { FieldsChannel::Description => "description", FieldsChannel::Icon => "icon", FieldsChannel::DefaultPermissions => "default_permissions", + FieldsChannel::Voice => "voice", }) } } diff --git a/crates/core/database/src/models/channels/ops/mongodb.rs b/crates/core/database/src/models/channels/ops/mongodb.rs index b247a6834..79612f8d7 100644 --- a/crates/core/database/src/models/channels/ops/mongodb.rs +++ b/crates/core/database/src/models/channels/ops/mongodb.rs @@ -184,7 +184,7 @@ impl AbstractChannels for MongoDb { async fn delete_channel(&self, channel: &Channel) -> Result<()> { let id = channel.id().to_string(); let server_id = match channel { - Channel::TextChannel { server, .. } | Channel::VoiceChannel { server, .. } => { + Channel::TextChannel { server, .. } => { Some(server) } _ => None, diff --git a/crates/core/database/src/models/channels/ops/reference.rs b/crates/core/database/src/models/channels/ops/reference.rs index 7d5c9a59f..518808bcc 100644 --- a/crates/core/database/src/models/channels/ops/reference.rs +++ b/crates/core/database/src/models/channels/ops/reference.rs @@ -94,9 +94,6 @@ impl AbstractChannels for ReferenceDb { match &mut channel { Channel::TextChannel { role_permissions, .. - } - | Channel::VoiceChannel { - role_permissions, .. } => { if role_permissions.get(role_id).is_some() { role_permissions.remove(role_id); diff --git a/crates/core/database/src/models/messages/model.rs b/crates/core/database/src/models/messages/model.rs index f9d0d1017..11bc2eacf 100644 --- a/crates/core/database/src/models/messages/model.rs +++ b/crates/core/database/src/models/messages/model.rs @@ -114,6 +114,11 @@ auto_derived!( MessagePinned { id: String, by: String }, #[serde(rename = "message_unpinned")] MessageUnpinned { id: String, by: String }, + #[serde(rename = "call_started")] + CallStarted { + by: String, + finished_at: Option, + }, } /// Name and / or avatar override information @@ -326,9 +331,7 @@ impl Message { } let server_id = match channel { - Channel::TextChannel { ref server, .. } | Channel::VoiceChannel { ref server, .. } => { - Some(server.clone()) - } + Channel::TextChannel { ref server, .. } => Some(server.clone()), _ => None, }; @@ -486,6 +489,7 @@ impl Message { // Validate the mentions go to users in the channel/server if !user_mentions.is_empty() { + #[allow(deprecated)] match channel { Channel::DirectMessage { ref recipients, .. } | Channel::Group { ref recipients, .. } => { @@ -493,8 +497,7 @@ impl Message { user_mentions.retain(|m| recipients_hash.contains(m)); role_mentions.clear(); } - Channel::TextChannel { ref server, .. } - | Channel::VoiceChannel { ref server, .. } => { + Channel::TextChannel { ref server, .. }=> { let mentions_vec = Vec::from_iter(user_mentions.iter().cloned()); let valid_members = db.fetch_members(server.as_str(), &mentions_vec[..]).await; @@ -684,7 +687,6 @@ impl Message { ) .await?; - if !self.has_suppressed_notifications() && (self.mentions.is_some() || self.contains_mass_push_mention()) { @@ -800,7 +802,7 @@ impl Message { query: MessageQuery, perspective: &User, include_users: Option, - server_id: Option, + server_id: Option<&str>, ) -> Result { let messages: Vec = db .fetch_messages(query) @@ -843,6 +845,7 @@ impl Message { v0::SystemMessage::MessageUnpinned { by, .. } => { users.push(by.clone()); } + v0::SystemMessage::CallStarted { by, .. } => users.push(by.clone()), } } users @@ -857,7 +860,7 @@ impl Message { users, members: if let Some(server_id) = server_id { Some( - db.fetch_members(&server_id, &user_ids) + db.fetch_members(server_id, &user_ids) .await? .into_iter() .map(Into::into) diff --git a/crates/core/database/src/models/server_members/model.rs b/crates/core/database/src/models/server_members/model.rs index ee5e354bc..74ec04a8e 100644 --- a/crates/core/database/src/models/server_members/model.rs +++ b/crates/core/database/src/models/server_members/model.rs @@ -3,10 +3,18 @@ use revolt_permissions::{calculate_channel_permissions, ChannelPermission}; use revolt_result::{create_error, Result}; use crate::{ - events::client::EventV1, util::permissions::DatabasePermissionQuery, Channel, Database, File, - Server, SystemMessage, User, + events::client::EventV1, util::permissions::DatabasePermissionQuery, Channel, + Database, File, Server, SystemMessage, User, }; +fn default_true() -> bool { + true +} + +fn is_true(x: &bool) -> bool { + *x +} + auto_derived_partial!( /// Server Member pub struct Member { @@ -30,6 +38,14 @@ auto_derived_partial!( /// Timestamp this member is timed out until #[serde(skip_serializing_if = "Option::is_none")] pub timeout: Option, + + /// Whether the member is server-wide voice muted + #[serde(skip_serializing_if = "is_true", default = "default_true")] + pub can_publish: bool, + /// Whether the member is server-wide voice deafened + #[serde(skip_serializing_if = "is_true", default = "default_true")] + pub can_receive: bool, + // This value only exists in the database, not the models. // If it is not-None, the database layer should return None to member fetching queries. // pub pending_deletion_at: Option @@ -53,6 +69,8 @@ auto_derived!( Avatar, Roles, Timeout, + CanReceive, + CanPublish, JoinedAt, } @@ -73,6 +91,8 @@ impl Default for Member { avatar: None, roles: vec![], timeout: None, + can_publish: true, + can_receive: true, } } } @@ -127,6 +147,16 @@ impl Member { let emojis = db.fetch_emoji_by_parent_id(&server.id).await?; + #[allow(unused_mut)] + let mut voice_states = Vec::new(); + + #[cfg(feature = "voice")] + for channel in &channels { + if let Ok(Some(voice_state)) = crate::voice::get_channel_voice_state(channel).await { + voice_states.push(voice_state) + } + } + EventV1::ServerMemberJoin { id: server.id.clone(), user: user.id.clone(), @@ -144,6 +174,7 @@ impl Member { .map(|channel| channel.into()) .collect(), emojis: emojis.into_iter().map(|emoji| emoji.into()).collect(), + voice_states } .private(user.id.clone()) .await; @@ -198,6 +229,8 @@ impl Member { FieldsMember::Nickname => self.nickname = None, FieldsMember::Roles => self.roles.clear(), FieldsMember::Timeout => self.timeout = None, + FieldsMember::CanReceive => self.can_receive = true, + FieldsMember::CanPublish => self.can_publish = true, } } diff --git a/crates/core/database/src/models/server_members/ops/mongodb.rs b/crates/core/database/src/models/server_members/ops/mongodb.rs index cd9c50954..198ad6a80 100644 --- a/crates/core/database/src/models/server_members/ops/mongodb.rs +++ b/crates/core/database/src/models/server_members/ops/mongodb.rs @@ -336,6 +336,8 @@ impl IntoDocumentPath for FieldsMember { FieldsMember::Nickname => "nickname", FieldsMember::Roles => "roles", FieldsMember::Timeout => "timeout", + FieldsMember::CanPublish => "can_publish", + FieldsMember::CanReceive => "can_receive", }) } } diff --git a/crates/core/database/src/tasks/ack.rs b/crates/core/database/src/tasks/ack.rs index c12e41f3c..c26de03b7 100644 --- a/crates/core/database/src/tasks/ack.rs +++ b/crates/core/database/src/tasks/ack.rs @@ -14,7 +14,7 @@ use validator::HasLen; use revolt_result::Result; use super::DelayedTask; -use crate::Channel::{TextChannel, VoiceChannel}; +use crate::Channel::TextChannel; /// Enumeration of possible events #[derive(Debug, Eq, PartialEq)] @@ -191,17 +191,14 @@ pub async fn handle_ack_event( .await .expect("Failed to fetch channel from db"); - match channel { - TextChannel { server, .. } | VoiceChannel { server, .. } => { - if let Err(err) = - amqp.mass_mention_message_sent(server, mass_mentions).await - { - revolt_config::capture_error(&err); - } - } - _ => { - panic!("Unknown channel type when sending mass mention event"); + if let TextChannel { server, .. } = channel { + if let Err(err) = + amqp.mass_mention_message_sent(server, mass_mentions).await + { + revolt_config::capture_error(&err); } + } else { + panic!("Unknown channel type when sending mass mention event"); } } } diff --git a/crates/core/database/src/util/bridge/v0.rs b/crates/core/database/src/util/bridge/v0.rs index de64a4bf2..915b75ce1 100644 --- a/crates/core/database/src/util/bridge/v0.rs +++ b/crates/core/database/src/util/bridge/v0.rs @@ -143,6 +143,7 @@ impl From for FieldsWebhook { } impl From for Channel { + #[allow(deprecated)] fn from(value: crate::Channel) -> Self { match value { crate::Channel::SavedMessages { id, user } => Channel::SavedMessages { id, user }, @@ -188,6 +189,7 @@ impl From for Channel { default_permissions, role_permissions, nsfw, + voice, } => Channel::TextChannel { id, server, @@ -198,31 +200,14 @@ impl From for Channel { default_permissions, role_permissions, nsfw, - }, - crate::Channel::VoiceChannel { - id, - server, - name, - description, - icon, - default_permissions, - role_permissions, - nsfw, - } => Channel::VoiceChannel { - id, - server, - name, - description, - icon: icon.map(|file| file.into()), - default_permissions, - role_permissions, - nsfw, + voice: voice.map(|voice| voice.into()), }, } } } impl From for crate::Channel { + #[allow(deprecated)] fn from(value: Channel) -> crate::Channel { match value { Channel::SavedMessages { id, user } => crate::Channel::SavedMessages { id, user }, @@ -268,6 +253,7 @@ impl From for crate::Channel { default_permissions, role_permissions, nsfw, + voice, } => crate::Channel::TextChannel { id, server, @@ -278,25 +264,7 @@ impl From for crate::Channel { default_permissions, role_permissions, nsfw, - }, - Channel::VoiceChannel { - id, - server, - name, - description, - icon, - default_permissions, - role_permissions, - nsfw, - } => crate::Channel::VoiceChannel { - id, - server, - name, - description, - icon: icon.map(|file| file.into()), - default_permissions, - role_permissions, - nsfw, + voice: voice.map(|voice| voice.into()), }, } } @@ -315,6 +283,7 @@ impl From for PartialChannel { role_permissions: value.role_permissions, default_permissions: value.default_permissions, last_message_id: value.last_message_id, + voice: value.voice.map(|voice| voice.into()) } } } @@ -332,6 +301,7 @@ impl From for crate::PartialChannel { role_permissions: value.role_permissions, default_permissions: value.default_permissions, last_message_id: value.last_message_id, + voice: value.voice.map(|voice| voice.into()) } } } @@ -342,6 +312,7 @@ impl From for crate::FieldsChannel { FieldsChannel::Description => crate::FieldsChannel::Description, FieldsChannel::Icon => crate::FieldsChannel::Icon, FieldsChannel::DefaultPermissions => crate::FieldsChannel::DefaultPermissions, + FieldsChannel::Voice => crate::FieldsChannel::Voice, } } } @@ -352,6 +323,7 @@ impl From for FieldsChannel { crate::FieldsChannel::Description => FieldsChannel::Description, crate::FieldsChannel::Icon => FieldsChannel::Icon, crate::FieldsChannel::DefaultPermissions => FieldsChannel::DefaultPermissions, + crate::FieldsChannel::Voice => FieldsChannel::Voice, } } } @@ -543,6 +515,7 @@ impl From for SystemMessage { crate::SystemMessage::UserRemove { id, by } => Self::UserRemove { id, by }, crate::SystemMessage::MessagePinned { id, by } => Self::MessagePinned { id, by }, crate::SystemMessage::MessageUnpinned { id, by } => Self::MessageUnpinned { id, by }, + crate::SystemMessage::CallStarted { by, finished_at } => Self::CallStarted { by, finished_at } } } } @@ -639,6 +612,8 @@ impl From for Member { avatar: value.avatar.map(|f| f.into()), roles: value.roles, timeout: value.timeout, + can_publish: value.can_publish, + can_receive: value.can_receive, } } } @@ -652,6 +627,8 @@ impl From for crate::Member { avatar: value.avatar.map(|f| f.into()), roles: value.roles, timeout: value.timeout, + can_publish: value.can_publish, + can_receive: value.can_receive, } } } @@ -665,6 +642,8 @@ impl From for PartialMember { avatar: value.avatar.map(|f| f.into()), roles: value.roles, timeout: value.timeout, + can_publish: value.can_publish, + can_receive: value.can_receive, } } } @@ -678,6 +657,8 @@ impl From for crate::PartialMember { avatar: value.avatar.map(|f| f.into()), roles: value.roles, timeout: value.timeout, + can_publish: value.can_publish, + can_receive: value.can_receive, } } } @@ -707,6 +688,8 @@ impl From for FieldsMember { crate::FieldsMember::Nickname => FieldsMember::Nickname, crate::FieldsMember::Roles => FieldsMember::Roles, crate::FieldsMember::Timeout => FieldsMember::Timeout, + crate::FieldsMember::CanReceive => FieldsMember::CanReceive, + crate::FieldsMember::CanPublish => FieldsMember::CanPublish, crate::FieldsMember::JoinedAt => FieldsMember::JoinedAt, } } @@ -719,6 +702,8 @@ impl From for crate::FieldsMember { FieldsMember::Nickname => crate::FieldsMember::Nickname, FieldsMember::Roles => crate::FieldsMember::Roles, FieldsMember::Timeout => crate::FieldsMember::Timeout, + FieldsMember::CanReceive => crate::FieldsMember::CanReceive, + FieldsMember::CanPublish => crate::FieldsMember::CanPublish, FieldsMember::JoinedAt => crate::FieldsMember::JoinedAt, } } @@ -1387,3 +1372,19 @@ impl From for crate::FieldsMessage { } } } + +impl From for crate::VoiceInformation { + fn from(value: VoiceInformation) -> Self { + crate::VoiceInformation { + max_users: value.max_users + } + } +} + +impl From for VoiceInformation { + fn from(value: crate::VoiceInformation) -> Self { + VoiceInformation { + max_users: value.max_users + } + } +} \ No newline at end of file diff --git a/crates/core/database/src/util/bulk_permissions.rs b/crates/core/database/src/util/bulk_permissions.rs index 9e7a1f7a1..976b0d692 100644 --- a/crates/core/database/src/util/bulk_permissions.rs +++ b/crates/core/database/src/util/bulk_permissions.rs @@ -144,10 +144,6 @@ impl<'z> BulkDatabasePermissionQuery<'z> { Channel::TextChannel { default_permissions, .. - } - | Channel::VoiceChannel { - default_permissions, - .. } => default_permissions.unwrap_or_default().into(), _ => Default::default(), } @@ -156,16 +152,14 @@ impl<'z> BulkDatabasePermissionQuery<'z> { } } - #[allow(dead_code)] + #[allow(dead_code, deprecated)] fn get_channel_type(&mut self) -> ChannelType { if let Some(channel) = &self.channel { match channel { Channel::DirectMessage { .. } => ChannelType::DirectMessage, Channel::Group { .. } => ChannelType::Group, Channel::SavedMessages { .. } => ChannelType::SavedMessages, - Channel::TextChannel { .. } | Channel::VoiceChannel { .. } => { - ChannelType::ServerChannel - } + Channel::TextChannel { .. } => ChannelType::ServerChannel, } } else { ChannelType::Unknown @@ -179,9 +173,6 @@ impl<'z> BulkDatabasePermissionQuery<'z> { match channel { Channel::TextChannel { role_permissions, .. - } - | Channel::VoiceChannel { - role_permissions, .. } => role_permissions, _ => panic!("Not supported for non-server channels"), } @@ -208,12 +199,6 @@ async fn calculate_members_permissions<'a>( role_permissions, default_permissions, .. - } - | Channel::VoiceChannel { - id, - role_permissions, - default_permissions, - .. } => (id, role_permissions, default_permissions), _ => panic!("Calculation of member permissions must be done on a server channel"), }; diff --git a/crates/core/database/src/util/funcs.rs b/crates/core/database/src/util/funcs.rs new file mode 100644 index 000000000..24f9906d4 --- /dev/null +++ b/crates/core/database/src/util/funcs.rs @@ -0,0 +1,24 @@ +use crate::Database; +use revolt_result::Result; + +/// Formats a user's name depending on their optional features and location. +/// Factors in server display names and user display names before falling back to username#discriminator. +/// Passing a server in which the user is not a member will result in an Err. +pub async fn format_display_name( + db: &Database, + user_id: &str, + server_id: Option<&str>, +) -> Result { + if let Some(server_id) = server_id { + let member = db.fetch_member(server_id, user_id).await?; + if let Some(nick) = member.nickname { + return Ok(nick); + } + } + + let user = db.fetch_user(user_id).await?; + if let Some(display) = user.display_name { + return Ok(display); + } + Ok(format!("{}#{}", user.username, user.discriminator)) +} diff --git a/crates/core/database/src/util/mod.rs b/crates/core/database/src/util/mod.rs index 1baf7d8ba..1a03a1768 100644 --- a/crates/core/database/src/util/mod.rs +++ b/crates/core/database/src/util/mod.rs @@ -1,6 +1,9 @@ pub mod bridge; pub mod bulk_permissions; +mod funcs; pub mod idempotency; pub mod permissions; pub mod reference; pub mod test_fixtures; + +pub use funcs::*; diff --git a/crates/core/database/src/util/permissions.rs b/crates/core/database/src/util/permissions.rs index e592988eb..85db48267 100644 --- a/crates/core/database/src/util/permissions.rs +++ b/crates/core/database/src/util/permissions.rs @@ -185,9 +185,26 @@ impl PermissionQuery for DatabasePermissionQuery<'_> { } } + async fn do_we_have_publish_overwrites(&mut self) -> bool { + if let Some(member) = &self.member { + member.can_publish + } else { + true + } + } + + async fn do_we_have_receive_overwrites(&mut self) -> bool { + if let Some(member) = &self.member { + member.can_receive + } else { + true + } + } + // * For calculating channel permission /// Get the type of the channel + #[allow(deprecated)] async fn get_channel_type(&mut self) -> ChannelType { if let Some(channel) = &self.channel { match channel { @@ -199,9 +216,7 @@ impl PermissionQuery for DatabasePermissionQuery<'_> { Cow::Borrowed(Channel::SavedMessages { .. }) | Cow::Owned(Channel::SavedMessages { .. }) => ChannelType::SavedMessages, Cow::Borrowed(Channel::TextChannel { .. }) - | Cow::Owned(Channel::TextChannel { .. }) - | Cow::Borrowed(Channel::VoiceChannel { .. }) - | Cow::Owned(Channel::VoiceChannel { .. }) => ChannelType::ServerChannel, + | Cow::Owned(Channel::TextChannel { .. }) => ChannelType::ServerChannel, } } else { ChannelType::Unknown @@ -225,14 +240,6 @@ impl PermissionQuery for DatabasePermissionQuery<'_> { | Cow::Owned(Channel::TextChannel { default_permissions, .. - }) - | Cow::Borrowed(Channel::VoiceChannel { - default_permissions, - .. - }) - | Cow::Owned(Channel::VoiceChannel { - default_permissions, - .. }) => default_permissions.unwrap_or_default().into(), _ => Default::default(), } @@ -250,12 +257,6 @@ impl PermissionQuery for DatabasePermissionQuery<'_> { }) | Cow::Owned(Channel::TextChannel { role_permissions, .. - }) - | Cow::Borrowed(Channel::VoiceChannel { - role_permissions, .. - }) - | Cow::Owned(Channel::VoiceChannel { - role_permissions, .. }) => { if let Some(server) = &self.server { let member_roles = self @@ -343,11 +344,10 @@ impl PermissionQuery for DatabasePermissionQuery<'_> { /// (this will only ever be called for server channels, use unimplemented!() for other code paths) async fn set_server_from_channel(&mut self) { if let Some(channel) = &self.channel { + #[allow(deprecated)] match channel { Cow::Borrowed(Channel::TextChannel { server, .. }) - | Cow::Owned(Channel::TextChannel { server, .. }) - | Cow::Borrowed(Channel::VoiceChannel { server, .. }) - | Cow::Owned(Channel::VoiceChannel { server, .. }) => { + | Cow::Owned(Channel::TextChannel { server, .. }) => { if let Some(known_server) = // I'm not sure why I can't just pattern match both at once here? // It throws some weird error and the provided fix doesn't work :/ diff --git a/crates/core/database/src/voice/mod.rs b/crates/core/database/src/voice/mod.rs new file mode 100644 index 000000000..56009a539 --- /dev/null +++ b/crates/core/database/src/voice/mod.rs @@ -0,0 +1,598 @@ +use crate::{ + events::client::EventV1, + models::{Channel, User}, + util::{permissions::DatabasePermissionQuery, reference::Reference}, + Database, Server, +}; +use iso8601_timestamp::{Duration, Timestamp}; +use livekit_protocol::ParticipantPermission; +use redis_kiss::{get_connection as _get_connection, redis::Pipeline, AsyncCommands, Conn}; +use revolt_config::FeaturesLimits; +use revolt_models::v0::{self, PartialUserVoiceState, UserVoiceState}; +use revolt_permissions::{calculate_channel_permissions, ChannelPermission, PermissionValue}; +use revolt_result::{create_error, Result, ToRevoltError}; + +mod voice_client; +pub use voice_client::VoiceClient; + +async fn get_connection() -> Result { + _get_connection().await.map_err(|_| create_error!(InternalError)) +} + +pub async fn raise_if_in_voice(user: &User, channel_id: &str) -> Result<()> { + let mut conn = get_connection().await?; + + if user.bot.is_some() + // bots can be in as many voice channels as it wants so we just check if its already connected to the one its trying to connect to + && conn.sismember(format!("vc:{}", &user.id), channel_id) + .await + .to_internal_error()? + { + Err(create_error!(AlreadyConnected)) + } else if conn + .scard::<_, u32>(format!("vc:{}", &user.id)) // check if the current vc set is empty + .await + .to_internal_error()? + > 0 + { + Err(create_error!(AlreadyConnected)) + } else { + Ok(()) + } +} + +pub async fn set_channel_node(channel: &str, node: &str) -> Result<()> { + get_connection() + .await? + .set(format!("node:{channel}"), node) + .await + .to_internal_error() +} + +pub async fn get_channel_node(channel: &str) -> Result> { + get_connection() + .await? + .get(format!("node:{channel}")) + .await + .to_internal_error() +} + +pub async fn get_user_voice_channels(user_id: &str) -> Result> { + get_connection() + .await? + .smembers(format!("vc:{user_id}")) + .await + .to_internal_error() +} + +pub async fn set_user_moved_from_voice( + old_channel: &str, + new_channel: &str, + user_id: &str, +) -> Result<()> { + get_connection() + .await? + .set_ex( + format!("moved_from:{user_id}:{old_channel}"), + new_channel, + 10, + ) + .await + .to_internal_error() +} + +pub async fn get_user_moved_from_voice(channel_id: &str, user_id: &str) -> Result> { + get_connection() + .await? + .get_del(format!("moved_from:{user_id}:{channel_id}")) + .await + .to_internal_error() +} + +pub async fn set_user_moved_to_voice( + new_channel: &str, + old_channel: &str, + user_id: &str, +) -> Result<()> { + get_connection() + .await? + .set_ex(format!("moved_to:{user_id}:{new_channel}"), old_channel, 10) + .await + .to_internal_error() +} + +pub async fn get_user_moved_to_voice(channel_id: &str, user_id: &str) -> Result> { + get_connection() + .await? + .get_del(format!("moved_to:{user_id}:{channel_id}")) + .await + .to_internal_error() +} + +pub async fn is_in_voice_channel(user_id: &str, channel_id: &str) -> Result { + get_connection() + .await? + .sismember(format!("vc:{user_id}"), channel_id) + .await + .to_internal_error() +} + +pub async fn get_user_voice_channel_in_server( + user_id: &str, + server_id: &str, +) -> Result> { + let mut conn = get_connection().await?; + + let unique_key = format!("{user_id}:{server_id}"); + + conn.get(&unique_key).await.to_internal_error() +} + +pub fn get_allowed_sources( + limits: &FeaturesLimits, + permissions: PermissionValue, +) -> Vec<&'static str> { + let mut allowed_sources = Vec::new(); + + if permissions.has(ChannelPermission::Speak as u64) { + allowed_sources.push("microphone") + }; + + if permissions.has(ChannelPermission::Video as u64) && limits.video { + allowed_sources.extend(["camera", "screen_share", "screen_share_audio"]); + }; + + allowed_sources +} + +pub async fn create_voice_state( + channel_id: &str, + server_id: Option<&str>, + user_id: &str, + joined_at: Timestamp, +) -> Result { + let unique_key = format!("{}:{}", &user_id, server_id.unwrap_or(channel_id)); + + let voice_state = UserVoiceState { + joined_at, + id: user_id.to_string(), + is_receiving: true, + is_publishing: false, + screensharing: false, + camera: false, + }; + + Pipeline::new() + .sadd(format!("vc_members:{channel_id}"), user_id) + .sadd(format!("vc:{user_id}"), channel_id) + .set(&unique_key, channel_id) + .set( + format!("joined_at:{unique_key}"), + joined_at + .duration_since(Timestamp::UNIX_EPOCH) + .whole_milliseconds() as i64, + ) + .set( + format!("is_publishing:{unique_key}"), + voice_state.is_publishing, + ) + .set( + format!("is_receiving:{unique_key}"), + voice_state.is_receiving, + ) + .set( + format!("screensharing:{unique_key}"), + voice_state.screensharing, + ) + .set(format!("camera:{unique_key}"), voice_state.camera) + .query_async::<_, ()>(&mut get_connection().await?.into_inner()) + .await + .to_internal_error()?; + + Ok(voice_state) +} + +pub async fn delete_voice_state( + channel_id: &str, + server_id: Option<&str>, + user_id: &str, +) -> Result<()> { + let unique_key = format!("{}:{}", &user_id, server_id.unwrap_or(channel_id)); + + Pipeline::new() + .srem(format!("vc_members:{channel_id}"), user_id) + .srem(format!("vc:{user_id}"), channel_id) + .del(&[ + format!("joined_at:{unique_key}"), + format!("is_publishing:{unique_key}"), + format!("is_receiving:{unique_key}"), + format!("screensharing:{unique_key}"), + format!("camera:{unique_key}"), + unique_key.clone(), + ]) + .query_async(&mut get_connection().await?.into_inner()) + .await + .to_internal_error() +} + +pub async fn delete_channel_voice_state( + channel_id: &str, + server_id: Option<&str>, + user_ids: &[String], +) -> Result<()> { + let parent_id = server_id.unwrap_or(channel_id); + + let mut pipeline = Pipeline::new(); + pipeline.del(format!("vc_members:{channel_id}")); + + for user_id in user_ids { + let unique_key = format!("{user_id}:{parent_id}"); + + pipeline.srem(format!("vc:{user_id}"), channel_id).del(&[ + format!("joined_at:{unique_key}"), + format!("is_publishing:{unique_key}"), + format!("is_receiving:{unique_key}"), + format!("screensharing:{unique_key}"), + format!("camera:{unique_key}"), + unique_key.clone(), + ]); + } + + pipeline + .query_async(&mut get_connection().await?.into_inner()) + .await + .to_internal_error() +} + +pub async fn update_voice_state_tracks( + channel_id: &str, + server_id: Option<&str>, + user_id: &str, + added: bool, + track: i32, +) -> Result { + let partial = match track { + /* TrackSource::Unknown */ 0 => PartialUserVoiceState::default(), + /* TrackSource::Camera */ + 1 => PartialUserVoiceState { + camera: Some(added), + ..Default::default() + }, + /* TrackSource::Microphone */ + 2 => PartialUserVoiceState { + is_publishing: Some(added), + ..Default::default() + }, + /* TrackSource::ScreenShare | TrackSource::ScreenShareAudio */ + 3 | 4 => PartialUserVoiceState { + screensharing: Some(added), + ..Default::default() + }, + _ => unreachable!(), + }; + + update_voice_state(channel_id, server_id, user_id, &partial).await?; + + Ok(partial) +} + +pub async fn update_voice_state( + channel_id: &str, + server_id: Option<&str>, + user_id: &str, + partial: &PartialUserVoiceState, +) -> Result<()> { + let unique_key = format!("{}:{}", &user_id, server_id.unwrap_or(channel_id)); + + let mut pipeline = Pipeline::new(); + + if let Some(camera) = &partial.camera { + pipeline.set(format!("camera:{unique_key}"), camera); + }; + + if let Some(is_publishing) = &partial.is_publishing { + pipeline.set(format!("is_publishing:{unique_key}"), is_publishing); + } + + if let Some(is_receiving) = &partial.is_receiving { + pipeline.set(format!("is_receiving:{unique_key}"), is_receiving); + } + + if let Some(screensharing) = &partial.screensharing { + pipeline.set(format!("screensharing:{unique_key}"), screensharing); + } + + pipeline + .query_async(&mut get_connection().await?.into_inner()) + .await + .to_internal_error() +} + +pub async fn get_voice_channel_members(channel_id: &str) -> Result>> { + get_connection() + .await? + .smembers::<_, Option>>(format!("vc_members:{channel_id}")) + .await + .to_internal_error() + .map(|opt| opt.and_then(|v| if v.is_empty() { None } else { Some(v) })) +} + +pub async fn get_voice_state( + channel_id: &str, + server_id: Option<&str>, + user_id: &str, +) -> Result> { + let unique_key = format!("{}:{}", user_id, server_id.unwrap_or(channel_id)); + + let (joined_at, is_publishing, is_receiving, screensharing, camera) = get_connection() + .await? + .mget(&[ + format!("joined_at:{unique_key}"), + format!("is_publishing:{unique_key}"), + format!("is_receiving:{unique_key}"), + format!("screensharing:{unique_key}"), + format!("camera:{unique_key}"), + ]) + .await + .to_internal_error()?; + + match ( + joined_at, + is_publishing, + is_receiving, + screensharing, + camera, + ) { + ( + Some(joined_at), + Some(is_publishing), + Some(is_receiving), + Some(screensharing), + Some(camera), + ) => Ok(Some(v0::UserVoiceState { + joined_at: Timestamp::UNIX_EPOCH + .checked_add(Duration::milliseconds(joined_at)) + .unwrap(), + id: user_id.to_string(), + is_receiving, + is_publishing, + screensharing, + camera, + })), + _ => Ok(None), + } +} + +pub async fn get_channel_voice_state(channel: &Channel) -> Result> { + let members = get_voice_channel_members(channel.id()).await?; + + let server = channel.server(); + + if let Some(members) = members { + let mut participants = Vec::with_capacity(members.len()); + + for user_id in members { + if let Some(voice_state) = get_voice_state(channel.id(), server, &user_id).await? { + participants.push(voice_state); + } else { + log::info!("Voice state not found but member in voice channel members, removing."); + + delete_voice_state(channel.id(), server, &user_id).await?; + } + } + + // In case a user voice state failed to be fetched, the vec's capacity will be larger than the length, shrink it + participants.shrink_to_fit(); + + Ok(Some(v0::ChannelVoiceState { + id: channel.id().to_string(), + participants, + })) + } else { + Ok(None) + } +} + +pub async fn move_user(user: &str, from: &str, to: &str) -> Result<()> { + get_connection() + .await? + .smove( + format!("vc-members-{from}"), + format!("vc-members-{to}"), + user, + ) + .await + .to_internal_error() +} + +pub async fn sync_voice_permissions( + db: &Database, + voice_client: &VoiceClient, + channel: &Channel, + server: Option<&Server>, + role_id: Option<&str>, +) -> Result<()> { + let Some(node) = get_channel_node(channel.id()).await? else { + return Ok(()); + }; + + for user_id in get_voice_channel_members(channel.id()) + .await? + .iter() + .flatten() + { + let user = Reference::from_unchecked(user_id).as_user(db).await?; + + sync_user_voice_permissions(db, voice_client, &node, &user, channel, server, role_id) + .await?; + } + + Ok(()) +} + +pub async fn sync_user_voice_permissions( + db: &Database, + voice_client: &VoiceClient, + node: &str, + user: &User, + channel: &Channel, + server: Option<&Server>, + role_id: Option<&str>, +) -> Result<()> { + let channel_id = channel.id(); + let server_id = server.as_ref().map(|s| s.id.as_str()); + + let member = match server_id { + Some(server_id) => Some( + Reference::from_unchecked(&user.id) + .as_member(db, server_id) + .await?, + ), + None => None, + }; + + if role_id.is_none_or(|role_id| { + member + .as_ref() + .is_none_or(|member| member.roles.iter().any(|r| r == role_id)) + }) { + let Some(voice_state) = get_voice_state(channel_id, server_id, &user.id).await? else { + return Ok(()); + }; + + let mut query = DatabasePermissionQuery::new(db, user) + .channel(channel) + .user(user); + + if let (Some(server), Some(member)) = (server, member.as_ref()) { + query = query.member(member).server(server) + } + + let permissions = calculate_channel_permissions(&mut query).await; + let limits = user.limits().await; + + let mut update_event = PartialUserVoiceState { + id: Some(user.id.clone()), + ..Default::default() + }; + + let before = update_event.clone(); + + let can_video = + limits.video && permissions.has_channel_permission(ChannelPermission::Video); + let can_speak = permissions.has_channel_permission(ChannelPermission::Speak); + let can_listen = permissions.has_channel_permission(ChannelPermission::Listen); + + update_event.camera = voice_state.camera.then_some(can_video); + update_event.screensharing = voice_state.screensharing.then_some(can_video); + update_event.is_publishing = voice_state.is_publishing.then_some(can_speak); + + update_voice_state(channel_id, server_id, &user.id, &update_event).await?; + + voice_client + .update_permissions( + node, + user, + channel_id, + ParticipantPermission { + can_subscribe: can_listen, + can_publish: can_speak, + can_publish_data: can_speak, + ..Default::default() + }, + ) + .await?; + + if update_event != before { + EventV1::UserVoiceStateUpdate { + id: user.id.clone(), + channel_id: channel_id.to_string(), + data: update_event, + } + .p(channel_id.to_string()) + .await; + }; + }; + + Ok(()) +} + +pub async fn set_channel_call_started_system_message( + channel_id: &str, + message_id: &str, +) -> Result<()> { + get_connection() + .await? + .set(format!("call_started_message:{channel_id}"), message_id) + .await + .to_internal_error() +} + +pub async fn take_channel_call_started_system_message(channel_id: &str) -> Result> { + get_connection() + .await? + .get_del(format!("call_started_message:{channel_id}")) + .await + .to_internal_error() +} + +pub async fn set_call_notification_recipients( + channel_id: &str, + user_id: &str, + recipients: &[String], +) -> Result<()> { + get_connection() + .await? + .set_ex( + format!("call_notification_recipients:{channel_id}-{user_id}"), + recipients, + 10, + ) + .await + .to_internal_error() +} + +pub async fn get_call_notification_recipients( + channel_id: &str, + user_id: &str, +) -> Result>> { + get_connection() + .await? + .get_del(format!( + "call_notification_recipients:{channel_id}-{user_id}" + )) + .await + .to_internal_error() +} + +pub async fn remove_user_from_voice_channels(db: &Database, voice_client: &VoiceClient, user_id: &str) -> Result<()> { + for channel_id in get_user_voice_channels(user_id).await? { + remove_user_from_voice_channel(db, voice_client, &channel_id, user_id).await?; + }; + + Ok(()) +} + +pub async fn remove_user_from_voice_channel(db: &Database, voice_client: &VoiceClient, channel_id: &str, user_id: &str) -> Result<()> { + if let Some(node) = get_channel_node(channel_id).await? { + let _ = voice_client.remove_user(&node, user_id, channel_id).await; + } + + let channel = Reference::from_unchecked(channel_id).as_channel(db).await?; + + delete_voice_state(channel_id, channel.server(), user_id).await?; + + Ok(()) +} + +pub async fn delete_voice_channel(voice_client: &VoiceClient, channel_id: &str, server_id: Option<&str>) -> Result<()> { + if let Some(users) = get_voice_channel_members(channel_id).await? { + let node = get_channel_node(channel_id).await?.unwrap(); + + voice_client.delete_room(&node, channel_id).await?; + + delete_channel_voice_state(channel_id, server_id, &users).await?; + }; + + Ok(()) +} \ No newline at end of file diff --git a/crates/core/database/src/voice/voice_client.rs b/crates/core/database/src/voice/voice_client.rs new file mode 100644 index 000000000..967f3fefc --- /dev/null +++ b/crates/core/database/src/voice/voice_client.rs @@ -0,0 +1,156 @@ +use crate::{ + models::{Channel, User}, + Database, +}; +use livekit_api::{ + access_token::{AccessToken, VideoGrants}, + services::room::{CreateRoomOptions, RoomClient as InnerRoomClient, UpdateParticipantOptions}, +}; +use livekit_protocol::{ParticipantInfo, ParticipantPermission, Room}; +use revolt_config::{config, LiveKitNode}; +use revolt_permissions::{ChannelPermission, PermissionValue}; +use revolt_result::{create_error, Result, ToRevoltError}; +use std::{collections::HashMap, time::Duration}; + +use super::get_allowed_sources; + +#[derive(Debug)] +pub struct RoomClient { + pub client: InnerRoomClient, + pub node: LiveKitNode, +} + +#[derive(Debug)] +pub struct VoiceClient { + pub rooms: HashMap, +} + +impl VoiceClient { + pub fn new(nodes: HashMap) -> Self { + Self { + rooms: nodes + .into_iter() + .map(|(name, node)| { + ( + name, + RoomClient { + client: InnerRoomClient::with_api_key( + &node.url, + &node.key, + &node.secret, + ), + node, + }, + ) + }) + .collect(), + } + } + + pub fn is_enabled(&self) -> bool { + !self.rooms.is_empty() + } + + pub async fn from_revolt_config() -> Self { + let config = config().await; + + Self::new(config.api.livekit.nodes.clone()) + } + + pub fn get_node(&self, name: &str) -> Result<&RoomClient> { + self.rooms + .get(name) + .ok_or_else(|| create_error!(UnknownNode)) + } + + pub async fn create_token( + &self, + node: &str, + db: &Database, + user: &User, + permissions: PermissionValue, + channel: &Channel, + ) -> Result { + let room = self.get_node(node)?; + + let limits = user.limits().await; + let allowed_sources = get_allowed_sources(&limits, permissions); + + AccessToken::with_api_key(&room.node.key, &room.node.secret) + .with_name(&format!("{}#{}", user.username, user.discriminator)) + .with_identity(&user.id) + .with_metadata( + &serde_json::to_string(&user.clone().into(db, None).await).to_internal_error()?, + ) + .with_ttl(Duration::from_secs(10)) + .with_grants(VideoGrants { + room_join: true, + can_publish: true, + can_publish_data: false, + can_publish_sources: allowed_sources + .into_iter() + .map(ToString::to_string) + .collect(), + can_subscribe: permissions.has_channel_permission(ChannelPermission::Listen), + room: channel.id().to_string(), + ..Default::default() + }) + .to_jwt() + .to_internal_error() + } + + pub async fn create_room(&self, node: &str, channel: &Channel) -> Result { + let room = self.get_node(node)?; + + room.client + .create_room( + channel.id(), + CreateRoomOptions { + empty_timeout: 5 * 60, // 5 minutes, + ..Default::default() + }, + ) + .await + .to_internal_error() + } + + pub async fn update_permissions( + &self, + node: &str, + user: &User, + channel_id: &str, + new_permissions: ParticipantPermission, + ) -> Result { + let room = self.get_node(node)?; + + room.client + .update_participant( + channel_id, + &user.id, + UpdateParticipantOptions { + permission: Some(new_permissions), + ..Default::default() + }, + ) + .await + .to_internal_error() + } + + pub async fn remove_user(&self, node: &str, user_id: &str, channel_id: &str) -> Result<()> { + let room = self.get_node(node)?; + + room.client + .remove_participant(channel_id, user_id) + .await + .to_internal_error() + } + + pub async fn delete_room(&self, node: &str, channel_id: &str) -> Result<()> { + let room = self.get_node(node)?; + + room.client + .delete_room(channel_id) + .await + .to_internal_error() + } +} diff --git a/crates/core/models/src/v0/channels.rs b/crates/core/models/src/v0/channels.rs index ec25257b8..d8b4e228d 100644 --- a/crates/core/models/src/v0/channels.rs +++ b/crates/core/models/src/v0/channels.rs @@ -1,4 +1,5 @@ -use super::File; +#![allow(deprecated)] +use super::{File, UserVoiceState}; use revolt_permissions::{Override, OverrideField}; use std::collections::{HashMap, HashSet}; @@ -107,46 +108,23 @@ auto_derived!( serde(skip_serializing_if = "crate::if_false", default) )] nsfw: bool, - }, - /// Voice channel belonging to a server - VoiceChannel { - /// Unique Id - #[cfg_attr(feature = "serde", serde(rename = "_id"))] - id: String, - /// Id of the server this channel belongs to - server: String, - /// Display name of the channel - name: String, - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] - /// Channel description - description: Option, - /// Custom icon attachment + /// Voice Information for when this channel is also a voice channel #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] - icon: Option, - - /// Default permissions assigned to users in this channel - #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] - default_permissions: Option, - /// Permissions assigned based on role to this channel - #[cfg_attr( - feature = "serde", - serde( - default = "HashMap::::new", - skip_serializing_if = "HashMap::::is_empty" - ) - )] - role_permissions: HashMap, - - /// Whether this channel is marked as not safe for work - #[cfg_attr( - feature = "serde", - serde(skip_serializing_if = "crate::if_false", default) - )] - nsfw: bool, + voice: Option, }, } + /// Voice information for a channel + #[derive(Default)] + #[cfg_attr(feature = "validator", derive(validator::Validate))] + pub struct VoiceInformation { + /// Maximium amount of users allowed in the voice channel at once + #[cfg_attr(feature = "validator", validate(range(min = 1)))] + #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + pub max_users: Option, + } + /// Partial representation of a channel #[derive(Default)] pub struct PartialChannel { @@ -170,6 +148,8 @@ auto_derived!( pub default_permissions: Option, #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] pub last_message_id: Option, + #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + pub voice: Option, } /// Optional fields on channel object @@ -177,6 +157,7 @@ auto_derived!( Description, Icon, DefaultPermissions, + Voice, } /// New webhook information @@ -205,6 +186,9 @@ auto_derived!( /// Whether this channel is archived pub archived: Option, + /// Voice Information for voice channels + pub voice: Option, + /// Fields to remove from channel #[cfg_attr(feature = "serde", serde(default))] pub remove: Vec, @@ -260,6 +244,10 @@ auto_derived!( /// Whether this channel is age restricted #[serde(skip_serializing_if = "Option::is_none")] pub nsfw: Option, + + /// Voice Information for when this channel is also a voice channel + #[serde(skip_serializing_if = "Option::is_none")] + pub voice: Option, } /// New default permissions @@ -270,7 +258,7 @@ auto_derived!( permissions: u64, }, Field { - /// Allow / deny values to set for members in this `TextChannel` or `VoiceChannel` + /// Allow / deny values to set for members in this server channel permissions: Override, }, } @@ -289,9 +277,32 @@ auto_derived!( } /// Voice server token response - pub struct LegacyCreateVoiceUserResponse { + pub struct CreateVoiceUserResponse { /// Token for authenticating with the voice server - token: String, + pub token: String, + /// Url of the livekit server to connect to + pub url: String, + } + + /// Voice state for a channel + pub struct ChannelVoiceState { + pub id: String, + /// The states of the users who are connected to the channel + pub participants: Vec, + } + + /// Join a voice channel + pub struct DataJoinCall { + /// Name of the node to join + pub node: Option, + /// Whether to force disconnect any other existing voice connections + /// + /// Useful for disconnecting on another device and joining on a new. + pub force_disconnect: Option, + /// Users which should be notified of the call starting + /// + /// Only used when the user is the first one connected. + pub recipients: Option>, } ); @@ -302,8 +313,7 @@ impl Channel { Channel::DirectMessage { id, .. } | Channel::Group { id, .. } | Channel::SavedMessages { id, .. } - | Channel::TextChannel { id, .. } - | Channel::VoiceChannel { id, .. } => id, + | Channel::TextChannel { id, .. } => id, } } @@ -315,9 +325,7 @@ impl Channel { match self { Channel::DirectMessage { .. } => None, Channel::SavedMessages { .. } => Some("Saved Messages"), - Channel::TextChannel { name, .. } - | Channel::Group { name, .. } - | Channel::VoiceChannel { name, .. } => Some(name), + Channel::TextChannel { name, .. } | Channel::Group { name, .. } => Some(name), } } } diff --git a/crates/core/models/src/v0/messages.rs b/crates/core/models/src/v0/messages.rs index 2116d98ba..67af69f85 100644 --- a/crates/core/models/src/v0/messages.rs +++ b/crates/core/models/src/v0/messages.rs @@ -132,6 +132,8 @@ auto_derived!( MessagePinned { id: String, by: String }, #[serde(rename = "message_unpinned")] MessageUnpinned { id: String, by: String }, + #[serde(rename = "call_started")] + CallStarted { by: String, finished_at: Option }, } /// Name and / or avatar override information @@ -445,6 +447,7 @@ impl From for String { } SystemMessage::MessagePinned { .. } => "Message pinned.".to_string(), SystemMessage::MessageUnpinned { .. } => "Message unpinned.".to_string(), + SystemMessage::CallStarted { .. } => "Call started.".to_string(), } } } diff --git a/crates/core/models/src/v0/server_members.rs b/crates/core/models/src/v0/server_members.rs index 048f696bc..d1ccb0589 100644 --- a/crates/core/models/src/v0/server_members.rs +++ b/crates/core/models/src/v0/server_members.rs @@ -31,6 +31,14 @@ pub static RE_COLOUR: Lazy = Lazy::new(|| { Regex::new(r"(?i)^(?:[a-z ]+|var\(--[a-z\d-]+\)|rgba?\([\d, ]+\)|#[a-f0-9]+|(repeating-)?(linear|conic|radial)-gradient\(([a-z ]+|var\(--[a-z\d-]+\)|rgba?\([\d, ]+\)|#[a-f0-9]+|\d+deg)([ ]+(\d{1,3}%|0))?(,[ ]*([a-z ]+|var\(--[a-z\d-]+\)|rgba?\([\d, ]+\)|#[a-f0-9]+)([ ]+(\d{1,3}%|0))?)+\))$").unwrap() }); +fn default_true() -> bool { + true +} + +fn is_true(x: &bool) -> bool { + *x +} + auto_derived_partial!( /// Server Member pub struct Member { @@ -57,6 +65,13 @@ auto_derived_partial!( /// Timestamp this member is timed out until #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] pub timeout: Option, + + /// Whether the member is server-wide voice muted + #[serde(skip_serializing_if = "is_true", default = "default_true")] + pub can_publish: bool, + /// Whether the member is server-wide voice deafened + #[serde(skip_serializing_if = "is_true", default = "default_true")] + pub can_receive: bool, }, "PartialMember" ); @@ -77,6 +92,8 @@ auto_derived!( Avatar, Roles, Timeout, + CanReceive, + CanPublish, JoinedAt, } @@ -124,6 +141,12 @@ auto_derived!( pub roles: Option>, /// Timestamp this member is timed out until pub timeout: Option, + /// server-wide voice muted + pub can_publish: Option, + /// server-wide voice deafened + pub can_receive: Option, + /// voice channel to move to if already in a voice channel + pub voice_channel: Option, /// Fields to remove from channel object #[cfg_attr(feature = "serde", serde(default))] pub remove: Vec, diff --git a/crates/core/models/src/v0/users.rs b/crates/core/models/src/v0/users.rs index fc681e003..73957768b 100644 --- a/crates/core/models/src/v0/users.rs +++ b/crates/core/models/src/v0/users.rs @@ -1,3 +1,4 @@ +use iso8601_timestamp::Timestamp; use once_cell::sync::Lazy; use regex::Regex; @@ -279,6 +280,19 @@ auto_derived!( } ); +auto_derived_partial!( + /// Voice State information for a user + pub struct UserVoiceState { + pub id: String, + pub joined_at: Timestamp, + pub is_receiving: bool, + pub is_publishing: bool, + pub screensharing: bool, + pub camera: bool, + }, + "PartialUserVoiceState" +); + pub trait CheckRelationship { fn with(&self, user: &str) -> RelationshipStatus; } diff --git a/crates/core/permissions/src/impl.rs b/crates/core/permissions/src/impl.rs index 9975eeda5..064fee3e6 100644 --- a/crates/core/permissions/src/impl.rs +++ b/crates/core/permissions/src/impl.rs @@ -61,6 +61,15 @@ pub async fn calculate_server_permissions(query: &mut P) -> permissions.apply(role_override); } + if !query.do_we_have_publish_overwrites().await { + permissions.revoke(ChannelPermission::Speak as u64); + permissions.revoke(ChannelPermission::Video as u64); + } + + if !query.do_we_have_receive_overwrites().await { + permissions.revoke(ChannelPermission::Listen as u64); + } + if query.are_we_timed_out().await { permissions.restrict(*ALLOW_IN_TIMEOUT); } diff --git a/crates/core/permissions/src/models/channel.rs b/crates/core/permissions/src/models/channel.rs index aca22b5c2..9e9160263 100644 --- a/crates/core/permissions/src/models/channel.rs +++ b/crates/core/permissions/src/models/channel.rs @@ -89,6 +89,8 @@ pub enum ChannelPermission { DeafenMembers = 1 << 34, /// Move members between voice channels MoveMembers = 1 << 35, + /// Listen to other users + Listen = 1 << 36, // * Channel permissions two electric boogaloo /// Mention everyone and online members @@ -130,7 +132,9 @@ pub static DEFAULT_PERMISSION: Lazy = Lazy::new(|| { + ChannelPermission::SendEmbeds + ChannelPermission::UploadFiles + ChannelPermission::Connect - + ChannelPermission::Speak, + + ChannelPermission::Speak + + ChannelPermission::Listen + + ChannelPermission::Video ) }); diff --git a/crates/core/permissions/src/models/server.rs b/crates/core/permissions/src/models/server.rs index e6355eedc..8391029a0 100644 --- a/crates/core/permissions/src/models/server.rs +++ b/crates/core/permissions/src/models/server.rs @@ -39,7 +39,7 @@ pub enum DataPermissionPoly { permissions: u64, }, Field { - /// Allow / deny values to set for members in this `TextChannel` or `VoiceChannel` + /// Allow / deny values to set for members in this server channel permissions: Override, }, } diff --git a/crates/core/permissions/src/test.rs b/crates/core/permissions/src/test.rs index e4dadd485..93e1dea2c 100644 --- a/crates/core/permissions/src/test.rs +++ b/crates/core/permissions/src/test.rs @@ -64,6 +64,14 @@ async fn validate_user_permissions() { unreachable!() } + async fn do_we_have_publish_overwrites(&mut self) -> bool { + true + } + + async fn do_we_have_receive_overwrites(&mut self) -> bool { + true + } + async fn get_channel_type(&mut self) -> ChannelType { ChannelType::DirectMessage } @@ -153,6 +161,14 @@ async fn validate_group_permissions() { unreachable!() } + async fn do_we_have_publish_overwrites(&mut self) -> bool { + true + } + + async fn do_we_have_receive_overwrites(&mut self) -> bool { + true + } + async fn get_channel_type(&mut self) -> ChannelType { ChannelType::Group } @@ -254,6 +270,14 @@ async fn validate_server_permissions() { false } + async fn do_we_have_publish_overwrites(&mut self) -> bool { + true + } + + async fn do_we_have_receive_overwrites(&mut self) -> bool { + true + } + async fn get_channel_type(&mut self) -> ChannelType { ChannelType::ServerChannel } @@ -346,6 +370,14 @@ async fn validate_timed_out_member() { true } + async fn do_we_have_publish_overwrites(&mut self) -> bool { + true + } + + async fn do_we_have_receive_overwrites(&mut self) -> bool { + true + } + async fn get_channel_type(&mut self) -> ChannelType { ChannelType::ServerChannel } diff --git a/crates/core/permissions/src/trait.rs b/crates/core/permissions/src/trait.rs index d4a7c3d36..96b42caf8 100644 --- a/crates/core/permissions/src/trait.rs +++ b/crates/core/permissions/src/trait.rs @@ -39,6 +39,12 @@ pub trait PermissionQuery { /// Is our perspective user timed out on this server? async fn are_we_timed_out(&mut self) -> bool; + /// Is the member muted? + async fn do_we_have_publish_overwrites(&mut self) -> bool; + + /// Is the member deafend? + async fn do_we_have_receive_overwrites(&mut self) -> bool; + // * For calculating channel permission /// Get the type of the channel diff --git a/crates/core/result/Cargo.toml b/crates/core/result/Cargo.toml index b8ce0c59e..ebc0764ea 100644 --- a/crates/core/result/Cargo.toml +++ b/crates/core/result/Cargo.toml @@ -15,8 +15,9 @@ utoipa = ["dep:utoipa"] rocket = ["dep:rocket", "dep:serde_json"] axum = ["dep:axum", "dep:serde_json"] okapi = ["dep:revolt_rocket_okapi", "dep:revolt_okapi", "schemas"] +sentry = ["dep:sentry"] -default = ["serde"] +default = ["serde", "sentry"] [dependencies] # Serialisation @@ -32,5 +33,9 @@ rocket = { optional = true, version = "0.5.0-rc.2", default-features = false } revolt_rocket_okapi = { version = "0.10.0", optional = true } revolt_okapi = { version = "0.9.1", optional = true } +# utilities +log = "0.4" # Axum axum = { version = "0.7.5", optional = true } + +sentry = { version = "0.31.5", optional = true } \ No newline at end of file diff --git a/crates/core/result/src/axum.rs b/crates/core/result/src/axum.rs index 08ad0b41b..3cbf43590 100644 --- a/crates/core/result/src/axum.rs +++ b/crates/core/result/src/axum.rs @@ -76,6 +76,11 @@ impl IntoResponse for Error { ErrorType::NotFound => StatusCode::NOT_FOUND, ErrorType::NoEffect => StatusCode::OK, ErrorType::FailedValidation { .. } => StatusCode::BAD_REQUEST, + ErrorType::LiveKitUnavailable => StatusCode::BAD_REQUEST, + ErrorType::NotConnected => StatusCode::BAD_REQUEST, + ErrorType::NotAVoiceChannel => StatusCode::BAD_REQUEST, + ErrorType::AlreadyConnected => StatusCode::BAD_REQUEST, + ErrorType::UnknownNode => StatusCode::BAD_REQUEST, ErrorType::InvalidFlagValue => StatusCode::BAD_REQUEST, ErrorType::FeatureDisabled { .. } => StatusCode::BAD_REQUEST, diff --git a/crates/core/result/src/lib.rs b/crates/core/result/src/lib.rs index 5ae2ac2a0..a76612124 100644 --- a/crates/core/result/src/lib.rs +++ b/crates/core/result/src/lib.rs @@ -1,3 +1,4 @@ +use std::panic::Location; use std::fmt::Display; #[cfg(feature = "serde")] @@ -159,6 +160,12 @@ pub enum ErrorType { error: String, }, + // ? Voice errors + LiveKitUnavailable, + NotAVoiceChannel, + AlreadyConnected, + NotConnected, + UnknownNode, // ? Micro-service errors ProxyError, FileTooSmall, @@ -198,6 +205,61 @@ macro_rules! create_database_error { }; } +#[macro_export] +#[cfg(debug_assertions)] +macro_rules! query { + ( $self: ident, $type: ident, $collection: expr, $($rest:expr),+ ) => { + Ok($self.$type($collection, $($rest),+).await.unwrap()) + }; +} + +#[macro_export] +#[cfg(not(debug_assertions))] +macro_rules! query { + ( $self: ident, $type: ident, $collection: expr, $($rest:expr),+ ) => { + $self.$type($collection, $($rest),+).await + .map_err(|_| create_database_error!(stringify!($type), $collection)) + }; +} + +pub trait ToRevoltError { + #[track_caller] + fn to_internal_error(self) -> Result; +} + +impl ToRevoltError for Result { + #[track_caller] + fn to_internal_error(self) -> Result { + let loc = Location::caller(); + + self + .map_err(|e| { + log::error!("{e:?}"); + #[cfg(feature = "sentry")] + sentry::capture_error(&e); + + Error { + error_type: ErrorType::InternalError, + location: format!("{}:{}:{}", loc.file(), loc.line(), loc.column()) + } + }) + } +} + +impl ToRevoltError for Option { + #[track_caller] + fn to_internal_error(self) -> Result { + let loc = Location::caller(); + + self.ok_or_else(|| { + Error { + error_type: ErrorType::InternalError, + location: format!("{}:{}:{}", loc.file(), loc.line(), loc.column()) + } + }) + } +} + #[cfg(test)] mod tests { use crate::ErrorType; diff --git a/crates/core/result/src/rocket.rs b/crates/core/result/src/rocket.rs index f450d88ba..94bed4d2b 100644 --- a/crates/core/result/src/rocket.rs +++ b/crates/core/result/src/rocket.rs @@ -79,10 +79,14 @@ impl<'r> Responder<'r, 'static> for Error { ErrorType::InvalidSession => Status::Unauthorized, ErrorType::NotAuthenticated => Status::Unauthorized, ErrorType::DuplicateNonce => Status::Conflict, - ErrorType::VosoUnavailable => Status::BadRequest, ErrorType::NotFound => Status::NotFound, ErrorType::NoEffect => Status::Ok, ErrorType::FailedValidation { .. } => Status::BadRequest, + ErrorType::LiveKitUnavailable => Status::BadRequest, + ErrorType::NotAVoiceChannel => Status::BadRequest, + ErrorType::AlreadyConnected => Status::BadRequest, + ErrorType::NotConnected => Status::BadRequest, + ErrorType::UnknownNode => Status::BadRequest, ErrorType::FeatureDisabled { .. } => Status::BadRequest, ErrorType::ProxyError => Status::BadRequest, @@ -91,6 +95,7 @@ impl<'r> Responder<'r, 'static> for Error { ErrorType::FileTypeNotAllowed => Status::BadRequest, ErrorType::ImageProcessingFailed => Status::InternalServerError, ErrorType::NoEmbedData => Status::BadRequest, + ErrorType::VosoUnavailable => Status::BadRequest, }; // Serialize the error data structure into JSON. diff --git a/crates/daemons/pushd/src/consumers/inbound/dm_call.rs b/crates/daemons/pushd/src/consumers/inbound/dm_call.rs new file mode 100644 index 000000000..b5b89dc13 --- /dev/null +++ b/crates/daemons/pushd/src/consumers/inbound/dm_call.rs @@ -0,0 +1,168 @@ +use std::collections::HashMap; + +use crate::consumers::inbound::internal::*; +use amqprs::{ + channel::{BasicPublishArguments, Channel}, + connection::Connection, + consumer::AsyncConsumer, + BasicProperties, Deliver, +}; +use anyhow::Result; +use async_trait::async_trait; +use log::debug; +use revolt_database::{events::rabbit::*, Database}; + +pub struct DmCallConsumer { + #[allow(dead_code)] + db: Database, + authifier_db: authifier::Database, + conn: Option, + channel: Option, +} + +impl Channeled for DmCallConsumer { + fn get_connection(&self) -> Option<&Connection> { + if self.conn.is_none() { + None + } else { + Some(self.conn.as_ref().unwrap()) + } + } + + fn get_channel(&self) -> Option<&Channel> { + if self.channel.is_none() { + None + } else { + Some(self.channel.as_ref().unwrap()) + } + } + + fn set_connection(&mut self, conn: Connection) { + self.conn = Some(conn); + } + + fn set_channel(&mut self, channel: Channel) { + self.channel = Some(channel) + } +} + +impl DmCallConsumer { + pub fn new(db: Database, authifier_db: authifier::Database) -> DmCallConsumer { + DmCallConsumer { + db, + authifier_db, + conn: None, + channel: None, + } + } + + async fn consume_event( + &mut self, + _channel: &Channel, + _deliver: Deliver, + _basic_properties: BasicProperties, + content: Vec, + ) -> Result<()> { + let content = String::from_utf8(content)?; + let _p: InternalDmCallPayload = serde_json::from_str(content.as_str())?; + let payload = _p.payload; + + debug!("Received dm call start/stop event"); + + let (revolt_database::Channel::DirectMessage { recipients, .. } + | revolt_database::Channel::Group { recipients, .. }) = + self.db.fetch_channel(&payload.channel_id).await? + else { + warn!( + "Discarding dm call start/stop event for non-dm/group channel {}", + payload.channel_id + ); + + return Ok(()); + }; + + let call_recipients = if let Some(user_recipients) = _p.recipients { + user_recipients + .into_iter() + .filter(|user_id| recipients.contains(user_id) && user_id != &payload.initiator_id) + .collect() + } else { + recipients + .into_iter() + .filter(|user_id| user_id != &payload.initiator_id) + .collect::>() + }; + + let config = revolt_config::config().await; + + for user_id in call_recipients { + if let Ok(sessions) = self.authifier_db.find_sessions(&user_id).await { + for session in sessions { + if let Some(sub) = session.subscription { + let mut sendable = PayloadToService { + notification: PayloadKind::DmCallStartEnd(payload.clone()), + token: sub.auth, + user_id: session.user_id, + session_id: session.id, + extras: HashMap::new(), + }; + + let args: BasicPublishArguments; + + if sub.endpoint == "apn" { + args = BasicPublishArguments::new( + config.pushd.exchange.as_str(), + config.pushd.apn.queue.as_str(), + ) + .finish(); + } else if sub.endpoint == "fcm" { + args = BasicPublishArguments::new( + config.pushd.exchange.as_str(), + config.pushd.fcm.queue.as_str(), + ) + .finish(); + } else { + // web push (vapid) + args = BasicPublishArguments::new( + config.pushd.exchange.as_str(), + config.pushd.vapid.queue.as_str(), + ) + .finish(); + sendable.extras.insert("p265dh".to_string(), sub.p256dh); + sendable + .extras + .insert("endpoint".to_string(), sub.endpoint.clone()); + } + + let payload = serde_json::to_string(&sendable)?; + + publish_message(self, payload.into(), args).await; + } + } + } + } + + Ok(()) + } +} + +#[allow(unused_variables)] +#[async_trait] +impl AsyncConsumer for DmCallConsumer { + /// This consumer handles delegating messages into their respective platform queues. + async fn consume( + &mut self, + channel: &Channel, + deliver: Deliver, + basic_properties: BasicProperties, + content: Vec, + ) { + if let Err(err) = self + .consume_event(channel, deliver, basic_properties, content) + .await + { + revolt_config::capture_anyhow(&err); + warn!("Failed to process dm call start/stop event: {err:?}"); + } + } +} diff --git a/crates/daemons/pushd/src/consumers/inbound/mod.rs b/crates/daemons/pushd/src/consumers/inbound/mod.rs index 9c3593367..4d6d36b23 100644 --- a/crates/daemons/pushd/src/consumers/inbound/mod.rs +++ b/crates/daemons/pushd/src/consumers/inbound/mod.rs @@ -1,4 +1,5 @@ pub mod ack; +pub mod dm_call; pub mod fr_accepted; pub mod fr_received; pub mod generic; diff --git a/crates/daemons/pushd/src/consumers/outbound/apn.rs b/crates/daemons/pushd/src/consumers/outbound/apn.rs index 7cc43c76a..ec478c1f0 100644 --- a/crates/daemons/pushd/src/consumers/outbound/apn.rs +++ b/crates/daemons/pushd/src/consumers/outbound/apn.rs @@ -47,6 +47,32 @@ impl<'a> PayloadLike for MessagePayload<'a> { } } +#[derive(Serialize, Debug)] +struct CallStartStopPayload<'a> { + aps: APS<'a>, + #[serde(skip_serializing)] + options: NotificationOptions<'a>, + #[serde(skip_serializing)] + device_token: &'a str, + + initiator_id: &'a str, + #[serde(rename = "camelCase")] + channel_id: &'a str, + #[serde(rename = "camelCase")] + started_at: &'a str, + #[serde(rename = "camelCase")] + ended: bool, +} + +impl<'a> PayloadLike for CallStartStopPayload<'a> { + fn get_device_token(&self) -> &'a str { + self.device_token + } + fn get_options(&self) -> &NotificationOptions { + &self.options + } +} + // region: consumer pub struct ApnsOutboundConsumer { @@ -63,10 +89,11 @@ impl ApnsOutboundConsumer { // in a dm it should just be "Sendername". // not sure how feasible all those are given the PushNotification object as it currently stands. + #[allow(deprecated)] match ¬ification.channel { Channel::DirectMessage { .. } => notification.author.clone(), Channel::Group { name, .. } => format!("{}, #{}", notification.author, name), - Channel::TextChannel { name, .. } | Channel::VoiceChannel { name, .. } => { + Channel::TextChannel { name, .. } => { format!("{} in #{}", notification.author, name) } _ => "Unknown".to_string(), @@ -309,6 +336,7 @@ impl ApnsOutboundConsumer { ); resp = self.client.send(apn_payload).await; } + PayloadKind::BadgeUpdate(badge) => { let apn_payload = Payload { aps: APS { @@ -323,6 +351,35 @@ impl ApnsOutboundConsumer { debug!("Sending badge update for user: {:}", &payload.user_id); resp = self.client.send(apn_payload).await; } + + PayloadKind::DmCallStartEnd(alert) => { + let started_at = alert.started_at.map_or(String::new(), |f| f.clone()); + + let apn_payload = CallStartStopPayload { + aps: APS { + alert: None, + badge: self.get_badge_count(&payload.user_id).await, + sound: None, + thread_id: None, + content_available: None, + category: None, + mutable_content: Some(1), + url_args: None, + }, + device_token: &payload.token, + options: payload_options.clone(), + initiator_id: &alert.initiator_id, + channel_id: &alert.channel_id, + started_at: &started_at, + ended: alert.ended, + }; + + debug!( + "Sending call start/stop notification for user: {:}", + &payload.user_id + ); + resp = self.client.send(apn_payload).await; + } } if let Err(err) = resp { diff --git a/crates/daemons/pushd/src/consumers/outbound/fcm.rs b/crates/daemons/pushd/src/consumers/outbound/fcm.rs index 1e3f1d2ad..196a9eeac 100644 --- a/crates/daemons/pushd/src/consumers/outbound/fcm.rs +++ b/crates/daemons/pushd/src/consumers/outbound/fcm.rs @@ -5,11 +5,12 @@ use amqprs::{channel::Channel as AmqpChannel, consumer::AsyncConsumer, BasicProp use anyhow::{anyhow, bail, Result}; use async_trait::async_trait; use fcm_v1::{ - android::AndroidConfig, + android::{AndroidConfig, AndroidMessagePriority}, auth::{Authenticator, ServiceAccountKey}, message::{Message, Notification}, Client, Error as FcmError, }; +use revolt_config::config; use revolt_database::{events::rabbit::*, Database}; use revolt_models::v0::{Channel, PushNotification}; use serde_json::Value; @@ -27,10 +28,11 @@ impl FcmOutboundConsumer { // in a dm it should just be "Sendername". // not sure how feasible all those are given the PushNotification object as it currently stands. + #[allow(deprecated)] match ¬ification.channel { Channel::DirectMessage { .. } => notification.author.clone(), Channel::Group { name, .. } => format!("{}, #{}", notification.author, name), - Channel::TextChannel { name, .. } | Channel::VoiceChannel { name, .. } => { + Channel::TextChannel { name, .. } => { format!("{} in #{}", notification.author, name) } _ => "Unknown".to_string(), @@ -169,6 +171,37 @@ impl FcmOutboundConsumer { resp = self.client.send(&msg).await; } + PayloadKind::DmCallStartEnd(alert) => { + let mut data: HashMap = HashMap::new(); + data.insert( + "initiator_id".to_string(), + Value::String(alert.initiator_id), + ); + data.insert("channel_id".to_string(), Value::String(alert.channel_id)); + data.insert( + "started_at".to_string(), + Value::String(alert.started_at.unwrap_or_else(|| "".to_string())), + ); + data.insert("ended".to_string(), Value::Bool(alert.ended)); + + let msg = Message { + token: Some(payload.token), + notification: None, + data: Some(data), + android: Some(AndroidConfig { + priority: Some(AndroidMessagePriority::High), + ttl: Some(format!( + "{}s", + config().await.api.livekit.call_ring_duration + )), + ..Default::default() + }), + ..Default::default() + }; + + resp = self.client.send(&msg).await; + } + PayloadKind::BadgeUpdate(_) => { bail!("FCM cannot handle badge updates and they should not be sent here."); } diff --git a/crates/daemons/pushd/src/consumers/outbound/vapid.rs b/crates/daemons/pushd/src/consumers/outbound/vapid.rs index 92ce6e569..67ec31fb8 100644 --- a/crates/daemons/pushd/src/consumers/outbound/vapid.rs +++ b/crates/daemons/pushd/src/consumers/outbound/vapid.rs @@ -8,7 +8,7 @@ use base64::{ engine::{self}, Engine as _, }; -use revolt_database::{events::rabbit::*, Database}; +use revolt_database::{events::rabbit::*, util::format_display_name, Database}; use web_push::{ ContentEncoding, IsahcWebPushClient, SubscriptionInfo, SubscriptionKeys, VapidSignatureBuilder, WebPushClient, WebPushError, WebPushMessageBuilder, @@ -107,6 +107,33 @@ impl VapidOutboundConsumer { PayloadKind::MessageNotification(alert) => { payload_body = serde_json::to_string(&alert)?; } + PayloadKind::DmCallStartEnd(alert) => { + let initiator_name = if let Some(server_id) = + self.db.fetch_channel(&alert.channel_id).await?.server() + { + format_display_name(&self.db, &alert.initiator_id, Some(server_id)).await + } else { + format_display_name(&self.db, &alert.initiator_id, None).await + }?; + + let channel = self.db.fetch_channel(&alert.channel_id).await?; + let mut body = HashMap::new(); + + match channel { + revolt_database::Channel::DirectMessage { .. } => { + body.insert("body", format!("{} is calling you", initiator_name)); + } + revolt_database::Channel::Group { name, .. } => { + body.insert( + "body", + format!("{} is calling your group, {}", initiator_name, name), + ); + } + _ => bail!("Invalid DmCallStart/End channel type"), + } + + payload_body = serde_json::to_string(&body)?; + } PayloadKind::BadgeUpdate(_) => { bail!("Vapid cannot handle badge updates and they should not be sent here."); } diff --git a/crates/daemons/pushd/src/main.rs b/crates/daemons/pushd/src/main.rs index 78845a634..472caafe4 100644 --- a/crates/daemons/pushd/src/main.rs +++ b/crates/daemons/pushd/src/main.rs @@ -16,8 +16,9 @@ use tokio::sync::Notify; mod consumers; use consumers::{ inbound::{ - ack::AckConsumer, fr_accepted::FRAcceptedConsumer, fr_received::FRReceivedConsumer, - generic::GenericConsumer, mass_mention::MassMessageConsumer, message::MessageConsumer, + ack::AckConsumer, dm_call::DmCallConsumer, fr_accepted::FRAcceptedConsumer, + fr_received::FRReceivedConsumer, generic::GenericConsumer, + mass_mention::MassMessageConsumer, message::MessageConsumer, }, outbound::{apn::ApnsOutboundConsumer, fcm::FcmOutboundConsumer, vapid::VapidOutboundConsumer}, }; @@ -102,6 +103,7 @@ async fn main() { .await, ); + // inbound: Mass Mentions connections.push( make_queue_and_consume( &config, @@ -113,6 +115,18 @@ async fn main() { .await, ); + // inbound: Dm Calls + connections.push( + make_queue_and_consume( + &config, + &config.pushd.dm_call_queue, + config.pushd.get_dm_call_routing_key().as_str(), + None, + DmCallConsumer::new(db.clone(), authifier.clone()), + ) + .await, + ); + if !config.pushd.apn.pkcs8.is_empty() { connections.push( make_queue_and_consume( diff --git a/crates/daemons/voice-ingress/.gitignore b/crates/daemons/voice-ingress/.gitignore new file mode 100644 index 000000000..c41cc9e35 --- /dev/null +++ b/crates/daemons/voice-ingress/.gitignore @@ -0,0 +1 @@ +/target \ No newline at end of file diff --git a/crates/daemons/voice-ingress/Cargo.toml b/crates/daemons/voice-ingress/Cargo.toml new file mode 100644 index 000000000..3b9e69747 --- /dev/null +++ b/crates/daemons/voice-ingress/Cargo.toml @@ -0,0 +1,48 @@ +[package] +name = "revolt-voice-ingress" +version = "0.7.1" +license = "AGPL-3.0-or-later" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +# util +log = "*" +sentry = "0.31.5" +lru = "0.7.6" +ulid = "0.5.0" +redis-kiss = "0.1.4" +chrono = "0.4.15" + +# Serde +serde_json = "1.0.79" +rmp-serde = "1.0.0" +serde = "1.0.136" + +# Http +rocket = { version = "0.5.0-rc.2", features = ["json"] } +rocket_empty = "0.1.1" + +# Async +futures = "0.3.21" +async-std = { version = "1.8.0", features = [ + "tokio1", + "tokio02", + "attributes", +] } + +# Core +revolt-result = { path = "../../core/result" } +revolt-models = { path = "../../core/models" } +revolt-config = { path = "../../core/config" } +revolt-database = { path = "../../core/database", features = ["voice"] } +revolt-permissions = { path = "../../core/permissions" } + +# Voice +livekit-api = "0.4.4" +livekit-protocol = "0.4.0" +livekit-runtime = { version = "0.3.1", features = ["tokio"] } + +# RabbitMQ +amqprs = { version = "1.7.0" } diff --git a/crates/daemons/voice-ingress/Dockerfile b/crates/daemons/voice-ingress/Dockerfile new file mode 100644 index 000000000..18d82e4b4 --- /dev/null +++ b/crates/daemons/voice-ingress/Dockerfile @@ -0,0 +1,11 @@ +# Build Stage +FROM ghcr.io/stoatchat/base:latest AS builder +FROM debian:12 AS debian + +# Bundle Stage +FROM gcr.io/distroless/cc-debian12:nonroot +COPY --from=builder /home/rust/src/target/release/revolt-voice-ingress ./ +COPY --from=debian /usr/bin/uname /usr/bin/uname + +USER nonroot +CMD ["./revolt-voice-ingress"] \ No newline at end of file diff --git a/crates/daemons/voice-ingress/src/api.rs b/crates/daemons/voice-ingress/src/api.rs new file mode 100644 index 000000000..2af3ab267 --- /dev/null +++ b/crates/daemons/voice-ingress/src/api.rs @@ -0,0 +1,274 @@ +use livekit_api::{access_token::TokenVerifier, webhooks::WebhookReceiver}; +use livekit_protocol::TrackType; +use revolt_database::{ + events::client::EventV1, + iso8601_timestamp::{Duration, Timestamp}, + util::reference::Reference, + voice::{ + create_voice_state, delete_voice_state, + get_user_moved_from_voice, get_user_moved_to_voice, + update_voice_state_tracks, VoiceClient, + }, + Database, AMQP, +}; +use revolt_result::{Result, ToRevoltError}; +use rocket::{post, State}; +use rocket_empty::EmptyResponse; + +use crate::guard::AuthHeader; + +#[post("/", data = "")] +pub async fn ingress( + db: &State, + voice_client: &State, + _amqp: &State, + node: &str, + auth_header: AuthHeader<'_>, + body: &str, +) -> Result { + log::debug!("received event: {body:?}"); + + let config = revolt_config::config().await; + + let node_info = config + .api + .livekit + .nodes + .get(node) + .to_internal_error() + .inspect_err(|_| { + log::error!("Unknown node {node}, make sure livekit has the correct node name set and matches `hosts.livekit` and `api.livekit.nodes` in the Revolt config.") + })?; + + let webhook_receiver = WebhookReceiver::new(TokenVerifier::with_api_key( + &node_info.key, + &node_info.secret, + )); + + let event = webhook_receiver + .receive(body, &auth_header) + .to_internal_error()?; + + let channel_id = event.room.as_ref().map(|r| &r.name); + let user_id = event.participant.as_ref().map(|r| &r.identity); + + match event.event.as_str() { + // User joined a channel + "participant_joined" => { + let channel_id = channel_id.to_internal_error()?; + let user_id = user_id.to_internal_error()?; + + let channel = Reference::from_unchecked(channel_id).as_channel(db).await?; + + let joined_at = Timestamp::UNIX_EPOCH + .checked_add(Duration::seconds(event.created_at)) + .unwrap(); + + let voice_state = + create_voice_state(channel_id, channel.server(), user_id, joined_at).await?; + + // Only publish one event when a user is moved from one channel to another. + if let Some(moved_from) = get_user_moved_to_voice(channel_id, user_id).await? { + EventV1::VoiceChannelMove { + user: user_id.to_string(), + from: moved_from, + to: channel_id.to_string(), + state: voice_state, + } + .p(channel_id.to_string()) + .await; + } else { + EventV1::VoiceChannelJoin { + id: channel_id.to_string(), + state: voice_state, + } + .p(channel_id.to_string()) + .await; + }; + + // TODO: fix `num_participants` being incorrect sometimes see (#457) + // First user who joined - send call started system message. + // if event.room.as_ref().unwrap().num_participants == 1 { + // let user = Reference::from_unchecked(user_id).as_user(db).await?; + + // let message_id = + // Ulid::from_datetime(DateTime::from_timestamp_secs(event.created_at).unwrap()) + // .to_string(); + + // let mut call_started_message = SystemMessage::CallStarted { + // by: user_id.to_string(), + // finished_at: None, + // } + // .into_message(channel.id().to_string()); + + // call_started_message.id = message_id; + + // set_channel_call_started_system_message(channel.id(), &call_started_message.id) + // .await?; + + // call_started_message + // .send( + // db, + // Some(amqp), + // v0::MessageAuthor::System { + // username: &user.username, + // avatar: user.avatar.as_ref().map(|file| file.id.as_ref()), + // }, + // None, + // None, + // &channel, + // false, + // ) + // .await?; + + // let recipients = get_call_notification_recipients(&channel_id, &user_id).await?; + // let now = joined_at.format_short().to_string(); + + // if let Err(e) = amqp + // .dm_call_updated(&user.id, channel.id(), Some(&now), false, recipients) + // .await + // { + // revolt_config::capture_error(&e); + // } + // } + } + // User left a channel + "participant_left" => { + let channel_id = channel_id.to_internal_error()?; + let user_id = user_id.to_internal_error()?; + + let channel = Reference::from_unchecked(channel_id).as_channel(db).await?; + + delete_voice_state(channel_id, channel.server(), user_id).await?; + + // Dont send leave event when a user is moved + if get_user_moved_from_voice(channel_id, user_id) + .await? + .is_none() + { + EventV1::VoiceChannelLeave { + id: channel_id.clone(), + user: user_id.clone(), + } + .p(channel_id.clone()) + .await; + }; + + // See above for why this is commented out + + // // Update CallStarted system message if everyone has left with the end time + // let members = get_voice_channel_members(channel_id).await?; + + // if members.is_none_or(|m| m.is_empty()) { + // // The channel is empty so send out an "end" message for ringing + // if let Err(e) = amqp + // .dm_call_updated(user_id, channel_id, None, true, None) + // .await + // { + // revolt_config::capture_internal_error!(&e); + // } + + // if let Some(system_message_id) = + // take_channel_call_started_system_message(channel_id).await? + // { + // // Could have been deleted + // if let Ok(mut message) = Reference::from_unchecked(&system_message_id) + // .as_message(db) + // .await + // { + // if let Some(SystemMessage::CallStarted { finished_at, .. }) = + // &mut message.system + // { + // *finished_at = Some(Timestamp::now_utc()); + + // message + // .update( + // db, + // PartialMessage { + // system: message.system.clone(), + // ..Default::default() + // }, + // Vec::new(), + // ) + // .await?; + // } else { + // log::error!("Broken State: Call started message ID ({}) does not contain a CallStarted system message.", &message.id) + // } + // }; + // }; + // } + } + // Audio/video track was started/stopped/unmuted/muted + "track_published" | "track_unpublished" | "track_unmuted" | "track_muted" => { + let channel_id = channel_id.to_internal_error()?; + let user_id = user_id.to_internal_error()?; + let track = event.track.as_ref().to_internal_error()?; + + let channel = Reference::from_unchecked(channel_id).as_channel(db).await?; + + let user = Reference::from_unchecked(user_id).as_user(db).await?; + + let user_limits = user.limits().await; + + // forbid any size which goes over the limit and also limit the aspect ratio to stop people from making too tall or too wide and bypassing the limit. + // TODO: figure out how to track audio stream quality + + if event.event == "track_published" { + let mut disconnect = false; + + if track.r#type == TrackType::Data as i32 { + log::debug!("User published data"); + disconnect = true; + }; + + if track.r#type == TrackType::Video as i32 { + if user_limits.video_resolution[0] != 0 + && user_limits.video_resolution[1] != 0 + && track.width * track.height + > user_limits.video_resolution[0] * user_limits.video_resolution[1] + { + log::debug!("User published video with out of bounds resolution"); + disconnect = true; + }; + + if user_limits.video_aspect_ratio[0] != user_limits.video_aspect_ratio[1] + && !(user_limits.video_aspect_ratio[0]..=user_limits.video_aspect_ratio[1]) + .contains(&(track.width as f32 / track.height as f32)) + { + log::debug!("User published video with out of bounds aspect ratio"); + disconnect = true; + }; + }; + + if disconnect { + log::debug!("Removing user {user_id} from channel {channel_id} {event:?} due to forbidden track."); + + let _ = voice_client.remove_user(node, user_id, channel_id).await; + delete_voice_state(channel_id, channel.server(), user_id).await?; + + return Ok(EmptyResponse); + }; + }; + + let partial = update_voice_state_tracks( + channel_id, + channel.server(), + user_id, + event.event == "track_published" || event.event == "track_unmuted", // to avoid duplicating this entire case twice + track.source, + ) + .await?; + + EventV1::UserVoiceStateUpdate { + id: user_id.clone(), + channel_id: channel_id.clone(), + data: partial, + } + .p(channel_id.clone()) + .await; + } + _ => {} + }; + + Ok(EmptyResponse) +} diff --git a/crates/daemons/voice-ingress/src/guard.rs b/crates/daemons/voice-ingress/src/guard.rs new file mode 100644 index 000000000..f6ce11ddb --- /dev/null +++ b/crates/daemons/voice-ingress/src/guard.rs @@ -0,0 +1,28 @@ +use revolt_result::{create_error, Error}; +use rocket::{ + http::Status, + request::{FromRequest, Outcome}, + Request, +}; + +pub struct AuthHeader<'a>(&'a str); + +#[rocket::async_trait] +impl<'r> FromRequest<'r> for AuthHeader<'r> { + type Error = Error; + + async fn from_request(request: &'r Request<'_>) -> Outcome { + match request.headers().get("Authorization").next() { + Some(token) => Outcome::Success(Self(token)), + None => Outcome::Error((Status::Unauthorized, create_error!(NotAuthenticated))), + } + } +} + +impl std::ops::Deref for AuthHeader<'_> { + type Target = str; + + fn deref(&self) -> &Self::Target { + self.0 + } +} diff --git a/crates/daemons/voice-ingress/src/main.rs b/crates/daemons/voice-ingress/src/main.rs new file mode 100644 index 000000000..45191c2c5 --- /dev/null +++ b/crates/daemons/voice-ingress/src/main.rs @@ -0,0 +1,37 @@ +use std::env; + +use revolt_database::DatabaseInfo; +use revolt_database::{voice::VoiceClient, AMQP}; +use revolt_result::Result; +use rocket::{build, routes, Config}; +use std::net::Ipv4Addr; + +mod api; +mod guard; + +#[rocket::main] +async fn main() -> Result<(), rocket::Error> { + revolt_config::configure!(voice_ingress); + + let amqp = AMQP::new_auto().await; + + let database = DatabaseInfo::Auto.connect().await.unwrap(); + let voice_client = VoiceClient::from_revolt_config().await; + + let _rocket = build() + .manage(database) + .manage(voice_client) + .manage(amqp) + .mount("/", routes![api::ingress]) + .configure(Config { + port: 8500, + address: Ipv4Addr::new(0, 0, 0, 0).into(), + ..Default::default() + }) + .ignite() + .await? + .launch() + .await?; + + Ok(()) +} diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index fa4bc806f..fc4b1d49e 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -72,6 +72,7 @@ revolt-config = { path = "../core/config" } revolt-database = { path = "../core/database", features = [ "rocket-impl", "redis-is-patched", + "voice", ] } revolt-models = { path = "../core/models", features = [ "schemas", @@ -83,5 +84,9 @@ revolt-result = { path = "../core/result", features = ["rocket", "okapi"] } revolt-permissions = { path = "../core/permissions", features = ["schemas"] } revolt-ratelimits = { path = "../core/ratelimits", features = ["rocket"] } +# voice +livekit-api = "0.4.4" +livekit-protocol = "0.4.0" + [build-dependencies] vergen = "7.5.0" diff --git a/crates/delta/src/main.rs b/crates/delta/src/main.rs index 6d0eaa605..e7c060be7 100644 --- a/crates/delta/src/main.rs +++ b/crates/delta/src/main.rs @@ -25,6 +25,7 @@ use amqprs::{ use async_std::channel::unbounded; use authifier::AuthifierEvent; use rocket::data::ToByteUnit; +use revolt_database::voice::VoiceClient; pub async fn web() -> Rocket { // Get settings @@ -35,6 +36,7 @@ pub async fn web() -> Rocket { // Setup database let db = revolt_database::DatabaseInfo::Auto.connect().await.unwrap(); + log::info!("database_here {db:?}"); db.migrate_database().await.unwrap(); // Setup Authifier event channel @@ -90,6 +92,16 @@ pub async fn web() -> Rocket { ) .into(); + let swagger_0_8 = revolt_rocket_okapi::swagger_ui::make_swagger_ui( + &revolt_rocket_okapi::swagger_ui::SwaggerUIConfig { + url: "/0.8/openapi.json".to_owned(), + ..Default::default() + }, + ) + .into(); + + // Voice handler + let voice_client = VoiceClient::new(config.api.livekit.nodes.clone()); // Configure Rabbit let connection = Connection::open(&OpenConnectionArguments::new( &config.rabbit.host, @@ -137,6 +149,7 @@ pub async fn web() -> Rocket { .manage(db) .manage(amqp) .manage(cors.clone()) + .manage(voice_client) .manage(ratelimits) .attach(ratelimiter::RatelimitFairing) .attach(cors) diff --git a/crates/delta/src/routes/bots/delete.rs b/crates/delta/src/routes/bots/delete.rs index 4d4daefbe..73a001569 100644 --- a/crates/delta/src/routes/bots/delete.rs +++ b/crates/delta/src/routes/bots/delete.rs @@ -1,4 +1,4 @@ -use revolt_database::{util::reference::Reference, Database, User}; +use revolt_database::{Database, User, util::reference::Reference, voice::{VoiceClient, remove_user_from_voice_channels}}; use revolt_result::{create_error, Result}; use rocket::State; use rocket_empty::EmptyResponse; @@ -10,6 +10,7 @@ use rocket_empty::EmptyResponse; #[delete("/")] pub async fn delete_bot( db: &State, + voice_client: &State, user: User, target: Reference<'_>, ) -> Result { @@ -18,7 +19,11 @@ pub async fn delete_bot( return Err(create_error!(NotFound)); } - bot.delete(db).await.map(|_| EmptyResponse) + bot.delete(db).await?; + + remove_user_from_voice_channels(db, voice_client, &bot.id).await?; + + Ok(EmptyResponse) } #[cfg(test)] diff --git a/crates/delta/src/routes/channels/channel_delete.rs b/crates/delta/src/routes/channels/channel_delete.rs index 9d2b37b82..f6cc8b75a 100644 --- a/crates/delta/src/routes/channels/channel_delete.rs +++ b/crates/delta/src/routes/channels/channel_delete.rs @@ -1,6 +1,7 @@ use revolt_database::{ - util::{permissions::DatabasePermissionQuery, reference::Reference}, - Channel, Database, PartialChannel, User, AMQP, + AMQP, Channel, Database, PartialChannel, User, util::{permissions::DatabasePermissionQuery, reference::Reference}, voice::{ + VoiceClient, delete_voice_channel, is_in_voice_channel, remove_user_from_voice_channel + } }; use revolt_models::v0; use revolt_permissions::{calculate_channel_permissions, ChannelPermission}; @@ -15,6 +16,7 @@ use rocket_empty::EmptyResponse; #[delete("/?")] pub async fn delete( db: &State, + voice_client: &State, amqp: &State, user: User, target: Reference<'_>, @@ -26,34 +28,45 @@ pub async fn delete( permissions.throw_if_lacking_channel_permission(ChannelPermission::ViewChannel)?; + #[allow(deprecated)] match &channel { - Channel::SavedMessages { .. } => Err(create_error!(NoEffect)), - Channel::DirectMessage { .. } => channel - .update( - db, - PartialChannel { - active: Some(false), - ..Default::default() - }, - vec![], - ) - .await - .map(|_| EmptyResponse), - Channel::Group { .. } => channel - .remove_user_from_group( - db, - amqp, - &user, - None, - options.leave_silently.unwrap_or_default(), - ) - .await - .map(|_| EmptyResponse), - Channel::TextChannel { .. } | Channel::VoiceChannel { .. } => { + Channel::SavedMessages { .. } => Err(create_error!(NoEffect))?, + Channel::DirectMessage { .. } => { + channel + .update( + db, + PartialChannel { + active: Some(false), + ..Default::default() + }, + vec![], + ) + .await? + } + Channel::Group { .. } => { + channel + .remove_user_from_group( + db, + amqp, + &user, + None, + options.leave_silently.unwrap_or_default(), + ) + .await?; + + if is_in_voice_channel(&user.id, channel.id()).await? { + remove_user_from_voice_channel(db, voice_client, channel.id(), &user.id).await?; + }; + } + Channel::TextChannel { .. } => { permissions.throw_if_lacking_channel_permission(ChannelPermission::ManageChannel)?; - channel.delete(db).await.map(|_| EmptyResponse) + channel.delete(db).await?; + + delete_voice_channel(voice_client, channel.id(), channel.server()).await?; } - } + }; + + Ok(EmptyResponse) } #[cfg(test)] diff --git a/crates/delta/src/routes/channels/channel_edit.rs b/crates/delta/src/routes/channels/channel_edit.rs index 881656f60..64b3b06a4 100644 --- a/crates/delta/src/routes/channels/channel_edit.rs +++ b/crates/delta/src/routes/channels/channel_edit.rs @@ -1,5 +1,6 @@ use revolt_database::{ util::{permissions::DatabasePermissionQuery, reference::Reference}, + voice::{delete_voice_channel, VoiceClient}, Channel, Database, File, PartialChannel, SystemMessage, User, AMQP, }; use revolt_models::v0; @@ -15,6 +16,7 @@ use validator::Validate; #[patch("/", data = "")] pub async fn edit( db: &State, + voice_client: &State, amqp: &State, user: User, target: Reference<'_>, @@ -38,6 +40,7 @@ pub async fn edit( && data.icon.is_none() && data.nsfw.is_none() && data.owner.is_none() + && data.voice.is_none() && data.remove.is_empty() { return Ok(Json(channel.into())); @@ -95,22 +98,6 @@ pub async fn edit( icon, nsfw, .. - } - | Channel::TextChannel { - id, - name, - description, - icon, - nsfw, - .. - } - | Channel::VoiceChannel { - id, - name, - description, - icon, - nsfw, - .. } => { if data.remove.contains(&v0::FieldsChannel::Icon) { if let Some(icon) = &icon { @@ -151,73 +138,130 @@ pub async fn edit( } // Send out mutation system messages. - if let Channel::Group { .. } = &channel { - if let Some(name) = &partial.name { - SystemMessage::ChannelRenamed { - name: name.to_string(), - by: user.id.clone(), - } - .into_message(channel.id().to_string()) - .send( - db, - Some(amqp), - user.as_author_for_system(), - None, - None, - &channel, - false, - ) - .await - .ok(); + if let Some(name) = &partial.name { + SystemMessage::ChannelRenamed { + name: name.to_string(), + by: user.id.clone(), } + .into_message(channel.id().to_string()) + .send( + db, + Some(amqp), + user.as_author_for_system(), + None, + None, + &channel, + false, + ) + .await + .ok(); + } - if partial.description.is_some() { - SystemMessage::ChannelDescriptionChanged { - by: user.id.clone(), - } - .into_message(channel.id().to_string()) - .send( - db, - Some(amqp), - user.as_author_for_system(), - None, - None, - &channel, - false, - ) - .await - .ok(); + if partial.description.is_some() { + SystemMessage::ChannelDescriptionChanged { + by: user.id.clone(), } + .into_message(channel.id().to_string()) + .send( + db, + Some(amqp), + user.as_author_for_system(), + None, + None, + &channel, + false, + ) + .await + .ok(); + } - if partial.icon.is_some() { - SystemMessage::ChannelIconChanged { - by: user.id.clone(), + if partial.icon.is_some() { + SystemMessage::ChannelIconChanged { + by: user.id.clone(), + } + .into_message(channel.id().to_string()) + .send( + db, + Some(amqp), + user.as_author_for_system(), + None, + None, + &channel, + false, + ) + .await + .ok(); + } + } + Channel::TextChannel { + id, + name, + description, + icon, + nsfw, + voice, + .. + } => { + if data.remove.contains(&v0::FieldsChannel::Icon) { + if let Some(icon) = &icon { + db.mark_attachment_as_deleted(&icon.id).await?; + } + } + + for field in &data.remove { + match field { + v0::FieldsChannel::Description => { + description.take(); } - .into_message(channel.id().to_string()) - .send( - db, - Some(amqp), - user.as_author_for_system(), - None, - None, - &channel, - false, - ) - .await - .ok(); + v0::FieldsChannel::Icon => { + icon.take(); + } + v0::FieldsChannel::Voice => { + voice.take(); + } + _ => {} } } - channel - .update( - db, - partial, - data.remove.into_iter().map(|f| f.into()).collect(), - ) - .await?; + if let Some(icon_id) = data.icon { + partial.icon = Some(File::use_channel_icon(db, &icon_id, id, &user.id).await?); + *icon = partial.icon.clone(); + } + + if let Some(new_name) = data.name { + *name = new_name.clone(); + partial.name = Some(new_name); + } + + if let Some(new_description) = data.description { + partial.description = Some(new_description); + *description = partial.description.clone(); + } + + if let Some(new_nsfw) = data.nsfw { + *nsfw = new_nsfw; + partial.nsfw = Some(new_nsfw); + } + + if let Some(new_voice) = data.voice { + *voice = Some(new_voice.clone().into()); + partial.voice = Some(new_voice.into()); + } } _ => return Err(create_error!(InvalidOperation)), }; + channel + .update( + db, + partial, + data.remove.into_iter().map(|f| f.into()).collect(), + ) + .await?; + + if channel.voice().is_none() { + delete_voice_channel(voice_client, channel.id(), channel.server()).await?; + } + Ok(Json(channel.into())) } diff --git a/crates/delta/src/routes/channels/group_remove_member.rs b/crates/delta/src/routes/channels/group_remove_member.rs index 467168bac..995991f9a 100644 --- a/crates/delta/src/routes/channels/group_remove_member.rs +++ b/crates/delta/src/routes/channels/group_remove_member.rs @@ -1,4 +1,8 @@ -use revolt_database::{util::reference::Reference, Channel, Database, User, AMQP}; +use revolt_database::{ + util::reference::Reference, + voice::{is_in_voice_channel, remove_user_from_voice_channel, VoiceClient}, + Channel, Database, User, AMQP, +}; use revolt_permissions::ChannelPermission; use revolt_result::{create_error, Result}; @@ -12,6 +16,7 @@ use rocket_empty::EmptyResponse; #[delete("//recipients/")] pub async fn remove_member( db: &State, + voice_client: &State, amqp: &State, user: User, target: Reference<'_>, @@ -23,32 +28,37 @@ pub async fn remove_member( let channel = target.as_channel(db).await?; - match &channel { - Channel::Group { - owner, recipients, .. - } => { - if &user.id != owner { - return Err(create_error!(MissingPermission { - permission: ChannelPermission::ManageChannel.to_string() - })); - } - - let member = member.as_user(db).await?; - if user.id == member.id { - return Err(create_error!(CannotRemoveYourself)); - } - - if !recipients.iter().any(|x| *x == member.id) { - return Err(create_error!(NotInGroup)); - } - - channel - .remove_user_from_group(db, amqp, &member, Some(&user.id), false) - .await - .map(|_| EmptyResponse) + if let Channel::Group { + owner, recipients, .. + } = &channel + { + if &user.id != owner { + return Err(create_error!(MissingPermission { + permission: ChannelPermission::ManageChannel.to_string() + })); } - _ => Err(create_error!(InvalidOperation)), - } + + let member = member.as_user(db).await?; + if user.id == member.id { + return Err(create_error!(CannotRemoveYourself)); + } + + if !recipients.contains(&member.id) { + return Err(create_error!(NotInGroup)); + } + + channel + .remove_user_from_group(db, amqp, &member, Some(&user.id), false) + .await?; + } else { + return Err(create_error!(InvalidOperation)); + }; + + if is_in_voice_channel(&member.id, channel.id()).await? { + remove_user_from_voice_channel(db, voice_client, channel.id(), &member.id).await?; + }; + + Ok(EmptyResponse) } #[cfg(test)] diff --git a/crates/delta/src/routes/channels/message_query.rs b/crates/delta/src/routes/channels/message_query.rs index 27df85e42..ff66e3757 100644 --- a/crates/delta/src/routes/channels/message_query.rs +++ b/crates/delta/src/routes/channels/message_query.rs @@ -1,6 +1,6 @@ use revolt_database::{ util::{permissions::DatabasePermissionQuery, reference::Reference}, - Channel, Database, Message, MessageFilter, MessageQuery, MessageTimePeriod, User, + Database, Message, MessageFilter, MessageQuery, MessageTimePeriod, User, }; use revolt_models::v0::{self, MessageSort}; use revolt_permissions::{calculate_channel_permissions, ChannelPermission}; @@ -65,12 +65,7 @@ pub async fn query( }, &user, include_users, - match channel { - Channel::TextChannel { server, .. } | Channel::VoiceChannel { server, .. } => { - Some(server) - } - _ => None, - }, + channel.server(), ) .await .map(Json) diff --git a/crates/delta/src/routes/channels/message_search.rs b/crates/delta/src/routes/channels/message_search.rs index 85676823d..74bc20171 100644 --- a/crates/delta/src/routes/channels/message_search.rs +++ b/crates/delta/src/routes/channels/message_search.rs @@ -1,6 +1,6 @@ use revolt_database::{ util::{permissions::DatabasePermissionQuery, reference::Reference}, - Channel, Database, Message, MessageFilter, MessageQuery, MessageTimePeriod, User, + Database, Message, MessageFilter, MessageQuery, MessageTimePeriod, User, }; use revolt_models::v0; use revolt_permissions::{calculate_channel_permissions, ChannelPermission}; @@ -31,7 +31,7 @@ pub async fn search( })?; if options.query.is_some() && options.pinned.is_some() { - return Err(create_error!(InvalidOperation)) + return Err(create_error!(InvalidOperation)); } let channel = target.as_channel(db).await?; @@ -69,12 +69,7 @@ pub async fn search( }, &user, include_users, - match channel { - Channel::TextChannel { server, .. } | Channel::VoiceChannel { server, .. } => { - Some(server) - } - _ => None, - }, + channel.server(), ) .await .map(Json) diff --git a/crates/delta/src/routes/channels/message_send.rs b/crates/delta/src/routes/channels/message_send.rs index cb05f94bc..e0dac2765 100644 --- a/crates/delta/src/routes/channels/message_send.rs +++ b/crates/delta/src/routes/channels/message_send.rs @@ -151,6 +151,7 @@ mod test { name: "Hidden Channel".to_string(), description: None, nsfw: Some(false), + voice: None }, true, ) @@ -193,6 +194,7 @@ mod test { d: ChannelPermission::ViewChannel as i64, }), last_message_id: None, + voice: None, }; locked_channel .update(&harness.db, partial, vec![]) @@ -287,6 +289,8 @@ mod test { avatar: None, timeout: None, roles: Some(second_member_roles), + can_publish: None, + can_receive: None }; second_member .update(&harness.db, partial, vec![]) @@ -613,6 +617,8 @@ mod test { nickname: None, roles: Some(vec![role_id.clone()]), timeout: None, + can_publish: None, + can_receive: None }, vec![], ) diff --git a/crates/delta/src/routes/channels/mod.rs b/crates/delta/src/routes/channels/mod.rs index c57fbaa88..5d3fbc850 100644 --- a/crates/delta/src/routes/channels/mod.rs +++ b/crates/delta/src/routes/channels/mod.rs @@ -25,6 +25,7 @@ mod message_unreact; mod permissions_set; mod permissions_set_default; mod voice_join; +mod voice_stop_ring; mod webhook_create; mod webhook_fetch_all; @@ -49,6 +50,7 @@ pub fn routes() -> (Vec, OpenApi) { group_add_member::add_member, group_remove_member::remove_member, voice_join::call, + voice_stop_ring::stop_ring, permissions_set::set_role_permissions, permissions_set_default::set_default_channel_permissions, message_react::react_message, diff --git a/crates/delta/src/routes/channels/permissions_set.rs b/crates/delta/src/routes/channels/permissions_set.rs index ee42e403d..545f6bb8d 100644 --- a/crates/delta/src/routes/channels/permissions_set.rs +++ b/crates/delta/src/routes/channels/permissions_set.rs @@ -1,6 +1,5 @@ use revolt_database::{ - util::{permissions::DatabasePermissionQuery, reference::Reference}, - Database, User, + util::{permissions::DatabasePermissionQuery, reference::Reference}, voice::{sync_voice_permissions, VoiceClient}, Database, User }; use revolt_models::v0; use revolt_permissions::{calculate_channel_permissions, ChannelPermission, Override}; @@ -11,19 +10,20 @@ use rocket::{serde::json::Json, State}; /// /// Sets permissions for the specified role in this channel. /// -/// Channel must be a `TextChannel` or `VoiceChannel`. +/// Channel must be a `TextChannel`. #[openapi(tag = "Channel Permissions")] #[put("//permissions/", data = "", rank = 2)] pub async fn set_role_permissions( db: &State, + voice_client: &State, user: User, target: Reference<'_>, role_id: String, data: Json, ) -> Result> { - let mut channel = target.as_channel(db).await?; + let channel = target.as_channel(db).await?; let mut query = DatabasePermissionQuery::new(db, &user).channel(&channel); - let permissions = calculate_channel_permissions(&mut query).await; + let permissions: revolt_permissions::PermissionValue = calculate_channel_permissions(&mut query).await; permissions.throw_if_lacking_channel_permission(ChannelPermission::ManagePermissions)?; @@ -38,11 +38,15 @@ pub async fn set_role_permissions( .throw_permission_override(current_value, &data.permissions) .await?; - channel + let mut new_channel = channel.clone(); + + new_channel .set_role_permission(db, &role_id, data.permissions.clone().into()) .await?; - Ok(Json(channel.into())) + sync_voice_permissions(db, voice_client, &new_channel, Some(server), Some(&role_id)).await?; + + Ok(Json(new_channel.into())) } else { Err(create_error!(NotFound)) } diff --git a/crates/delta/src/routes/channels/permissions_set_default.rs b/crates/delta/src/routes/channels/permissions_set_default.rs index 700b29e42..ad14a88ea 100644 --- a/crates/delta/src/routes/channels/permissions_set_default.rs +++ b/crates/delta/src/routes/channels/permissions_set_default.rs @@ -1,6 +1,5 @@ use revolt_database::{ - util::{permissions::DatabasePermissionQuery, reference::Reference}, - Channel, Database, PartialChannel, User, + util::{permissions::DatabasePermissionQuery, reference::Reference}, voice::{sync_voice_permissions, VoiceClient}, Channel, Database, PartialChannel, User }; use revolt_models::v0::{self, DataDefaultChannelPermissions}; use revolt_permissions::{calculate_channel_permissions, ChannelPermission}; @@ -11,11 +10,12 @@ use rocket::{serde::json::Json, State}; /// /// Sets permissions for the default role in this channel. /// -/// Channel must be a `Group`, `TextChannel` or `VoiceChannel`. +/// Channel must be a `Group` or `TextChannel`. #[openapi(tag = "Channel Permissions")] #[put("//permissions/default", data = "", rank = 1)] pub async fn set_default_channel_permissions( db: &State, + voice_client: &State, user: User, target: Reference<'_>, data: Json, @@ -48,10 +48,6 @@ pub async fn set_default_channel_permissions( Channel::TextChannel { default_permissions, .. - } - | Channel::VoiceChannel { - default_permissions, - .. } => { if let DataDefaultChannelPermissions::Field { permissions: field } = data { permissions @@ -75,5 +71,12 @@ pub async fn set_default_channel_permissions( _ => return Err(create_error!(InvalidOperation)), } + let server = match channel.server() { + Some(server_id) => Some(Reference::from_unchecked(server_id).as_server(db).await?), + None => None + }; + + sync_voice_permissions(db, voice_client, &channel, server.as_ref(), None).await?; + Ok(Json(channel.into())) } diff --git a/crates/delta/src/routes/channels/voice_join.rs b/crates/delta/src/routes/channels/voice_join.rs index c04e00118..670c5032e 100644 --- a/crates/delta/src/routes/channels/voice_join.rs +++ b/crates/delta/src/routes/channels/voice_join.rs @@ -1,105 +1,115 @@ use revolt_config::config; use revolt_database::{ - util::{permissions::DatabasePermissionQuery, reference::Reference}, - Channel, Database, User, + util::{permissions::perms, reference::Reference}, + voice::{ + delete_voice_state, get_channel_node, get_user_voice_channels, get_voice_channel_members, + raise_if_in_voice, set_call_notification_recipients, VoiceClient, + }, + Database, User, }; use revolt_models::v0; use revolt_permissions::{calculate_channel_permissions, ChannelPermission}; use revolt_result::{create_error, Result}; + use rocket::{serde::json::Json, State}; /// # Join Call /// /// Asks the voice server for a token to join the call. #[openapi(tag = "Voice")] -#[post("//join_call")] +#[post("//join_call", data = "")] pub async fn call( db: &State, + voice_client: &State, user: User, target: Reference<'_>, -) -> Result> { + data: Json, +) -> Result> { + if !voice_client.is_enabled() { + return Err(create_error!(LiveKitUnavailable)); + } + + let v0::DataJoinCall { + node, + force_disconnect, + recipients, + } = data.into_inner(); + + if user.bot.is_some() && force_disconnect == Some(true) { + return Err(create_error!(IsBot)); + } + let channel = target.as_channel(db).await?; - let mut query = DatabasePermissionQuery::new(db, &user).channel(&channel); - calculate_channel_permissions(&mut query) - .await - .throw_if_lacking_channel_permission(ChannelPermission::Connect)?; - let config = config().await; - if config.api.security.voso_legacy_token.is_empty() { - return Err(create_error!(VosoUnavailable)); + let Some(voice_info) = channel.voice() else { + return Err(create_error!(NotAVoiceChannel)); + }; + + let mut permissions = perms(db, &user).channel(&channel); + + let current_permissions = calculate_channel_permissions(&mut permissions).await; + current_permissions.throw_if_lacking_channel_permission(ChannelPermission::Connect)?; + + if get_voice_channel_members(channel.id()) + .await? + .zip(voice_info.max_users) + .is_some_and(|(ms, max_users)| ms.len() >= max_users) + && !current_permissions.has(ChannelPermission::ManageChannel as u64) + { + return Err(create_error!(CannotJoinCall)); } - match channel { - Channel::SavedMessages { .. } | Channel::TextChannel { .. } => { - return Err(create_error!(CannotJoinCall)) + let existing_node = get_channel_node(channel.id()).await?; + + let node = existing_node + .or(node) + .ok_or_else(|| create_error!(UnknownNode))?; + + let config = config().await; + + let node_host = config + .hosts + .livekit + .get(&node) + .ok_or_else(|| create_error!(UnknownNode))? + .clone(); + + if force_disconnect == Some(true) { + // Finds and disconnects any existing voice connections by the user, + // should only ever loop once but just to cover our backs. + + for channel_id in get_user_voice_channels(&user.id).await? { + if let Some(node) = get_channel_node(&channel_id).await? { + // if this errors its just a mismatching state - ignore and proceed to still delete our state + let _ = voice_client.remove_user(&node, &user.id, &channel_id).await; + }; + + let channel = Reference::from_unchecked(&channel_id) + .as_channel(db) + .await?; + + delete_voice_state(&channel_id, channel.server(), &user.id).await?; } - _ => {} + } else { + raise_if_in_voice(&user, channel.id()).await?; } - // To join a call: - // - Check if the room exists. - // - If not, create it. - let client = reqwest::Client::new(); - let result = client - .get(format!( - "{}/room/{}", - config.hosts.voso_legacy, - channel.id() - )) - .header( - reqwest::header::AUTHORIZATION, - config.api.security.voso_legacy_token.clone(), - ) - .send() - .await; - - match result { - Err(_) => return Err(create_error!(VosoUnavailable)), - Ok(result) => match result.status() { - reqwest::StatusCode::OK => (), - reqwest::StatusCode::NOT_FOUND => { - if (client - .post(format!( - "{}/room/{}", - config.hosts.voso_legacy, - channel.id() - )) - .header( - reqwest::header::AUTHORIZATION, - config.api.security.voso_legacy_token.clone(), - ) - .send() - .await) - .is_err() - { - return Err(create_error!(VosoUnavailable)); - } - } - _ => return Err(create_error!(VosoUnavailable)), - }, - } + let token = voice_client + .create_token(&node, db, &user, current_permissions, &channel) + .await?; - // Then create a user for the room. - if let Ok(response) = client - .post(format!( - "{}/room/{}/user/{}", - config.hosts.voso_legacy, - channel.id(), - user.id - )) - .header( - reqwest::header::AUTHORIZATION, - config.api.security.voso_legacy_token, - ) - .send() - .await - { - response - .json() - .await - .map_err(|_| create_error!(InvalidOperation)) - .map(Json) - } else { - Err(create_error!(VosoUnavailable)) + let room = voice_client.create_room(&node, &channel).await?; + + log::debug!("Created room {}", room.name); + + if let Some(recipients) = recipients { + if room.num_participants == 0 && !recipients.is_empty() { + set_call_notification_recipients(channel.id(), &user.id, &recipients).await?; + } } + + Ok(Json(v0::CreateVoiceUserResponse { + token, + url: node_host.clone(), + })) } diff --git a/crates/delta/src/routes/channels/voice_stop_ring.rs b/crates/delta/src/routes/channels/voice_stop_ring.rs new file mode 100644 index 000000000..f8db8fc44 --- /dev/null +++ b/crates/delta/src/routes/channels/voice_stop_ring.rs @@ -0,0 +1,69 @@ +use revolt_database::{ + util::reference::Reference, + voice::{get_voice_state, VoiceClient}, + Channel, Database, User, AMQP, +}; +use revolt_result::{create_error, Result, ToRevoltError}; + +use rocket::State; +use rocket_empty::EmptyResponse; + +/// # Stop Ring +/// Stops ringing a specific user in a dm call. +/// You must be in the call to use this endpoint, returns NotConnected otherwise. +/// Only valid in DM/Group channels, will return NoEffect in servers. +/// Returns NotFound if the user is not in the dm/group channel +#[openapi(tag = "Voice")] +#[put("//end_ring/")] +pub async fn stop_ring( + db: &State, + amqp: &State, + voice: &State, + user: User, + target: Reference<'_>, + target_user: Reference<'_>, +) -> Result { + if !voice.is_enabled() { + return Err(create_error!(LiveKitUnavailable)); + } + + let channel = target.as_channel(db).await?; + if channel.server().is_some() { + return Err(create_error!(NoEffect)); + } + + if get_voice_state(channel.id(), None, &user.id) + .await? + .is_none() + { + return Err(create_error!(NotConnected)); + } + + let members = match channel { + Channel::DirectMessage { ref recipients, .. } | Channel::Group { ref recipients, .. } => { + recipients + } + _ => return Err(create_error!(NoEffect)), + }; + + if members.iter().any(|m| &target_user.id == m) { + if let Err(e) = amqp + .dm_call_updated( + &user.id, + channel.id(), + None, + true, + Some(vec![target_user.id.to_string()]), + ) + .await + .to_internal_error() + { + revolt_config::capture_internal_error!(&e); + return Err(e); + } + + Ok(EmptyResponse) + } else { + Err(create_error!(NotFound)) + } +} diff --git a/crates/delta/src/routes/invites/invite_fetch.rs b/crates/delta/src/routes/invites/invite_fetch.rs index 7c44d4ae6..7c1b7550c 100644 --- a/crates/delta/src/routes/invites/invite_fetch.rs +++ b/crates/delta/src/routes/invites/invite_fetch.rs @@ -23,13 +23,6 @@ pub async fn fetch(db: &State, target: Reference<'_>) -> Result { let server = db.fetch_server(&server).await?; @@ -202,6 +195,7 @@ mod test { name: "Voice Channel".to_string(), description: None, nsfw: Some(false), + voice: None }, true, ) diff --git a/crates/delta/src/routes/root.rs b/crates/delta/src/routes/root.rs index c90c53c0b..3ddbfcc7c 100644 --- a/crates/delta/src/routes/root.rs +++ b/crates/delta/src/routes/root.rs @@ -21,15 +21,22 @@ pub struct Feature { pub url: String, } +/// # Information about a livekit node +#[derive(Serialize, JsonSchema, Debug)] +pub struct VoiceNode { + pub name: String, + pub lat: f64, + pub lon: f64, + pub public_url: String, +} + /// # Voice Server Configuration #[derive(Serialize, JsonSchema, Debug)] pub struct VoiceFeature { /// Whether voice is enabled pub enabled: bool, - /// URL pointing to the voice API - pub url: String, - /// URL pointing to the voice WebSocket server - pub ws: String, + /// All livekit nodes + pub nodes: Vec, } /// # Feature Configuration @@ -46,7 +53,7 @@ pub struct RevoltFeatures { /// Proxy service configuration pub january: Feature, /// Voice server configuration - pub voso: VoiceFeature, + pub livekit: VoiceFeature, } /// # Build Information @@ -94,22 +101,38 @@ pub async fn root() -> Result> { features: RevoltFeatures { captcha: CaptchaFeature { enabled: !config.api.security.captcha.hcaptcha_key.is_empty(), - key: config.api.security.captcha.hcaptcha_sitekey, + key: config.api.security.captcha.hcaptcha_sitekey.clone(), }, email: !config.api.smtp.host.is_empty(), invite_only: config.api.registration.invite_only, autumn: Feature { enabled: !config.hosts.autumn.is_empty(), - url: config.hosts.autumn, + url: config.hosts.autumn.clone(), }, january: Feature { enabled: !config.hosts.january.is_empty(), - url: config.hosts.january, + url: config.hosts.january.clone(), }, - voso: VoiceFeature { - enabled: !config.hosts.voso_legacy.is_empty(), - url: config.hosts.voso_legacy, - ws: config.hosts.voso_legacy_ws, + livekit: VoiceFeature { + enabled: !config.hosts.livekit.is_empty(), + nodes: config + .api + .livekit + .nodes + .iter() + .filter(|(_, node)| !node.private) + .map(|(name, value)| VoiceNode { + name: name.clone(), + lat: value.lat, + lon: value.lon, + public_url: config + .hosts + .livekit + .get(name) + .expect("Missing corresponding host for voice node") + .clone(), + }) + .collect(), }, }, ws: config.hosts.events, diff --git a/crates/delta/src/routes/servers/ban_create.rs b/crates/delta/src/routes/servers/ban_create.rs index 13c0ef3b3..17589dad2 100644 --- a/crates/delta/src/routes/servers/ban_create.rs +++ b/crates/delta/src/routes/servers/ban_create.rs @@ -1,5 +1,6 @@ use revolt_database::{ util::{permissions::DatabasePermissionQuery, reference::Reference}, + voice::{get_user_voice_channel_in_server, remove_user_from_voice_channel, VoiceClient}, Database, RemovalIntention, ServerBan, User, }; use revolt_models::v0; @@ -16,6 +17,7 @@ use validator::Validate; #[put("//bans/", data = "")] pub async fn ban( db: &State, + voice_client: &State, user: User, server: Reference<'_>, target: Reference<'_>, @@ -54,6 +56,11 @@ pub async fn ban( member .remove(db, &server, RemovalIntention::Ban, false) .await?; + + // If the member is in a voice channel while banned kick them from the voice channel + if let Some(channel_id) = get_user_voice_channel_in_server(&target.id, &server.id).await? { + remove_user_from_voice_channel(db, voice_client, &channel_id, &target.id).await?; + } } ServerBan::create(db, &server, target.id, data.reason) diff --git a/crates/delta/src/routes/servers/member_edit.rs b/crates/delta/src/routes/servers/member_edit.rs index 74ac5d72a..458c10bae 100644 --- a/crates/delta/src/routes/servers/member_edit.rs +++ b/crates/delta/src/routes/servers/member_edit.rs @@ -1,14 +1,25 @@ use std::collections::HashSet; use revolt_database::{ - util::{permissions::DatabasePermissionQuery, reference::Reference}, + events::client::EventV1, + util::{ + permissions::{perms, DatabasePermissionQuery}, + reference::Reference, + }, + voice::{ + get_channel_node, get_user_voice_channel_in_server, set_channel_node, + set_user_moved_from_voice, set_user_moved_to_voice, sync_user_voice_permissions, + VoiceClient, + }, Database, File, PartialMember, User, }; -use revolt_models::v0; +use revolt_models::v0::{self, FieldsMember}; -use revolt_permissions::{calculate_server_permissions, ChannelPermission}; +use revolt_permissions::{ + calculate_channel_permissions, calculate_server_permissions, ChannelPermission, +}; use revolt_result::{create_error, Result}; -use rocket::{serde::json::Json, State}; +use rocket::{form::validate::Contains, serde::json::Json, State}; use validator::Validate; /// # Edit Member @@ -18,6 +29,7 @@ use validator::Validate; #[patch("//members/", data = "")] pub async fn edit( db: &State, + voice_client: &State, user: User, server: Reference<'_>, member: Reference<'_>, @@ -78,6 +90,44 @@ pub async fn edit( permissions.throw_if_lacking_channel_permission(ChannelPermission::TimeoutMembers)?; } + if data.can_publish.is_some() { + permissions.throw_if_lacking_channel_permission(ChannelPermission::MuteMembers)?; + } + + if data.can_receive.is_some() { + permissions.throw_if_lacking_channel_permission(ChannelPermission::DeafenMembers)?; + } + + let new_voice_channel = if let Some(new_channel) = &data.voice_channel { + if !voice_client.is_enabled() { + return Err(create_error!(LiveKitUnavailable)); + }; + + permissions.throw_if_lacking_channel_permission(ChannelPermission::MoveMembers)?; + + // ensure the channel we are moving them to is in the server and is a voice channel + + let channel = Reference::from_unchecked(new_channel) + .as_channel(db) + .await + .map_err(|_| create_error!(UnknownChannel))?; + + if channel.server().is_none_or(|v| v != member.id.server) { + Err(create_error!(UnknownChannel))? + } + + if get_user_voice_channel_in_server(&target_user.id, &server.id) + .await? + .is_none() + { + Err(create_error!(NotConnected))? + }; + + Some(channel) + } else { + None + }; + // Resolve our ranking let our_ranking = query.get_member_rank().unwrap_or(i64::MIN); @@ -113,12 +163,17 @@ pub async fn edit( roles, timeout, remove, + can_publish, + can_receive, + voice_channel: _, } = data; let mut partial = PartialMember { nickname, roles, timeout, + can_publish, + can_receive, ..Default::default() }; @@ -134,9 +189,69 @@ pub async fn edit( partial.avatar = Some(File::use_user_avatar(db, &avatar, &user.id, &user.id).await?); } + let remove_contains_voice = remove.contains(FieldsMember::CanPublish) || remove.contains(FieldsMember::CanReceive); + member .update(db, partial, remove.into_iter().map(Into::into).collect()) .await?; + if let Some(new_voice_channel) = new_voice_channel { + if let Some(channel) = get_user_voice_channel_in_server(&target_user.id, &server.id).await? + { + let old_node = get_channel_node(&channel).await?.unwrap(); + + let new_node = match get_channel_node(new_voice_channel.id()).await? { + Some(node) => node, + None => { + set_channel_node(new_voice_channel.id(), &old_node).await?; + old_node.clone() + } + }; + + set_user_moved_from_voice(&channel, new_voice_channel.id(), &target_user.id).await?; + set_user_moved_to_voice(new_voice_channel.id(), &channel, &target_user.id).await?; + + let mut query = perms(db, &target_user).channel(&new_voice_channel); + let permissions = calculate_channel_permissions(&mut query).await; + + voice_client + .create_room(&new_node, &new_voice_channel) + .await?; + let token = voice_client + .create_token(&new_node, db, &target_user, permissions, &new_voice_channel) + .await?; + + voice_client + .remove_user(&old_node, &target_user.id, &channel) + .await?; + + EventV1::UserMoveVoiceChannel { + node: new_node, + from: channel, + to: new_voice_channel.id().to_string(), + token, + } + .private(target_user.id.clone()) + .await; + }; + } else if can_publish.is_some() || can_receive.is_some() || remove_contains_voice { + if let Some(channel) = get_user_voice_channel_in_server(&target_user.id, &server.id).await? + { + let node = get_channel_node(&channel).await?.unwrap(); + let channel = Reference::from_unchecked(&channel).as_channel(db).await?; + + sync_user_voice_permissions( + db, + voice_client, + &node, + &user, + &channel, + Some(&server), + None, + ) + .await?; + }; + }; + Ok(Json(member.into())) } diff --git a/crates/delta/src/routes/servers/member_remove.rs b/crates/delta/src/routes/servers/member_remove.rs index 230042671..510da42ed 100644 --- a/crates/delta/src/routes/servers/member_remove.rs +++ b/crates/delta/src/routes/servers/member_remove.rs @@ -1,5 +1,6 @@ use revolt_database::{ util::{permissions::DatabasePermissionQuery, reference::Reference}, + voice::{get_user_voice_channel_in_server, remove_user_from_voice_channel, VoiceClient}, Database, RemovalIntention, User, }; use revolt_permissions::{calculate_server_permissions, ChannelPermission}; @@ -14,6 +15,7 @@ use rocket_empty::EmptyResponse; #[delete("//members/")] pub async fn kick( db: &State, + voice_client: &State, user: User, target: Reference<'_>, member: Reference<'_>, @@ -42,6 +44,11 @@ pub async fn kick( member .remove(db, &server, RemovalIntention::Kick, false) - .await - .map(|_| EmptyResponse) + .await?; + + if let Some(channel_id) = get_user_voice_channel_in_server(&target.id, &server.id).await? { + remove_user_from_voice_channel(db, voice_client, &channel_id, &target.id).await?; + }; + + Ok(EmptyResponse) } diff --git a/crates/delta/src/routes/servers/permissions_set.rs b/crates/delta/src/routes/servers/permissions_set.rs index f0d8099fd..41979a61b 100644 --- a/crates/delta/src/routes/servers/permissions_set.rs +++ b/crates/delta/src/routes/servers/permissions_set.rs @@ -1,5 +1,6 @@ use revolt_database::{ util::{permissions::DatabasePermissionQuery, reference::Reference}, + voice::{sync_voice_permissions, VoiceClient}, Database, User, }; use revolt_models::v0; @@ -14,6 +15,7 @@ use rocket::{serde::json::Json, State}; #[put("//permissions/", data = "", rank = 2)] pub async fn set_role_permission( db: &State, + voice_client: &State, user: User, target: Reference<'_>, role_id: String, @@ -22,30 +24,38 @@ pub async fn set_role_permission( let data = data.into_inner(); let mut server = target.as_server(db).await?; - if let Some((current_value, rank)) = server.roles.get(&role_id).map(|x| (x.permissions, x.rank)) - { - let mut query = DatabasePermissionQuery::new(db, &user).server(&server); - let permissions = calculate_server_permissions(&mut query).await; - - permissions.throw_if_lacking_channel_permission(ChannelPermission::ManagePermissions)?; - - // Prevent us from editing roles above us - if rank <= query.get_member_rank().unwrap_or(i64::MIN) { - return Err(create_error!(NotElevated)); - } - - // Ensure we have access to grant these permissions forwards - let current_value: Override = current_value.into(); - permissions - .throw_permission_override(current_value, &data.permissions) - .await?; - - server - .set_role_permission(db, &role_id, data.permissions.into()) - .await?; - - Ok(Json(server.into())) - } else { - Err(create_error!(NotFound)) + + let (current_value, rank) = server + .roles + .get(&role_id) + .map(|x| (x.permissions, x.rank)) + .ok_or_else(|| create_error!(NotFound))?; + + let mut query = DatabasePermissionQuery::new(db, &user).server(&server); + let permissions = calculate_server_permissions(&mut query).await; + + permissions.throw_if_lacking_channel_permission(ChannelPermission::ManagePermissions)?; + + // Prevent us from editing roles above us + if rank <= query.get_member_rank().unwrap_or(i64::MIN) { + return Err(create_error!(NotElevated)); } + + // Ensure we have access to grant these permissions forwards + let current_value: Override = current_value.into(); + permissions + .throw_permission_override(current_value, &data.permissions) + .await?; + + server + .set_role_permission(db, &role_id, data.permissions.into()) + .await?; + + for channel_id in &server.channels { + let channel = Reference::from_unchecked(channel_id).as_channel(db).await?; + + sync_voice_permissions(db, voice_client, &channel, Some(&server), Some(&role_id)).await?; + }; + + Ok(Json(server.into())) } diff --git a/crates/delta/src/routes/servers/permissions_set_default.rs b/crates/delta/src/routes/servers/permissions_set_default.rs index 6ee5b8135..bf9dd3048 100644 --- a/crates/delta/src/routes/servers/permissions_set_default.rs +++ b/crates/delta/src/routes/servers/permissions_set_default.rs @@ -1,6 +1,5 @@ use revolt_database::{ - util::{permissions::DatabasePermissionQuery, reference::Reference}, - Database, PartialServer, User, + util::{permissions::DatabasePermissionQuery, reference::Reference}, voice::{sync_voice_permissions, VoiceClient}, Database, PartialServer, User }; use revolt_models::v0; use revolt_permissions::{ @@ -16,6 +15,7 @@ use rocket::{serde::json::Json, State}; #[put("//permissions/default", data = "", rank = 1)] pub async fn set_default_server_permissions( db: &State, + voice_client: &State, user: User, target: Reference<'_>, data: Json, @@ -50,5 +50,11 @@ pub async fn set_default_server_permissions( ) .await?; + for channel_id in &server.channels { + let channel = Reference::from_unchecked(channel_id).as_channel(db).await?; + + sync_voice_permissions(db, voice_client, &channel, Some(&server), None).await?; + }; + Ok(Json(server.into())) } diff --git a/crates/delta/src/routes/servers/roles_delete.rs b/crates/delta/src/routes/servers/roles_delete.rs index 6867b647f..77df2501d 100644 --- a/crates/delta/src/routes/servers/roles_delete.rs +++ b/crates/delta/src/routes/servers/roles_delete.rs @@ -1,5 +1,6 @@ use revolt_database::{ util::{permissions::DatabasePermissionQuery, reference::Reference}, + voice::{sync_voice_permissions, VoiceClient}, Database, User, }; use revolt_permissions::{calculate_server_permissions, ChannelPermission}; @@ -17,6 +18,7 @@ pub async fn delete( user: User, target: Reference<'_>, role_id: String, + voice_client: &State, ) -> Result { let mut server = target.as_server(db).await?; let mut query = DatabasePermissionQuery::new(db, &user).server(&server); @@ -26,15 +28,22 @@ pub async fn delete( let member_rank = query.get_member_rank().unwrap_or(i64::MIN); - if let Some(role) = server.roles.remove(&role_id) { - if role.rank <= member_rank { - return Err(create_error!(NotElevated)); - } + let role = server + .roles + .remove(&role_id) + .ok_or_else(|| create_error!(NotFound))?; - role.delete(db, &server.id, &role_id) - .await - .map(|_| EmptyResponse) - } else { - Err(create_error!(NotFound)) + if role.rank <= member_rank { + return Err(create_error!(NotElevated)); } + + role.delete(db, &server.id, &role_id).await?; + + for channel_id in &server.channels { + let channel = Reference::from_unchecked(channel_id).as_channel(db).await?; + + sync_voice_permissions(db, voice_client, &channel, Some(&server), Some(&role_id)).await?; + } + + Ok(EmptyResponse) } diff --git a/crates/delta/src/routes/servers/roles_edit.rs b/crates/delta/src/routes/servers/roles_edit.rs index f18bd7d33..639589afa 100644 --- a/crates/delta/src/routes/servers/roles_edit.rs +++ b/crates/delta/src/routes/servers/roles_edit.rs @@ -1,6 +1,7 @@ use revolt_database::{ util::{permissions::DatabasePermissionQuery, reference::Reference}, - Database, PartialRole, User, + voice::{sync_voice_permissions, VoiceClient}, + Database, PartialRole, User }; use revolt_models::v0; use revolt_permissions::{calculate_server_permissions, ChannelPermission}; @@ -15,6 +16,7 @@ use validator::Validate; #[patch("//roles/", data = "", rank = 1)] pub async fn edit( db: &State, + voice_client: &State, user: User, target: Reference<'_>, role_id: String, @@ -65,6 +67,12 @@ pub async fn edit( ) .await?; + for channel_id in &server.channels { + let channel = Reference::from_unchecked(channel_id).as_channel(db).await?; + + sync_voice_permissions(db, voice_client, &channel, Some(&server), Some(&role_id)).await?; + }; + Ok(Json(role.into())) } else { Err(create_error!(NotFound)) diff --git a/crates/delta/src/routes/servers/roles_edit_positions.rs b/crates/delta/src/routes/servers/roles_edit_positions.rs index d27259e5b..4b55e95af 100644 --- a/crates/delta/src/routes/servers/roles_edit_positions.rs +++ b/crates/delta/src/routes/servers/roles_edit_positions.rs @@ -1,6 +1,5 @@ use revolt_database::{ - util::{permissions::DatabasePermissionQuery, reference::Reference}, - Database, User, + util::{permissions::DatabasePermissionQuery, reference::Reference}, voice::{sync_voice_permissions, VoiceClient}, Database, User }; use revolt_models::v0; use revolt_permissions::{calculate_server_permissions, ChannelPermission}; @@ -14,6 +13,7 @@ use rocket::{serde::json::Json, State}; #[patch("//roles/ranks", data = "")] pub async fn edit_role_ranks( db: &State, + voice_client: &State, user: User, target: Reference<'_>, data: Json, @@ -70,6 +70,12 @@ pub async fn edit_role_ranks( server.set_role_ordering(db, new_order).await?; + for channel_id in &server.channels { + let channel = Reference::from_unchecked(channel_id).as_channel(db).await?; + + sync_voice_permissions(db, voice_client, &channel, Some(&server), None).await?; + }; + Ok(Json(server.into())) } diff --git a/crates/delta/src/routes/servers/server_delete.rs b/crates/delta/src/routes/servers/server_delete.rs index 1302db5b5..475765ca1 100644 --- a/crates/delta/src/routes/servers/server_delete.rs +++ b/crates/delta/src/routes/servers/server_delete.rs @@ -1,4 +1,11 @@ -use revolt_database::{util::reference::Reference, Database, RemovalIntention, User}; +use revolt_database::{ + util::reference::Reference, + voice::{ + delete_voice_channel, get_user_voice_channel_in_server, remove_user_from_voice_channel, + VoiceClient, + }, + Database, RemovalIntention, User, +}; use revolt_models::v0; use revolt_result::Result; use rocket::State; @@ -12,6 +19,7 @@ use rocket_empty::EmptyResponse; #[delete("/?")] pub async fn delete( db: &State, + voice_client: &State, user: User, target: Reference<'_>, options: v0::OptionsServerDelete, @@ -20,8 +28,16 @@ pub async fn delete( let member = db.fetch_member(target.id, &user.id).await?; if server.owner == user.id { + for channel_id in &server.channels { + delete_voice_channel(voice_client, channel_id, Some(&server.id)).await?; + } + server.delete(db).await } else { + if let Some(channel_id) = get_user_voice_channel_in_server(&user.id, &server.id).await? { + remove_user_from_voice_channel(db, voice_client, &channel_id, &user.id).await?; + }; + member .remove( db, diff --git a/crates/delta/src/util/test.rs b/crates/delta/src/util/test.rs index 067f8bd0a..b90a1a5cd 100644 --- a/crates/delta/src/util/test.rs +++ b/crates/delta/src/util/test.rs @@ -165,6 +165,7 @@ impl TestHarness { name: "Test Channel".to_string(), description: None, nsfw: Some(false), + voice: None }, true, ) diff --git a/livekit.example.yml b/livekit.example.yml new file mode 100644 index 000000000..f502dd7ae --- /dev/null +++ b/livekit.example.yml @@ -0,0 +1,13 @@ +port: 7880 +redis: + address: localhost:6379 + username: "" + password: "" +webhook: + api_key: worldwide + urls: + - 'http://localhost:8500/worldwide' +logging: + level: debug +keys: + worldwide: ZjCofRlfm6GGtjlifmNpCDkcQbEIIVC0 diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 000000000..31578d3bf --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "stable" \ No newline at end of file diff --git a/scripts/build-image-layer.sh b/scripts/build-image-layer.sh index 613cd32d4..52170fdda 100644 --- a/scripts/build-image-layer.sh +++ b/scripts/build-image-layer.sh @@ -38,7 +38,8 @@ deps() { crates/services/january/src \ crates/services/gifbox/src \ crates/daemons/crond/src \ - crates/daemons/pushd/src + crates/daemons/pushd/src \ + crates/daemons/voice-ingress/src echo 'fn main() { panic!("stub"); }' | tee crates/bonfire/src/main.rs | tee crates/delta/src/main.rs | @@ -46,7 +47,8 @@ deps() { tee crates/services/january/src/main.rs | tee crates/services/gifbox/src/main.rs | tee crates/daemons/crond/src/main.rs | - tee crates/daemons/pushd/src/main.rs + tee crates/daemons/pushd/src/main.rs | + tee crates/daemons/voice-ingress/src/main.rs echo '' | tee crates/core/config/src/lib.rs | tee crates/core/database/src/lib.rs | @@ -72,6 +74,7 @@ apps() { crates/delta/src/main.rs \ crates/daemons/crond/src/main.rs \ crates/daemons/pushd/src/main.rs \ + crates/daemons/voice-ingress/src/main.rs \ crates/core/config/src/lib.rs \ crates/core/database/src/lib.rs \ crates/core/models/src/lib.rs \ diff --git a/scripts/publish-debug-image.sh b/scripts/publish-debug-image.sh index 1b07c8926..872609443 100755 --- a/scripts/publish-debug-image.sh +++ b/scripts/publish-debug-image.sh @@ -28,6 +28,7 @@ docker build -t ghcr.io/stoatchat/january:$TAG - < crates/services/january/Docke docker build -t ghcr.io/stoatchat/gifbox:$TAG - < crates/services/gifbox/Dockerfile docker build -t ghcr.io/stoatchat/crond:$TAG - < crates/daemons/crond/Dockerfile docker build -t ghcr.io/stoatchat/pushd:$TAG - < crates/daemons/pushd/Dockerfile +docker build -t ghcr.io/stoatchat/voice-ingress:$TAG - < crates/daemons/voice-ingress/Dockerfile if [ "$DEBUG" = "true" ]; then git restore Cargo.toml @@ -40,3 +41,4 @@ docker push ghcr.io/stoatchat/january:$TAG docker push ghcr.io/stoatchat/gifbox:$TAG docker push ghcr.io/stoatchat/crond:$TAG docker push ghcr.io/stoatchat/pushd:$TAG +docker push ghcr.io/stoatchat/voice-ingress:$TAG From 82b492e5295cec891d96d1b8d3b92bac48eb6167 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Wed, 12 Nov 2025 22:17:11 +0000 Subject: [PATCH 025/211] ci: normalise workflow triggers (#459) Signed-off-by: izzy --- .github/workflows/book.yml | 4 ++-- .github/workflows/docker.yaml | 2 -- .github/workflows/rust.yaml | 10 +--------- 3 files changed, 3 insertions(+), 13 deletions(-) diff --git a/.github/workflows/book.yml b/.github/workflows/book.yml index 00f7ef712..d9df2b584 100644 --- a/.github/workflows/book.yml +++ b/.github/workflows/book.yml @@ -1,8 +1,8 @@ name: Build documentation + on: push: - branches: - - main + branches: [main] jobs: deploy: diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 8d0d74264..5a2255af4 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -5,8 +5,6 @@ on: tags: - "*" pull_request: - branches: - - "main" paths: - "Dockerfile" diff --git a/.github/workflows/rust.yaml b/.github/workflows/rust.yaml index 503ec3710..22096d417 100644 --- a/.github/workflows/rust.yaml +++ b/.github/workflows/rust.yaml @@ -2,16 +2,8 @@ name: Rust build, test, and generate specification on: push: - paths-ignore: - - ".github/**" - - "!.github/workflows/rust.yaml" - - ".vscode/**" - - "doc/**" - - ".gitignore" - - "LICENSE" - - "README" - pull_request: branches: [main] + pull_request: env: CARGO_TERM_COLOR: always From b7c2ca84abafe2da79cc58e019595c300c6492e3 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Wed, 12 Nov 2025 22:19:34 +0000 Subject: [PATCH 026/211] chore: update branding in transactional emails (#458) Signed-off-by: izzy --- crates/core/database/templates/deletion.html | 6 +- .../database/templates/deletion.original.html | 71 ++++++++------- crates/core/database/templates/deletion.txt | 2 +- .../templates/deletion.whitelabel.txt | 4 +- .../database/templates/reset-existing.html | 6 +- .../templates/reset-existing.original.html | 5 +- .../database/templates/reset-existing.txt | 2 +- crates/core/database/templates/reset.html | 6 +- .../database/templates/reset.original.html | 64 +++++++------- crates/core/database/templates/reset.txt | 2 +- .../core/database/templates/suspension.html | 6 +- .../templates/suspension.original.html | 87 +++++++++---------- crates/core/database/templates/suspension.txt | 2 +- crates/core/database/templates/verify.html | 6 +- .../database/templates/verify.original.html | 65 +++++++------- crates/core/database/templates/verify.txt | 2 +- 16 files changed, 167 insertions(+), 169 deletions(-) diff --git a/crates/core/database/templates/deletion.html b/crates/core/database/templates/deletion.html index d25138838..e6cb83eae 100644 --- a/crates/core/database/templates/deletion.html +++ b/crates/core/database/templates/deletion.html @@ -1,7 +1,7 @@ - + @@ -42,7 +42,7 @@ - Revolt Logo + Stoat Logo @@ -107,7 +107,7 @@

This email is intended for {{email}}
- Sent from Revolt
+ Sent from Stoat
Made in Europe diff --git a/crates/core/database/templates/deletion.original.html b/crates/core/database/templates/deletion.original.html index 0da330eac..e3ad4e508 100644 --- a/crates/core/database/templates/deletion.original.html +++ b/crates/core/database/templates/deletion.original.html @@ -1,38 +1,37 @@ - - - - - -
- Revolt Logo -
-

Account Deletion

-

- You requested to have your account deleted, if you did not perform - this action please take measures to secure your account immediately. -

- Confirm -
-
- This email is intended for {{email}}
- Sent from Revolt
- Made in Europe -
-
- Revolt Platforms Ltd. is a company incorporated and registered under the - laws of England and Wales.
- Registered Company Number: 16260658
- Registered Office:
- Suite 5703 Unit 3A, 34-35 Hatton Garden,
- Holborn, United Kingdom, EC1N 8DX -
+ + + + + + + +
+ Stoat Logo +
+

Account Deletion

+

+ You requested to have your account deleted, if you did not perform + this action please take measures to secure your account immediately. +

+ Confirm
- - +
+ This email is intended for {{email}}
+ Sent from Stoat
+ Made in Europe +
+
+ Revolt Platforms Ltd. is a company incorporated and registered under the + laws of England and Wales.
+ Registered Company Number: 16260658
+ Registered Office:
+ Suite 5703 Unit 3A, 34-35 Hatton Garden,
+ Holborn, United Kingdom, EC1N 8DX +
+
+ + + \ No newline at end of file diff --git a/crates/core/database/templates/deletion.txt b/crates/core/database/templates/deletion.txt index b6c2871b0..648059a17 100644 --- a/crates/core/database/templates/deletion.txt +++ b/crates/core/database/templates/deletion.txt @@ -3,7 +3,7 @@ You requested to have your account deleted, if you did not perform this action p Please navigate to: {{url}} This email is intended for {{email}} -Sent by Revolt +Sent by Stoat Made in Europe Revolt Platforms Ltd. is a company incorporated and registered under the laws of England and Wales. diff --git a/crates/core/database/templates/deletion.whitelabel.txt b/crates/core/database/templates/deletion.whitelabel.txt index 491280aac..3447b3519 100644 --- a/crates/core/database/templates/deletion.whitelabel.txt +++ b/crates/core/database/templates/deletion.whitelabel.txt @@ -4,6 +4,6 @@ Please navigate to: {{url}} This email is intended for {{email}} -This email has no association with Revolt or Revolt Platforms Ltd. +This email has no association with Stoat or Revolt Platforms Ltd. Learn more about third party instances here: -https://developers.revolt.chat/faq.html +https://developers.stoat.chat/faq.html diff --git a/crates/core/database/templates/reset-existing.html b/crates/core/database/templates/reset-existing.html index 00ef782b6..1ed6424d3 100644 --- a/crates/core/database/templates/reset-existing.html +++ b/crates/core/database/templates/reset-existing.html @@ -1,7 +1,7 @@ - + @@ -42,7 +42,7 @@
@@ -120,7 +120,7 @@

This email is intended for {{email}}
- Sent from Revolt
+ Sent from Stoat
Made in Europe

diff --git a/crates/core/database/templates/reset-existing.original.html b/crates/core/database/templates/reset-existing.original.html index 1273a69c4..a68c3d35d 100644 --- a/crates/core/database/templates/reset-existing.original.html +++ b/crates/core/database/templates/reset-existing.original.html @@ -9,7 +9,8 @@
Stoat Logo

Password Reset

@@ -25,7 +26,7 @@

Password Reset

This email is intended for {{email}}
- Sent from Revolt
+ Sent from Stoat
Made in Europe
diff --git a/crates/core/database/templates/reset-existing.txt b/crates/core/database/templates/reset-existing.txt index 8c8fc9edc..6637f9086 100644 --- a/crates/core/database/templates/reset-existing.txt +++ b/crates/core/database/templates/reset-existing.txt @@ -8,7 +8,7 @@ password on it, click below to continue. Please navigate to: {{url}} This email is intended for {{email}} -Sent by Revolt +Sent by Stoat Made in Europe Revolt Platforms Ltd. is a company incorporated and registered under the laws of England and Wales. diff --git a/crates/core/database/templates/reset.html b/crates/core/database/templates/reset.html index 9b938f7a4..b2f05cf2e 100644 --- a/crates/core/database/templates/reset.html +++ b/crates/core/database/templates/reset.html @@ -1,7 +1,7 @@ - + @@ -42,7 +42,7 @@
@@ -104,7 +104,7 @@

This email is intended for {{email}}
- Sent from Revolt
+ Sent from Stoat
Made in Europe

diff --git a/crates/core/database/templates/reset.original.html b/crates/core/database/templates/reset.original.html index f15d03289..76b7b5c6e 100644 --- a/crates/core/database/templates/reset.original.html +++ b/crates/core/database/templates/reset.original.html @@ -1,34 +1,34 @@ - - - - - -
- -
-

Password Reset

-

You requested a password reset, click below to continue.

- Reset -
-
- This email is intended for {{email}}
- Sent from Revolt
- Made in Europe -
-
- Revolt Platforms Ltd. is a company incorporated and registered under the - laws of England and Wales.
- Registered Company Number: 16260658
- Registered Office:
- Suite 5703 Unit 3A, 34-35 Hatton Garden,
- Holborn, United Kingdom, EC1N 8DX -
+ + + + + + + +
+ Stoat Logo +
+

Password Reset

+

You requested a password reset, click below to continue.

+ Reset
- - +
+ This email is intended for {{email}}
+ Sent from Stoat
+ Made in Europe +
+
+ Revolt Platforms Ltd. is a company incorporated and registered under the + laws of England and Wales.
+ Registered Company Number: 16260658
+ Registered Office:
+ Suite 5703 Unit 3A, 34-35 Hatton Garden,
+ Holborn, United Kingdom, EC1N 8DX +
+
+ + + \ No newline at end of file diff --git a/crates/core/database/templates/reset.txt b/crates/core/database/templates/reset.txt index 020032c71..266a3e2ed 100644 --- a/crates/core/database/templates/reset.txt +++ b/crates/core/database/templates/reset.txt @@ -3,7 +3,7 @@ You requested a password reset, if you did not perform this action you can safel Please navigate to: {{url}} This email is intended for {{email}} -Sent by Revolt +Sent by Stoat Made in Europe Revolt Platforms Ltd. is a company incorporated and registered under the laws of England and Wales. diff --git a/crates/core/database/templates/suspension.html b/crates/core/database/templates/suspension.html index 5002c2580..2e4c2298a 100644 --- a/crates/core/database/templates/suspension.html +++ b/crates/core/database/templates/suspension.html @@ -1,7 +1,7 @@ - + @@ -42,7 +42,7 @@
@@ -134,7 +134,7 @@

This email is intended for {{email}}
- Sent from Revolt
+ Sent from Stoat
Made in Europe

diff --git a/crates/core/database/templates/suspension.original.html b/crates/core/database/templates/suspension.original.html index fbbbb4168..de49512d2 100644 --- a/crates/core/database/templates/suspension.original.html +++ b/crates/core/database/templates/suspension.original.html @@ -1,46 +1,45 @@ - - - - - -
- Revolt Logo -
-

Account Suspended

-

Your account has been suspended, for one or more reasons:

-
    - {{list}} -
-

- You will be able to use your account again in {{duration}} days. -

-

- Further violations may result in a permanent ban depending on - severity, please abide by the - Acceptable Usage Policy. -

-

Ban evasion is prohibited and will be dealt with accordingly.

-
-
- This email is intended for {{email}}
- Sent from Revolt
- Made in Europe -
-
- Revolt Platforms Ltd. is a company incorporated and registered under the - laws of England and Wales.
- Registered Company Number: 16260658
- Registered Office:
- Suite 5703 Unit 3A, 34-35 Hatton Garden,
- Holborn, United Kingdom, EC1N 8DX -
+ + + + + + + +
+ Stoat Logo +
+

Account Suspended

+

Your account has been suspended, for one or more reasons:

+
    + {{list}} +
+

+ You will be able to use your account again in {{duration}} days. +

+

+ Further violations may result in a permanent ban depending on + severity, please abide by the + Acceptable Usage Policy. +

+

Ban evasion is prohibited and will be dealt with accordingly.

- - +
+ This email is intended for {{email}}
+ Sent from Stoat
+ Made in Europe +
+
+ Revolt Platforms Ltd. is a company incorporated and registered under the + laws of England and Wales.
+ Registered Company Number: 16260658
+ Registered Office:
+ Suite 5703 Unit 3A, 34-35 Hatton Garden,
+ Holborn, United Kingdom, EC1N 8DX +
+
+ + + \ No newline at end of file diff --git a/crates/core/database/templates/suspension.txt b/crates/core/database/templates/suspension.txt index 30d48d846..d247eae33 100644 --- a/crates/core/database/templates/suspension.txt +++ b/crates/core/database/templates/suspension.txt @@ -8,7 +8,7 @@ Further violations may result in a permanent ban depending on severity, please a Ban evasion is prohibited and will be dealt with accordingly. This email is intended for {{email}} -Sent by Revolt +Sent by Stoat Made in Europe Revolt Platforms Ltd. is a company incorporated and registered under the laws of England and Wales. diff --git a/crates/core/database/templates/verify.html b/crates/core/database/templates/verify.html index 8ab9713d0..10a4ab6ae 100644 --- a/crates/core/database/templates/verify.html +++ b/crates/core/database/templates/verify.html @@ -1,7 +1,7 @@ - + @@ -42,7 +42,7 @@
@@ -104,7 +104,7 @@

This email is intended for {{email}}
- Sent from Revolt
+ Sent from Stoat
Made in Europe

diff --git a/crates/core/database/templates/verify.original.html b/crates/core/database/templates/verify.original.html index 75ae25cea..107d73077 100644 --- a/crates/core/database/templates/verify.original.html +++ b/crates/core/database/templates/verify.original.html @@ -1,35 +1,34 @@ - - - - - -
- Revolt Logo -
-

Almost there!

-

To complete your sign up, we just need to verify your email.

- Confirm -
-
- This email is intended for {{email}}
- Sent from Revolt
- Made in Europe -
-
- Revolt Platforms Ltd. is a company incorporated and registered under the - laws of England and Wales.
- Registered Company Number: 16260658
- Registered Office:
- Suite 5703 Unit 3A, 34-35 Hatton Garden,
- Holborn, United Kingdom, EC1N 8DX -
+ + + + + + + +
+ Stoat Logo +
+

Almost there!

+

To complete your sign up, we just need to verify your email.

+ Confirm
- - +
+ This email is intended for {{email}}
+ Sent from Stoat
+ Made in Europe +
+
+ Revolt Platforms Ltd. is a company incorporated and registered under the + laws of England and Wales.
+ Registered Company Number: 16260658
+ Registered Office:
+ Suite 5703 Unit 3A, 34-35 Hatton Garden,
+ Holborn, United Kingdom, EC1N 8DX +
+
+ + + \ No newline at end of file diff --git a/crates/core/database/templates/verify.txt b/crates/core/database/templates/verify.txt index 7fa871eef..cafd09d41 100644 --- a/crates/core/database/templates/verify.txt +++ b/crates/core/database/templates/verify.txt @@ -4,7 +4,7 @@ To complete your sign up, we just need to verify your email. Please navigate to: {{url}} This email is intended for {{email}} -Sent by Revolt +Sent by Stoat Made in Europe Revolt Platforms Ltd. is a company incorporated and registered under the laws of England and Wales. From ac2971a78d83b155367bc8652c97a30a32f9cf53 Mon Sep 17 00:00:00 2001 From: "stoat-tofu[bot]" <242700035+stoat-tofu[bot]@users.noreply.github.com> Date: Fri, 14 Nov 2025 20:25:09 +0000 Subject: [PATCH 027/211] chore: modify .github/workflows/validate-pr-title.yml --- .github/workflows/validate-pr-title.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/validate-pr-title.yml b/.github/workflows/validate-pr-title.yml index b72cc236a..6af093036 100644 --- a/.github/workflows/validate-pr-title.yml +++ b/.github/workflows/validate-pr-title.yml @@ -17,4 +17,4 @@ jobs: steps: - uses: amannn/action-semantic-pull-request@v6 env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file From e006cdd0515e9d9b0d6fc160f0c7d09f27ea3049 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Fri, 14 Nov 2025 21:41:22 +0000 Subject: [PATCH 028/211] ci: prevent concurrency on docker/rust actions (#461) --- .github/workflows/docker.yaml | 4 ++++ .github/workflows/rust.yaml | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 5a2255af4..e12f3a8bb 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -12,6 +12,10 @@ permissions: contents: read packages: write +concurrency: + group: ${{ github.head_ref }} + cancel-in-progress: true + jobs: base: name: Test base image build diff --git a/.github/workflows/rust.yaml b/.github/workflows/rust.yaml index 22096d417..ceb2c9188 100644 --- a/.github/workflows/rust.yaml +++ b/.github/workflows/rust.yaml @@ -5,6 +5,10 @@ on: branches: [main] pull_request: +concurrency: + group: ${{ github.head_ref }} + cancel-in-progress: true + env: CARGO_TERM_COLOR: always @@ -14,6 +18,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + - name: Free up disk space + run: | + sudo rm -rf /usr/local/lib/android /usr/share/dotnet /opt/ghc + - name: Install latest stable uses: actions-rs/toolchain@v1 with: From 0b7c132ace2acda92f2fe398e254e27f241cfcd4 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Fri, 14 Nov 2025 22:06:20 +0000 Subject: [PATCH 029/211] docs: initialise new docs with docusaurus (#460) * docs: initialise new docs with docusaurus * chore: sign off Signed-off-by: izzy * chore: lock pnpm version in package.json Signed-off-by: izzy * ci: specify package json to load pnpm version from Signed-off-by: izzy * docs: update repo. lifecycle details Signed-off-by: izzy * docs: add external links to for-web, for-android chore: add default.nix to docs * docs: correct headings in contrib * ci: use cache dependency path * fix: docusaurus configuration --------- Signed-off-by: izzy --- .github/workflows/book.yml | 37 - .github/workflows/docs-test.yml | 29 + .github/workflows/docs.yml | 54 + doc/.gitignore | 1 - doc/book.toml | 5 - doc/src/SUMMARY.md | 8 - doc/src/hello.md | 5 - docs/.gitignore | 20 + docs/README.md | 41 + docs/default.nix | 11 + docs/docs/developers/api/_category_.json | 10 + docs/docs/developers/api/authentication.md | 15 + .../developers/api/permission_hierarchy.svg | 1 + docs/docs/developers/api/permissions.mdx | 49 + docs/docs/developers/api/ratelimits.md | 49 + docs/docs/developers/api/uploading-files.md | 47 + docs/docs/developers/endpoints.md | 23 + docs/docs/developers/events/_category_.json | 10 + docs/docs/developers/events/establishing.md | 57 + docs/docs/developers/events/protocol.md | 589 + docs/docs/developers/legacy-plugin-api.md | 147 + docs/docs/developers/libraries.md | 8 + docs/docs/developers/stoat-migration-guide.md | 22 + docs/docs/developing/backend/_category_.json | 10 + .../docs/developing/backend}/new_features.md | 2 +- docs/docs/developing/contrib.md | 45 + docs/docs/faq.md | 109 + docs/docs/help.md | 30 + docs/docs/index.md | 17 + docs/docusaurus.config.ts | 182 + docs/package-lock.json | 18000 ++++++++++++++++ docs/package.json | 50 + docs/pnpm-lock.yaml | 11448 ++++++++++ docs/pnpm-workspace.yaml | 5 + docs/sidebars.ts | 49 + docs/static/.nojekyll | 0 docs/static/img/.gitkeep | 0 docs/tsconfig.json | 8 + 38 files changed, 31136 insertions(+), 57 deletions(-) delete mode 100644 .github/workflows/book.yml create mode 100644 .github/workflows/docs-test.yml create mode 100644 .github/workflows/docs.yml delete mode 100644 doc/.gitignore delete mode 100644 doc/book.toml delete mode 100644 doc/src/SUMMARY.md delete mode 100644 doc/src/hello.md create mode 100644 docs/.gitignore create mode 100644 docs/README.md create mode 100644 docs/default.nix create mode 100644 docs/docs/developers/api/_category_.json create mode 100644 docs/docs/developers/api/authentication.md create mode 100644 docs/docs/developers/api/permission_hierarchy.svg create mode 100644 docs/docs/developers/api/permissions.mdx create mode 100644 docs/docs/developers/api/ratelimits.md create mode 100644 docs/docs/developers/api/uploading-files.md create mode 100644 docs/docs/developers/endpoints.md create mode 100644 docs/docs/developers/events/_category_.json create mode 100644 docs/docs/developers/events/establishing.md create mode 100644 docs/docs/developers/events/protocol.md create mode 100644 docs/docs/developers/legacy-plugin-api.md create mode 100644 docs/docs/developers/libraries.md create mode 100644 docs/docs/developers/stoat-migration-guide.md create mode 100644 docs/docs/developing/backend/_category_.json rename {doc/src => docs/docs/developing/backend}/new_features.md (96%) create mode 100644 docs/docs/developing/contrib.md create mode 100644 docs/docs/faq.md create mode 100644 docs/docs/help.md create mode 100644 docs/docs/index.md create mode 100644 docs/docusaurus.config.ts create mode 100644 docs/package-lock.json create mode 100644 docs/package.json create mode 100644 docs/pnpm-lock.yaml create mode 100644 docs/pnpm-workspace.yaml create mode 100644 docs/sidebars.ts create mode 100644 docs/static/.nojekyll create mode 100644 docs/static/img/.gitkeep create mode 100644 docs/tsconfig.json diff --git a/.github/workflows/book.yml b/.github/workflows/book.yml deleted file mode 100644 index d9df2b584..000000000 --- a/.github/workflows/book.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: Build documentation - -on: - push: - branches: [main] - -jobs: - deploy: - runs-on: ubuntu-latest - permissions: - contents: write # To push a branch - pages: write # To push to a GitHub Pages site - id-token: write # To update the deployment status - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Install latest mdbook - run: | - tag=$(curl 'https://api.github.com/repos/rust-lang/mdbook/releases/latest' | jq -r '.tag_name') - url="https://github.com/rust-lang/mdbook/releases/download/${tag}/mdbook-${tag}-x86_64-unknown-linux-gnu.tar.gz" - mkdir mdbook - curl -sSL $url | tar -xz --directory=./mdbook - echo `pwd`/mdbook >> $GITHUB_PATH - - name: Build Book - run: | - cd doc - mdbook build - - name: Setup Pages - uses: actions/configure-pages@v4 - - name: Upload artifact - uses: actions/upload-pages-artifact@v3 - with: - path: "doc/book" - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 diff --git a/.github/workflows/docs-test.yml b/.github/workflows/docs-test.yml new file mode 100644 index 000000000..38c449102 --- /dev/null +++ b/.github/workflows/docs-test.yml @@ -0,0 +1,29 @@ +name: Documentation (test) + +on: + pull_request: + +jobs: + test-deploy: + name: Test deployment + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./docs + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: pnpm/action-setup@v4 + with: + package_json_file: ./docs/package.json + - uses: actions/setup-node@v4 + with: + node-version: lts/* + cache: pnpm + cache-dependency-path: ./docs/pnpm-lock.yaml + + - name: Install dependencies + run: pnpm install + - name: Test build website + run: pnpm run build \ No newline at end of file diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 000000000..8cf399a42 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,54 @@ +name: Documentation + +on: + push: + branches: + - main + +jobs: + build: + name: Build Docusaurus + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./docs + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: pnpm/action-setup@v4 + with: + package_json_file: ./docs/package.json + - uses: actions/setup-node@v4 + with: + node-version: lts/* + cache: pnpm + cache-dependency-path: ./docs/pnpm-lock.yaml + + - name: Install dependencies + run: pnpm install + - name: Build website + run: pnpm run build + + - name: Upload Build Artifact + uses: actions/upload-pages-artifact@v3 + with: + path: build + + deploy: + name: Deploy to GitHub Pages + needs: build + + permissions: + pages: write # to deploy to Pages + id-token: write # to verify the deployment originates from an appropriate source + + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + + runs-on: ubuntu-latest + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/doc/.gitignore b/doc/.gitignore deleted file mode 100644 index 7585238ef..000000000 --- a/doc/.gitignore +++ /dev/null @@ -1 +0,0 @@ -book diff --git a/doc/book.toml b/doc/book.toml deleted file mode 100644 index 830614c78..000000000 --- a/doc/book.toml +++ /dev/null @@ -1,5 +0,0 @@ -[book] -authors = [] -language = "en" -src = "src" -title = "Revolt Backend" diff --git a/doc/src/SUMMARY.md b/doc/src/SUMMARY.md deleted file mode 100644 index e772ccd7b..000000000 --- a/doc/src/SUMMARY.md +++ /dev/null @@ -1,8 +0,0 @@ -# Summary - -- [Introduction](./hello.md) -- [Project Structure]() -- [Creating new API features](./new_features.md) -- [Testing]() - - [Writing a new database test]() - - [Writing a new API test]() diff --git a/doc/src/hello.md b/doc/src/hello.md deleted file mode 100644 index f8182679a..000000000 --- a/doc/src/hello.md +++ /dev/null @@ -1,5 +0,0 @@ -# Revolt Backend - -Welcome to the developer documentation for the Revolt backend. - -This is very much incomplete and needs more work! diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 000000000..b2d6de306 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,20 @@ +# Dependencies +/node_modules + +# Production +/build + +# Generated files +.docusaurus +.cache-loader + +# Misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 000000000..b28211a9b --- /dev/null +++ b/docs/README.md @@ -0,0 +1,41 @@ +# Website + +This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator. + +## Installation + +```bash +yarn +``` + +## Local Development + +```bash +yarn start +``` + +This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. + +## Build + +```bash +yarn build +``` + +This command generates static content into the `build` directory and can be served using any static contents hosting service. + +## Deployment + +Using SSH: + +```bash +USE_SSH=true yarn deploy +``` + +Not using SSH: + +```bash +GIT_USER= yarn deploy +``` + +If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. diff --git a/docs/default.nix b/docs/default.nix new file mode 100644 index 000000000..f7b9b2fd5 --- /dev/null +++ b/docs/default.nix @@ -0,0 +1,11 @@ +{ + pkgs ? import { }, +}: + +with pkgs; +pkgs.mkShell { + buildInputs = [ + nodejs + nodejs.pkgs.pnpm + ]; +} diff --git a/docs/docs/developers/api/_category_.json b/docs/docs/developers/api/_category_.json new file mode 100644 index 000000000..ec96f5535 --- /dev/null +++ b/docs/docs/developers/api/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "API", + "position": 2, + "link": { + "type": "generated-index", + "description": "Connecting and consuming the Stoat API" + }, + "collapsed": false, + "collapsible": true +} \ No newline at end of file diff --git a/docs/docs/developers/api/authentication.md b/docs/docs/developers/api/authentication.md new file mode 100644 index 000000000..6586d06be --- /dev/null +++ b/docs/docs/developers/api/authentication.md @@ -0,0 +1,15 @@ +# Authentication + +To authenticate with the API, you must first acquire a bot token or user token: + +- **Bot:** create one from user settings in the client +- **User:** copy one from client or authenticate through API + +Then you may provide these through either: + +| Type | Header | +| :---: | :---------------: | +| Bot | `X-Bot-Token` | +| User | `X-Session-Token` | + +When dealing with an authenticated route. diff --git a/docs/docs/developers/api/permission_hierarchy.svg b/docs/docs/developers/api/permission_hierarchy.svg new file mode 100644 index 000000000..9bad3366c --- /dev/null +++ b/docs/docs/developers/api/permission_hierarchy.svg @@ -0,0 +1 @@ +
Fetch Server
Fetch Server
Determine Server Permissions
Apply allows from
default_permission
Apply allows from...
§
Member has un-applied role?
§...
Yes
Yes
No
No
Resolve role from
server object
Resolve role from...
Apply allows from
role_permission 
Apply allows from...
Apply denies from
role_permission
Apply denies from...
Determine Channel Permissions
Fetch Channel
Fetch Channel
Channel
Type
Channel...
(Text | Voice) Channel
(Text | Voice) Channel
Apply maximum
allows
Apply maximum...
Apply (#1).
Apply (#1).
Is user group owner?
Is user group ow...
No
No
Apply maximum
allows
Apply maximum...
Apply allows from
c.permissions
Apply allows from...
Determine Server Permissions 
Determine Server Per...
Apply allows
and denies.
Apply allows...
Apply allows from
permissions 
Apply allows from...
Apply denies from
permissions
Apply denies from...
†: order here does not matter.
†: order here does no...
§
Member has un-applied role?
§...
¶: assume we fetch server / member obj
¶: assume we fetch s...
Yes
Yes
Role has
overrides
Role has...
Yes
Yes
Apply allows from role_permissions 
Apply allows from ro...
Apply denies from role_permissions
Apply denies from ro...
No
No
No
No
Has default permissions?
Has default permis...
No
No
Yes
Yes
§: assume roles are sorted 
§: assume roles are...
Fetch Member
Fetch Member
Is the user
server owner?
Is the user...
Apply maximum
allows
Apply maximum...
Yes
Yes
No
No
#1: view channel, view history, send, manage, voice, embed, invite, upload
#1: view channel, view history, send,...
#2: view, history, send, voice, embed, invite, upload, change nick, change pfp
#2: view, history, send, voice, embed, i...
Saved Messages
Saved Messages
Direct Message
Direct Message
Yes
Yes
Has specified permissions?
Has specified pe...
Group
Group
Yes
Yes
Apply (#1).
Apply (#1).
No
No
‡: the permission set #2 is the default value
‡: the permission set...
Has send
perm?
Has send...
Determine User Permissions
Determine User Permi...
Yes
Yes
No
No
#3: view, history
#3: view, history
Apply (#3).
Apply (#3).
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/docs/developers/api/permissions.mdx b/docs/docs/developers/api/permissions.mdx new file mode 100644 index 000000000..a40a5763a --- /dev/null +++ b/docs/docs/developers/api/permissions.mdx @@ -0,0 +1,49 @@ +# Permissions + +Stoat's permission system works by sequentially applying allows then denies. + +## Flow Chart + +Below are the high-level steps taken to determine both server and channel permissions (click to view). + + + + + +If you are looking to implement permissions in a library, I highly recommend reading either the Stoat JavaScript SDK or the backend source code since all the routines are well commented and should be relatively easy to understand. + +## Values + +The following permissions are currently allocated: + +| Name | Value | Bitwise | Description | +| --------------------- | :-----------: | :-------: | ------------------------------------------------------- | +| `ManageChannel` | `1` | `1 << 0` | Manage the channel or channels on the server | +| `ManageServer` | `2` | `1 << 1` | Manage the server | +| `ManagePermissions` | `4` | `1 << 2` | Manage permissions on servers or channels | +| `ManageRole` | `8` | `1 << 3` | Manage roles on server | +| `ManageCustomisation` | `16` | `1 << 4` | Manage emoji on servers | +| `KickMembers` | `64` | `1 << 6` | Kick other members below their ranking | +| `BanMembers` | `128` | `1 << 7` | Ban other members below their ranking | +| `TimeoutMembers` | `256` | `1 << 8` | Timeout other members below their ranking | +| `AssignRoles` | `512` | `1 << 9` | Assign roles to members below their ranking | +| `ChangeNickname` | `1024` | `1 << 10` | Change own nickname | +| `ManageNicknames` | `2048` | `1 << 11` | Change or remove other's nicknames below their ranking | +| `ChangeAvatar` | `4096` | `1 << 12` | Change own avatar | +| `RemoveAvatars` | `8192` | `1 << 13` | Remove other's avatars below their ranking | +| `ViewChannel` | `1048576` | `1 << 20` | View a channel | +| `ReadMessageHistory` | `2097152` | `1 << 21` | Read a channel's past message history | +| `SendMessage` | `4194304` | `1 << 22` | Send a message in a channel | +| `ManageMessages` | `8388608` | `1 << 23` | Delete messages in a channel | +| `ManageWebhooks` | `16777216` | `1 << 24` | Manage webhook entries on a channel | +| `InviteOthers` | `33554432` | `1 << 25` | Create invites to this channel | +| `SendEmbeds` | `67108864` | `1 << 26` | Send embedded content in this channel | +| `UploadFiles` | `134217728` | `1 << 27` | Send attachments and media in this channel | +| `Masquerade` | `268435456` | `1 << 28` | Masquerade messages using custom nickname and avatar | +| `React` | `536870912` | `1 << 29` | React to messages with emojis | +| `Connect` | `1073741824` | `1 << 30` | Connect to a voice channel | +| `Speak` | `2147483648` | `1 << 31` | Speak in a voice call | +| `Video` | `4294967296` | `1 << 32` | Share video in a voice call | +| `MuteMembers` | `8589934592` | `1 << 33` | Mute other members with lower ranking in a voice call | +| `DeafenMembers` | `17179869184` | `1 << 34` | Deafen other members with lower ranking in a voice call | +| `MoveMembers` | `34359738368` | `1 << 35` | Move members between voice channels | diff --git a/docs/docs/developers/api/ratelimits.md b/docs/docs/developers/api/ratelimits.md new file mode 100644 index 000000000..b939015b8 --- /dev/null +++ b/docs/docs/developers/api/ratelimits.md @@ -0,0 +1,49 @@ +# Rate Limits + +Stoat uses a fixed-window ratelimiting algorithm: + +- You are given a set amount of calls per each named bucket. +- Any calls past this limit will result in 429 errors. +- Buckets are replenished after 10 seconds from initial request. + +## Buckets + +There are distinct buckets that you may be calling against, none of these affect each other and can be used up independently of one another. + +| Method | Path | Limit | +| -------: | --------------------------- | :---: | +| | `/users` | 20 | +| `PATCH` | `/users/:id` | 2 | +| | `/users/:id/default_avatar` | 255 | +| | `/bots` | 10 | +| | `/channels` | 15 | +| `POST` | `/channels/:id/messages` | 10 | +| | `/servers` | 5 | +| | `/auth` | 3 | +| `DELETE` | `/auth` | 255 | +| | `/safety` | 15 | +| | `/safety/report` | 3 | +| | `/swagger` | 100 | +| | `/*` | 20 | + +## Headers + +There are multiple headers you can use to figure out when you can and cannot send requests, and to determine when you can next send a request. + +| Header | Type | Description | +| ------------------------- | :------: | ------------------------------------------------ | +| `X-RateLimit-Limit` | `number` | Maximum number of calls allowed for this bucket. | +| `X-RateLimit-Bucket` | `string` | Unique identifier for this bucket. | +| `X-RateLimit-Remaining` | `number` | Remaining number of calls left for this bucket. | +| `X-RateLimit-Reset-After` | `number` | Milliseconds left until calls are replenished. | + +## Rate Limited Response + +When you receive `429 Too Many Requests`, you will also receive a JSON body with the schema: + +```typescript +interface Response { + // Milliseconds until calls are replenished + retry_after: number; +} +``` diff --git a/docs/docs/developers/api/uploading-files.md b/docs/docs/developers/api/uploading-files.md new file mode 100644 index 000000000..2ee1a1ee4 --- /dev/null +++ b/docs/docs/developers/api/uploading-files.md @@ -0,0 +1,47 @@ +# Uploading Files + +File uploads work by first sending a file to the server and then using the ID provided. + +You can find out what kinds of files you can upload by visiting [the API documentation](https://cdn.stoatusercontent.com/scalar). + +To upload a file, pick the desired tag then send a **POST** to `{endpoint}/{tag}` along with a `multipart/form-data` body with one field `file` that contains the file you wish to upload. + +You must specify session/bot authentication token as with any other API route. + +You will receive the following JSON response: + +```json +{ + "id": "0" +} +``` + +You can use the ID wherever a file is required in the API. + +Code sample in JavaScript using Fetch API: + +```js +const body = new FormData(); +body.append("file", file); + +const data = await fetch(`${endpoint}/${tag}`, { + method: "POST", + body, + headers: { + "X-Session-Token": "...", // or X-Bot-Token + }, +}).then((res) => res.json()); + +// use data.id +``` + +## Differences from old Autumn + +If you are migrating from old Autumn, the following key points are important: + +- There are only two paths that serve a unique image, the preview version of it (if available) and the original image. +- You should not specify any query parameters under any circumstance, the preview route will serve the optimal size for the content type. +- Preview routes for banners, emojis, backgrounds, and attachments will redirect to the original file where the file is not an image or the image is animated. +- If you are currently using logic to replace the URL path to start/stop animations, you should use the following templates: (NB. this only applies to avatars and icons) + - Non-animated file: `/{tag}/{file_id}` + - Animated file: `/{tag}/{file_id}/{file_name}` or `/{tag}/{file_id}/original` (if name unavailable) diff --git a/docs/docs/developers/endpoints.md b/docs/docs/developers/endpoints.md new file mode 100644 index 000000000..b22c64e2f --- /dev/null +++ b/docs/docs/developers/endpoints.md @@ -0,0 +1,23 @@ +--- +sidebar_position: 1 +--- + +# Endpoints + +**We are moving stuff around currently following the rebrand, guidance will follow soon!** + +You can connect to the API on the following URLs: + +| URL | Release | Description | +| ----------------------------- | :--------: | --------------------------- | +| `https://api.revolt.chat` | Production | Primary API endpoint | +| `https://app.revolt.chat/api` | Production | API endpoint for old client | +| `https://revolt.chat/api` | Staging | API endpoint for new client | + +You can connect to the events server on the following URLs: + +| URL | Release | Description | +| ------------------------------ | :--------: | ------------------------------ | +| `wss://ws.revolt.chat` | Production | Primary events endpoint | +| `wss://app.revolt.chat/events` | Production | Events endpoint for old client | +| `wss://revolt.chat/events` | Staging | Events endpoint for new client | diff --git a/docs/docs/developers/events/_category_.json b/docs/docs/developers/events/_category_.json new file mode 100644 index 000000000..d5a249fad --- /dev/null +++ b/docs/docs/developers/events/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "Events", + "position": 2, + "link": { + "type": "generated-index", + "description": "Connecting and using the Stoat gateway" + }, + "collapsed": false, + "collapsible": true +} \ No newline at end of file diff --git a/docs/docs/developers/events/establishing.md b/docs/docs/developers/events/establishing.md new file mode 100644 index 000000000..92d397632 --- /dev/null +++ b/docs/docs/developers/events/establishing.md @@ -0,0 +1,57 @@ +# Establishing a connection + +To get started, you should have: + +- A WebSocket URL, which is found from the API root. +- A valid session or bot token. + +You may authenticate in one of two ways: + +- Include credentials in the connection URL, see [Query Parameters](#query-parameters). +- Sending an [Authenticate](./protocol.md#authenticate) event to the server. + +You should listen out for [Error](./protocol.md#error) events to find out if your credentials are incorrect or if something goes wrong here. + +After authenticating, the server will respond with [Authenticated](./protocol.md#authenticated) then it will send a [Ready](./protocol.md#ready) event containing useful data. + +The server will now start sending relevant events as they come in. + +You should [Ping](./protocol.md#ping) the server every 10 to 30 seconds to prevent your connection being dropped. + +Bots receive all events, normal users do not receive UserUpdate events fanned out through servers by default, [read more here](./protocol.md#subscribe). + +## Query Parameters + +The Bonfire service supports additional query parameters: + +| Parameter | Description | Values | Required | +| --------- | ----------------------------------------------------------------------- | -------------------------- | -------- | +| `version` | Describes the protocol version in use. | `1` | No † | +| `format` | In what format to send packets, default is JSON. | `json`, `msgpack` | No | +| `token` | token for authenticating the connecting user. | Session or bot token | No | +| `ready` | Fields to include in the `Ready` event payload, by default all are sent | [See Below](#ready-fields) | No | + +† `version` may become compulsary in the future, please set it to `1` if you can. + +### Ready Fields + +The ready query parameter can be passed multiple times to specify multiple fields, supported fields are: + +| Value | Description | +| ----------------- | --------------------------------------------------------------------------------------------------------------- | +| `users` | Includes all users you have a relation with. | +| `servers` | Includes all servers you are in. | +| `channels` | Includes all channels you have access to. | +| `members` | Includes all members you have a relation with. | +| `emojis` | Includes all emojis you have access to. | +| `user_settings` | Specify which settings to pre-fetch, specify a setting by setting the value to `user_settings[]`. | +| `channel_unreads` | Includes all channel unreads you have. | +| `policy_changes` | Includes all new policy changes you should be aware of, this is not sent to bots. | + +For example: + +``` +?ready=users&ready=servers&ready=user_settings[ordering] +``` + +You may specify these in the connection URL: `wss://stoat.chat/events?version=1&format=json`. diff --git a/docs/docs/developers/events/protocol.md b/docs/docs/developers/events/protocol.md new file mode 100644 index 000000000..1c8a8618f --- /dev/null +++ b/docs/docs/developers/events/protocol.md @@ -0,0 +1,589 @@ +# Events + +This page documents various incoming and outgoing events. + +**Help Wanted:** we should adopt [AsyncAPI](https://www.asyncapi.com) to properly document the protocol! + +## Client to Server + +### Authenticate + +Authenticate with the server. + +```json +{ + "type": "Authenticate", + "token": "{token}" +} +``` + +### BeginTyping + +Tell other users that you have begun typing in a channel. + +Must be in the specified channel or nothing will happen. + +```json +{ + "type": "BeginTyping", + "channel": "{channel_id}" +} +``` + +### EndTyping + +Tell other users that you have stopped typing in a channel. + +Must be in the specified channel or nothing will happen. + +```json +{ + "type": "EndTyping", + "channel": "{channel_id}" +} +``` + +### Ping + +Ping the server, you can specify a timestamp that you'll receive back. + +```json +{ + "type": "Ping", + "data": 0 +} +``` + +### Subscribe + +Subscribe to a server's UserUpdate events. + +```json +{ + "type": "Subscribe", + "server_id": "{server_id}" +} +``` + +Implementation notes: + +- Subscriptions automatically expire within 15 minutes. +- A client may have up to 5 active subscriptions. +- This has no effect on bot sessions. +- This event should only be sent **iff** app/client is in focus. +- You should aim to send this event at most every 10 minutes per server. + +## Server to Client + +### Error + +An error occurred which meant you couldn't authenticate. + +```json +{ + "type": "Error", + "error": "{error_id}" +} +``` + +The `{error_id}` can be one of the following: + +- `LabelMe`: uncategorised error +- `InternalError`: the server ran into an issue +- `InvalidSession`: authentication details are incorrect +- `OnboardingNotFinished`: user has not chosen a username +- `AlreadyAuthenticated`: this connection is already authenticated + +### Authenticated + +The server has authenticated your connection and you will shortly start receiving data. + +```json +{ + "type": "Authenticated" +} +``` + +### Logged Out + +The current user session has been invalidated or the bot token has been reset. + +```json +{ + "type": "Logout" +} +``` + +Your connection will be closed shortly after. + +### Bulk + +Several events have been sent, process each item of `v` as its own event. + +```json +{ + "type": "Bulk", + "v": [...] +} +``` + +### Pong + +Ping response from the server. + +```json +{ + "type": "Pong", + "data": 0 +} +``` + +### Ready + +Data for use by client, data structures match the API specification. + +```json +{ + "type": "Ready", + "users"?: [{..}], + "servers"?: [{..}], + "channels"?: [{..}], + "members"?: [{..}], + "emojis"?: [{..}], + "user_settings"?: [{..}], + "channel_unreads"?: [{..}], + "policy_changes"?: [{..}], +} +``` + +### Message + +Message received, the event object has the same schema as the Message object in the API with the addition of an event type. + +```json +{ + "type": "Message", + [..] +} +``` + +### MessageUpdate + +Message edited or otherwise updated. + +```json +{ + "type": "MessageUpdate", + "id": "{message_id}", + "channel": "{channel_id}", + "data": {..} +} +``` + +- `data` field contains a partial Message object. + +### MessageAppend + +Message has data being appended to it. + +```json +{ + "type": "MessageAppend", + "id": "{message_id}", + "channel": "{channel_id}", + "append": { + "embeds"?: [...] + } +} +``` + +### MessageDelete + +Message has been deleted. + +```json +{ + "type": "MessageDelete", + "id": "{message_id}", + "channel": "{channel_id}" +} +``` + +### MessageReact + +A reaction has been added to a message. + +```json +{ + "type": "MessageReact", + "id": "{message_id}", + "channel_id": "{channel_id}", + "user_id": "{user_id}", + "emoji_id": "{emoji_id}" +} +``` + +### MessageUnreact + +A reaction has been removed from a message. + +```json +{ + "type": "MessageUnreact", + "id": "{message_id}", + "channel_id": "{channel_id}", + "user_id": "{user_id}", + "emoji_id": "{emoji_id}" +} +``` + +### MessageRemoveReaction + +A certain reaction has been removed from the message. + +```json +{ + "type": "MessageRemoveReaction", + "id": "{message_id}", + "channel_id": "{channel_id}", + "emoji_id": "{emoji_id}" +} +``` + +### ChannelCreate + +Channel created, the event object has the same schema as the Channel object in the API with the addition of an event type. + +```json +{ + "type": "ChannelCreate", + [..] +} +``` + +### ChannelUpdate + +Channel details updated. + +```json +{ + "type": "ChannelUpdate", + "id": "{channel_id}", + "data": {..}, + "clear": ["{field}", ...] +} +``` + +- `data` field contains a partial Channel object. +- `{field}` is a field to remove, one of: + - `Icon` + - `Description` + +### ChannelDelete + +Channel has been deleted. + +```json +{ + "type": "ChannelDelete", + "id": "{channel_id}" +} +``` + +### ChannelGroupJoin + +A user has joined the group. + +```json +{ + "type": "ChannelGroupJoin", + "id": "{channel_id}", + "user": "{user_id}" +} +``` + +### ChannelGroupLeave + +A user has left the group. + +```json +{ + "type": "ChannelGroupLeave", + "id": "{channel_id}", + "user": "{user_id}" +} +``` + +### ChannelStartTyping + +A user has started typing in this channel. + +```json +{ + "type": "ChannelStartTyping", + "id": "{channel_id}", + "user": "{user_id}" +} +``` + +### ChannelStopTyping + +A user has stopped typing in this channel. + +```json +{ + "type": "ChannelStopTyping", + "id": "{channel_id}", + "user": "{user_id}" +} +``` + +### ChannelAck + +You have acknowledged new messages in this channel up to this message ID. + +```json +{ + "type": "ChannelAck", + "id": "{channel_id}", + "user": "{user_id}", + "message_id": "{message_id}" +} +``` + +### ServerCreate + +Server created, the event object has the same schema as the SERVER object in the API with the addition of an event type. + +```json +{ + "type": "ServerCreate", + [..] +} +``` + +### ServerUpdate + +Server details updated. + +```json +{ + "type": "ServerUpdate", + "id": "{server_id}", + "data": {..}, + "clear": ["{field}", ...] +} +``` + +- `data` field contains a partial Server object. +- `{field}` is a field to remove, one of: + - `Icon` + - `Banner` + - `Description` + +### ServerDelete + +Server has been deleted. + +```json +{ + "type": "ServerDelete", + "id": "{server_id}" +} +``` + +### ServerMemberUpdate + +Server member details updated. + +```json +{ + "type": "ServerMemberUpdate", + "id": { + "server": "{server_id}", + "user": "{user_id}" + }, + "data": {..}, + "clear": ["{field}", ...] +} +``` + +- `data` field contains a partial Server Member object. +- `{field}` is a field to remove, one of: + - `Nickname` + - `Avatar` + +### ServerMemberJoin + +A user has joined the server. + +```json +{ + "type": "ServerMemberJoin", + "id": "{server_id}", + "user": "{user_id}", + "member": {..} +} +``` + +- `member` field contains a Member object. + +### ServerMemberLeave + +A user has left the server. + +```json +{ + "type": "ServerMemberLeave", + "id": "{server_id}", + "user": "{user_id}" +} +``` + +### ServerRoleUpdate + +Server role has been updated or created. + +```json +{ + "type": "ServerRoleUpdate", + "id": "{server_id}", + "role_id": "{role_id}", + "data": {..}, + "clear": ["{field}", ...] +} +``` + +- `data` field contains a partial Server Role object. +- `clear` is a field to remove, one of: + - `Colour` + +### ServerRoleDelete + +Server role has been deleted. + +```json +{ + "type": "ServerRoleDelete", + "id": "{server_id}", + "role_id": "{role_id}" +} +``` + +### UserUpdate + +User has been updated. + +```json +{ + "type": "UserUpdate", + "id": "{user_id}", + "data": {..}, + "clear": ["{field}", ...] +} +``` + +- `data` field contains a partial User object. +- `clear` is a field to remove, one of: + - `ProfileContent` + - `ProfileBackground` + - `StatusText` + - `Avatar` + - `DisplayName` + +### UserRelationship + +Your relationship with another user has changed. + +```json +{ + "type": "UserRelationship", + "id": "{your_user_id}", + "user": "{..}", + "status": "{status}" +} +``` + +- `user` field contains a User object. +- `status` field matches Relationship Status in API. + +### UserPlatformWipe + +User has been platform banned or deleted their account. + +Clients should remove the following associated data: + +- Messages +- DM Channels +- Relationships +- Server Memberships + +User flags are specified to explain why a wipe is occurring though not all reasons will necessarily ever appear. + +```json +{ + "type": "UserPlatformWipe", + "user_id": "{user_id}", + "flags": "{user_flags}" +} +``` + +### EmojiCreate + +Emoji created, the event object has the same schema as the Emoji object in the API with the addition of an event type. + +```json +{ + "type": "EmojiCreate", + [..] +} +``` + +### EmojiDelete + +Emoji has been deleted. + +```json +{ + "type": "EmojiDelete", + "id": "{emoji_id}" +} +``` + +### Auth + +Forwarded events from [Authifier](https://github.com/authifier/authifier), currently only session deletion events are forwarded. + +```json +{ + "type": "Auth", + "event_type": "{event_type}", + [..] +} +``` + +Event type may be defined as one of the following with the additional properties: + +#### DeleteSession + +A session has been deleted. + +```json +{ + "event_type": "DeleteSession", + "user_id": "{user_id}", + "session_id": "{session_id}" +} +``` + +#### DeleteAllSessions + +All sessions for this account have been deleted, optionally excluding a given ID. + +```json +{ + "event_type": "DeleteAllSessions", + "user_id": "{user_id}", + "exclude_session_id": "{session_id}" +} +``` diff --git a/docs/docs/developers/legacy-plugin-api.md b/docs/docs/developers/legacy-plugin-api.md new file mode 100644 index 000000000..ac5c58fce --- /dev/null +++ b/docs/docs/developers/legacy-plugin-api.md @@ -0,0 +1,147 @@ +# Plugin API + +:::danger +This page documents the old Revite Plugin API (manifest v1), it will be replaced in the new client. +::: + +:::warning +The Plugin API is very powerful. **Tread carefully.** + +**Zero guarantees or sandboxes are provided.** Your code is run as-is. +::: + +This document details the very experimental plugin API available in [Revite](https://github.com/revoltchat/revite). + +This is more or less a proof of concept but can be used to achieve some simple client modifications. + +## Plugin Manifest + +Below is the specification for revision 1 of the plugin API. The `format` parameter is not currently enforced but you should set it to `1` to avoid future breakage. + +````typescript +type Plugin = { + /** + * Plugin Format Revision + */ + format: 1; + + /** + * Semver Version String + * + * This is the version of the plugin. + */ + version: string; + + /** + * Plugin Namespace + * + * This will usually be the author's name. + */ + namespace: string; + + /** + * Plugin Id + * + * This should be a valid URL slug, e.g. cool-plugin. + */ + id: string; + + /** + * Entrypoint + * + * Valid Javascript code. It must be a function which returns a object. + * + * ```typescript + * function (state: State) { + * return { + * onUnload: () => {} + * } + * } + * ``` + */ + entrypoint: string; + + /** + * Whether this plugin is enabled. + * + * @default true + */ + enabled?: boolean; +}; +```` + +An example plugin: + +```javascript +{ + format: 1, + version: "0.0.1", + namespace: "insert", + id: "my-plugin", + entrypoint: `(state) => { + console.log('[my-plugin] Plugin init!'); + return { + onUnload: () => console.log('[my-plugin] bye!') + } + }` +} +``` + +## Using the Plugin API + +To begin, you can load plugins using the global plugin manager at `state.plugins`. + +Open the developer console and run: + +```javascript +state.plugins.load({ ... }); +// ...where [...] is your plugin manifest as described above. +``` + +## Plugin API + +A plugin's entrypoint is required to return an object which is referred to as the **instance**: + +```typescript +interface Instance { + onUnload?: () => void; +} +``` + +The Plugin API (`state.plugins`) exposes the following methods: + +```typescript +interface PluginAPI { + /** + * Add a plugin + * @param plugin Plugin Manifest + */ + add(plugin: Plugin); + + /** + * Remove a plugin + * @param namespace Plugin Namespace + * @param id Plugin Id + */ + remove(namespace: string, id: string); + + /** + * Load a plugin + * @param namespace Plugin Namespace + * @param id Plugin Id + */ + load(namespace: string, id: string); + + /** + * Unload a plugin + * @param namespace Plugin Namespace + * @param id Plugin Id + */ + unload(namespace: string, id: string); + + /** + * Reset everything + */ + reset(); +} +``` diff --git a/docs/docs/developers/libraries.md b/docs/docs/developers/libraries.md new file mode 100644 index 000000000..bda99ae10 --- /dev/null +++ b/docs/docs/developers/libraries.md @@ -0,0 +1,8 @@ +# Libraries + +The following libraries are provided by the Stoat team: + +- [Javascript SDK](https://github.com/stoatchat/javascript-client-sdk) +- [Python SDK](https://github.com/stoatchat/python-client-sdk) + +You can find a host of [community created libraries here](https://github.com/stoatchat/awesome-stoat#-api-libraries). diff --git a/docs/docs/developers/stoat-migration-guide.md b/docs/docs/developers/stoat-migration-guide.md new file mode 100644 index 000000000..c26168b52 --- /dev/null +++ b/docs/docs/developers/stoat-migration-guide.md @@ -0,0 +1,22 @@ +# Stoat Migration Guide + +:::warning + +This is not yet finished. + +::: + +## Endpoint changes + +| Service | Old URL | New URL | +| ---------- | ----------------------------------- | --------------------------------------- | +| **API** | `https://api.revolt.chat` | `https://stoat.chat/api` | +| | `https://app.revolt.chat/api` | `https://stoat.chat/api` | +| | `https://revolt.chat/api` | No equivalent | +| **Events** | `wss://ws.revolt.chat` | `wss://stoat.chat/events` | +| | `wss://app.revolt.chat/events` | `wss://stoat.chat/events` | +| | `wss://revolt.chat/events` | No equivalent | +| **Files** | `https://autumn.revolt.chat` | `https://cdn.stoatusercontent.com` | +| | `https://cdn.revoltusercontent.com` | `https://cdn.stoatusercontent.com` | +| **Proxy** | `https://jan.revolt.chat` | `https://external.stoatusercontent.com` | +| **Voice** | `https://vortex.revolt.chat` | Superseded by Voice Chats v2 | diff --git a/docs/docs/developing/backend/_category_.json b/docs/docs/developing/backend/_category_.json new file mode 100644 index 000000000..dccd5ffc7 --- /dev/null +++ b/docs/docs/developing/backend/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "Backend", + "position": 10, + "link": { + "type": "generated-index", + "description": "Building the Stoat software" + }, + "collapsed": false, + "collapsible": true +} \ No newline at end of file diff --git a/doc/src/new_features.md b/docs/docs/developing/backend/new_features.md similarity index 96% rename from doc/src/new_features.md rename to docs/docs/developing/backend/new_features.md index 82f068a1d..c95171807 100644 --- a/doc/src/new_features.md +++ b/docs/docs/developing/backend/new_features.md @@ -1,4 +1,4 @@ -# New API features +# Adding new API features New API features must be documented where appropriate, this document aims to cover everywhere you need to update for new features. diff --git a/docs/docs/developing/contrib.md b/docs/docs/developing/contrib.md new file mode 100644 index 000000000..39520b513 --- /dev/null +++ b/docs/docs/developing/contrib.md @@ -0,0 +1,45 @@ +--- +sidebar_position: 2 +--- + +# Contribution Guide + +This is the contribution guide for developers wanting to help out with Stoat. + +## Repository Lifecycle + +### Making Commits + +- Sign-off your commits ([Git flag](https://git-scm.com/docs/git-commit#Documentation/git-commit.txt---signoff)), [read here about DCO obligations](https://developercertificate.org/). +- Sign commits where possible, [learn more about that here](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits). +- Prefer to use [Conventional Commit style](https://www.conventionalcommits.org/en/v1.0.0-beta.2/). +- If present, e.g. `prettier`, `cargo fmt`, use the formatter. +- Try to keep each PR bound to a single feature or change, multiple bug fixes may be fine in some cases. + This is to avoid your PR getting stuck due to parts of it having conflicts or other issues. + +### Merging Pull Requests + +All PR titles must use use [Conventional Commit style](https://www.conventionalcommits.org/en/v1.0.0-beta.2/) and will be squash merged! + +## What can I help with? + +Stuff is currently being moved around, for the mean time, come ask in the development server: https://stt.gg/API + +Also typically `help wanted` labels are available on repo issues! + + + +## Project Guidance + +Please read the additional relevant guidance on: + +- [Developing for Backend](https://github.com/stoatchat/backend?tab=readme-ov-file#development-guide) (contrib guide TBA) +- [Contributing to Frontend](https://stoatchat.github.io/for-web/contribution-guide.html) +- [Contributing to Android](https://stoatchat.github.io/for-android/contributing/guidelines/) diff --git a/docs/docs/faq.md b/docs/docs/faq.md new file mode 100644 index 000000000..5f09386e2 --- /dev/null +++ b/docs/docs/faq.md @@ -0,0 +1,109 @@ +--- +sidebar_position: 4 +--- + +# 📖 Frequently Asked Questions + +This page includes several frequently asked questions and explanations. + +All of these answers are written from the perspective of the project owner. + +**Last Update:** 10th May 2024 + +
+ Why another project? + + I think this is best explained with a bit of history: + - Stoat (formerly Revolt) started as a passion project + - It grew way beyond any of our expectations + - We might as well keep going since there is an interest in this space + + Beyond that: + - Stoat has been a great learning experience, including development, management, and running the infrastructure for a large project. Stoat has also taught me a lot about different concepts and programming languages, and really, that's how developers learn. We make cool projects to try to better how we work, it doesn't matter if someone has done it before as long as you can attempt to do the same. Reinventing the wheel is part of the process. + - At the time, there was also a relative void of competition in this specific genre of chat platforms. There were Guilded, Discord, and Matrix but these are all either closed-source or cater to a different audience. + + PS. I've had a few people say, 'why not just contribute to X?', the answer is quite simple, I just didn't know about any of these projects (i.e. Matrix). +
+ +
+ How are we funded? + + Stoat is entirely funded through donations, we have amassed a significant amount of money from donations alone. (financial transparency reports coming soon :tm:) + + The month-to-month income of Stoat covers our operational costs and leaves enough spare to cover yearly expenses and the occassional one-time expense, such as for additional hardware. + + We have monetisation plans lined up for the future, however it is not our intention to paywall existing features, instead where possible we intend to pass down costs such as for file storage or voice bandwidth. +
+ +
+ 'X' feature when? + + Please take a look at [our roadmap on GitHub](https://op.stoatinternal.com/projects/all-of-revolt/gantt?query_id=53). +
+ +
+ Does Stoat have federation? + + As of right now, Stoat does not feature any federation and **it is not in our feature roadmap**. + + However, this does not necessarily mean federation is off the table, possible avenues are: + - Implement our own federation protocol + - Implement a promising up and coming federation protocol, polyproto + - Implement the Matrix protocol (unlikely, obtuse and unstable) + - Implement the XMPP protocol (battle-tested and stable) + + Any federation that is implemented MUST exercise caution in: + - Preventing spam and abuse: moderators should be able to block malicious actors + - Protecting user data: users should be able to redact all of their information and messages +
+ +
+ What can I do with Stoat and how do I self-host? + + In general: + - The Stoat branding is used to represent the platform, stoat.chat. + - You may use the branding as-is to promote the platform and your community on the platform. + - You should not use the branding in order to appear as if you are associated with the Stoat team. + - Please make explicit distinctions between Stoat (the platform, "stoat.chat") and the Stoat software. + - The Stoat software is provided unbranded and only associated by name. + + If you have any concerns or questions, please liase with us at [contact@stoat.chat](mailto:contact@stoat.chat). + + As a third-party platform: + - You **must** provide correct attribution in line with our software licenses: + + If you are using official images (GitHub Packages / Docker Hub), attribution is included. + If you are modifying the software and using it in production, you must publish the changes to the source publicly in line with AGPLv3. (In addition to providing attribution back to the original project.) + - You are **solely responsible** for whatever happens on your third party instance, we provide no warranty or liability for what happens on 3rd party instances. + - You **must not** appear to associate with Stoat / stoat.chat unless if granted explicit written permission. In regards to custom clients, provide a warning of any potential risks or clear it with us. + - You **may not** use any of the Stoat branding or brand assets to advertise or promote your third party instance. + + You can self-host Stoat by: + - Using [Docker Compose and our recommended guide](https://github.com/stoatchat/self-hosted). + - Building individual components yourself from the [source code](https://github.com/stoatchat). +
+ +
+ Can you verify my server/bot? + + Currently, you can only apply to verify servers given that you have a valid reason to believe verification is necessary for your community. Verification is intended to provide protection for server owners from copy cats and to provide authenticity to users as such we are not just giving it out to anyone because that would defeat the purpose. + + However if you would like to get a server verified, you should satisfy one of the following criteria: + + - Official community for a well-established open source project + - Official community for any other well-established product, service, or person + - Large and active distinct pre-existing community + + Distinct means the community is unique and well-known (& has an active presence) off platform. This means we are not currently verifying generic servers that centre around a topic unless if it meets one of the first two criteria. Though in special circumstances, well known on platform communities may also be considered. + + Server verification also comes with a vanity invite, so please have one ready if you want to apply. To apply, drop an email at [contact@stoat.chat](mailto:contact@stoat.chat). + + We also periodically prune verification from servers that have fallen into disrepair and / or otherwise are no longer active. +
+ +For questions about the Stoat platform, you may want to go to our knowledge base: + +- [What badges can I get?](https://support.stoat.chat/kb/account/badges) +- [How old do I have to be to use Stoat?](https://support.stoat.chat/kb/safety/minimum-age-guidelines) +- [Are there any restrictions on servers being on Discover?](https://support.stoat.chat/kb/safety/discover-guidelines) +- [(... and more)](https://support.stoat.chat) diff --git a/docs/docs/help.md b/docs/docs/help.md new file mode 100644 index 000000000..ae95dbf78 --- /dev/null +++ b/docs/docs/help.md @@ -0,0 +1,30 @@ +--- +sidebar_position: 3 +--- + +# 💖 Helping Stoat! + +You can contribute to Stoat in a variety of ways: + +### 1. Feedback + +The easiest, but most important, way to contribute to Stoat is to voice your opinion and give us feedback. +We want to hear what you think and appreciate and await your feature suggestions, bug reports and general opinions on everything Stoat has to offer. + +Typically, you can open issues on the relevant [GitHub repositories](https://github.com/stoatchat). + + + +### 2. Translate + +Stoat is used by users all around the world; as such, it's more accessible if the user interface is available in a variety of languages. +You can contribute translations through [**Weblate**](https://translate.stoat.chat/engage/revolt/). + +### 3. Donate + +Stoat is not backed by a big company, is not currently monetised (for example, via a subscription service) and does not serve you advertisements; as such, Stoat currently relies entirely on donations. +You can learn more about donating [here](https://wiki.revolt.chat/notes/project/financial-support/) - if you want to make a larger donation, please consult me first. + +### 4. Join the project + +We are a small team and always appreciate more help! [Check out roles we're looking for here!](https://outline.stoatinternal.com/s/454dd0eb-44b5-41f7-b1d1-b6accec577a0) diff --git a/docs/docs/index.md b/docs/docs/index.md new file mode 100644 index 000000000..370a2a4bd --- /dev/null +++ b/docs/docs/index.md @@ -0,0 +1,17 @@ +--- +sidebar_position: 1 +--- + +# 🤗 Introduction + +Welcome to Stoat's developer documentation. Everything you need to contribute to Stoat, build apps or bots, or to learn more about the project can be found here. + +Learn more about: + +- [Contributing as a developer](./developing/contrib) +- [Other ways to help out](./help) + +You may also be interested in the: + +- [Frontend Book](https://stoatchat.github.io/for-web) +- [Android Book](https://stoatchat.github.io/for-android) diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts new file mode 100644 index 000000000..9edf29e9b --- /dev/null +++ b/docs/docusaurus.config.ts @@ -0,0 +1,182 @@ +import { themes as prismThemes } from 'prism-react-renderer'; +import type { Config } from '@docusaurus/types'; +import type * as Preset from '@docusaurus/preset-classic'; +import type { ScalarOptions } from '@scalar/docusaurus'; + +const config: Config = { + title: 'Stoat Developers', + tagline: 'Developer documentation for Stoat', + favicon: 'https://stoat.chat/favicon.svg', + + future: { + v4: true, + }, + + url: 'https://developers.stoat.chat', + baseUrl: '/', + + organizationName: 'stoatchat', + projectName: 'stoatchat', + + onBrokenLinks: 'throw', + + i18n: { + defaultLocale: 'en', + locales: ['en'], + }, + + presets: [ + [ + 'classic', + { + docs: { + routeBasePath: '/', + sidebarPath: './sidebars.ts', + editUrl: + 'https://github.com/stoatchat/stoatchat/tree/main/docs/', + }, + } satisfies Preset.Options, + ], + ], + + plugins: [ + [ + '@scalar/docusaurus', + { + label: 'API Reference', + route: '/api-reference', + showNavLink: true, + configuration: { + url: 'https://stoat.chat/api/openapi.json', + }, + } as ScalarOptions, + ], + [ + '@docusaurus/plugin-client-redirects', + { + fromExtensions: ['html', 'htm'], + redirects: [ + // legacy docs website (stoatchat/developer-wiki) + { + from: '/developers/api/reference.html', + to: '/api-reference', + }, + { + from: '/contrib.html', + to: '/developing/contrib', + }, + { + from: '/contrib', + to: '/developing/contrib', + }, + ], + } + ], + ], + + themeConfig: { + // image: 'img/docusaurus-social-card.jpg', + colorMode: { + respectPrefersColorScheme: true, + }, + navbar: { + title: 'Stoat Developers', + logo: { + alt: 'Stoat', + src: 'https://stoat.chat/favicon.svg', + }, + items: [ + { + type: 'doc', + docId: 'index', + label: 'Docs' + }, + { + href: 'https://github.com/stoatchat', + label: 'GitHub', + position: 'right', + }, + ], + }, + footer: { + style: 'dark', + links: [ + { + title: 'Developers', + items: [ + { + label: 'Source Code', + href: 'https://github.com/stoatchat' + }, + { + label: 'Help Translate', + href: 'https://translate.stoat.chat' + }, + ], + }, + { + title: 'Team', + items: [ + { + label: 'About', + href: 'https://stoat.chat/about' + }, + { + label: 'Blog and Changelogs', + href: 'https://stoat.chat/updates' + }, + { + label: 'Contact', + href: 'https://support.stoat.chat' + }, + ], + }, + { + title: 'Stoat on Socials', + items: [ + { + label: 'Bluesky', + href: 'https://bsky.app/profile/stoat.chat' + }, + { + label: 'Reddit', + href: 'https://reddit.com/r/stoatchat' + }, + { + label: 'Stoat Server', + href: 'https://stt.gg/Testers' + }, + ], + }, + { + title: 'Legal', + items: [ + { + label: 'Community Guidelines', + href: 'https://stoat.chat/legal/community-guidelines' + }, + { + label: 'Terms of Service', + href: 'https://stoat.chat/legal/terms' + }, + { + label: 'Privacy Policy', + href: 'https://stoat.chat/legal/privacy' + }, + { + label: 'Imprint', + href: 'https://stoat.chat/legal/imprint' + }, + ], + }, + ], + copyright: `© Revolt Platforms Ltd, ${new Date().getFullYear()}`, + }, + prism: { + theme: prismThemes.github, + darkTheme: prismThemes.dracula, + }, + } satisfies Preset.ThemeConfig, +}; + +export default config; diff --git a/docs/package-lock.json b/docs/package-lock.json new file mode 100644 index 000000000..069f607ce --- /dev/null +++ b/docs/package-lock.json @@ -0,0 +1,18000 @@ +{ + "name": "docs", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "docs", + "version": "0.0.0", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/preset-classic": "3.9.2", + "@mdx-js/react": "^3.0.0", + "clsx": "^2.0.0", + "prism-react-renderer": "^2.3.0", + "react": "^19.0.0", + "react-dom": "^19.0.0" + }, + "devDependencies": { + "@docusaurus/module-type-aliases": "3.9.2", + "@docusaurus/tsconfig": "3.9.2", + "@docusaurus/types": "3.9.2", + "typescript": "~5.6.2" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@ai-sdk/gateway": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@ai-sdk/gateway/-/gateway-2.0.9.tgz", + "integrity": "sha512-E6x4h5CPPPJ0za1r5HsLtHbeI+Tp3H+YFtcH8G3dSSPFE6w+PZINzB4NxLZmg1QqSeA5HTP3ZEzzsohp0o2GEw==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/provider": "2.0.0", + "@ai-sdk/provider-utils": "3.0.17", + "@vercel/oidc": "3.0.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.25.76 || ^4.1.8" + } + }, + "node_modules/@ai-sdk/provider": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@ai-sdk/provider/-/provider-2.0.0.tgz", + "integrity": "sha512-6o7Y2SeO9vFKB8lArHXehNuusnpddKPk7xqL7T2/b+OvXMRIXUO1rR4wcv1hAFUAT9avGZshty3Wlua/XA7TvA==", + "license": "Apache-2.0", + "dependencies": { + "json-schema": "^0.4.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@ai-sdk/provider-utils": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-3.0.17.tgz", + "integrity": "sha512-TR3Gs4I3Tym4Ll+EPdzRdvo/rc8Js6c4nVhFLuvGLX/Y4V9ZcQMa/HTiYsHEgmYrf1zVi6Q145UEZUfleOwOjw==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/provider": "2.0.0", + "@standard-schema/spec": "^1.0.0", + "eventsource-parser": "^3.0.6" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.25.76 || ^4.1.8" + } + }, + "node_modules/@ai-sdk/react": { + "version": "2.0.93", + "resolved": "https://registry.npmjs.org/@ai-sdk/react/-/react-2.0.93.tgz", + "integrity": "sha512-2TzhpQr10HuWxpqyHpSAUMRUqD1G2O73J2sAaJChomVDbjr7BwpM0mdR3aRamCXNtuLiJmTFQhbNzw8fXMBdYw==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/provider-utils": "3.0.17", + "ai": "5.0.93", + "swr": "^2.2.5", + "throttleit": "2.1.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "react": "^18 || ^19 || ^19.0.0-rc", + "zod": "^3.25.76 || ^4.1.8" + }, + "peerDependenciesMeta": { + "zod": { + "optional": true + } + } + }, + "node_modules/@algolia/abtesting": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.9.0.tgz", + "integrity": "sha512-4q9QCxFPiDIx1n5w41A1JMkrXI8p0ugCQnCGFtCKZPmWtwgWCqwVRncIbp++81xSELFZVQUfiB7Kbsla1tIBSw==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.43.0", + "@algolia/requester-browser-xhr": "5.43.0", + "@algolia/requester-fetch": "5.43.0", + "@algolia/requester-node-http": "5.43.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/autocomplete-core": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.19.2.tgz", + "integrity": "sha512-mKv7RyuAzXvwmq+0XRK8HqZXt9iZ5Kkm2huLjgn5JoCPtDy+oh9yxUMfDDaVCw0oyzZ1isdJBc7l9nuCyyR7Nw==", + "license": "MIT", + "dependencies": { + "@algolia/autocomplete-plugin-algolia-insights": "1.19.2", + "@algolia/autocomplete-shared": "1.19.2" + } + }, + "node_modules/@algolia/autocomplete-plugin-algolia-insights": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.19.2.tgz", + "integrity": "sha512-TjxbcC/r4vwmnZaPwrHtkXNeqvlpdyR+oR9Wi2XyfORkiGkLTVhX2j+O9SaCCINbKoDfc+c2PB8NjfOnz7+oKg==", + "license": "MIT", + "dependencies": { + "@algolia/autocomplete-shared": "1.19.2" + }, + "peerDependencies": { + "search-insights": ">= 1 < 3" + } + }, + "node_modules/@algolia/autocomplete-shared": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.19.2.tgz", + "integrity": "sha512-jEazxZTVD2nLrC+wYlVHQgpBoBB5KPStrJxLzsIFl6Kqd1AlG9sIAGl39V5tECLpIQzB3Qa2T6ZPJ1ChkwMK/w==", + "license": "MIT", + "peerDependencies": { + "@algolia/client-search": ">= 4.9.1 < 6", + "algoliasearch": ">= 4.9.1 < 6" + } + }, + "node_modules/@algolia/client-abtesting": { + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.43.0.tgz", + "integrity": "sha512-YsKYkohIMxiYEAu8nppZi5EioYDUIo9Heoor8K8vMUnkUtGCOEU/Q4p5OWaYSSBx3evo09Ga9rG4jsKViIcDzQ==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.43.0", + "@algolia/requester-browser-xhr": "5.43.0", + "@algolia/requester-fetch": "5.43.0", + "@algolia/requester-node-http": "5.43.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-analytics": { + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.43.0.tgz", + "integrity": "sha512-kDGJWt3nzf0nu5RPFXQhNGl6Q0cn35fazxVWXhd0Fw3Vo6gcVfrcezcBenHb66laxnVJ7uwr1uKhmsu3Wy25sQ==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.43.0", + "@algolia/requester-browser-xhr": "5.43.0", + "@algolia/requester-fetch": "5.43.0", + "@algolia/requester-node-http": "5.43.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-common": { + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.43.0.tgz", + "integrity": "sha512-RAFipkAnI8xhL/Sgi/gpXgNWN5HDM6F7z4NNNOcI8ZMYysZEBsqVXojg/WdKEKkQCOHVTZ3mooIjc5BaQdyVtA==", + "license": "MIT", + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-insights": { + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.43.0.tgz", + "integrity": "sha512-PmVs83THco8Qig3cAjU9a5eAGaSxsfgh7PdmWMQFE/MCmIcLPv0MVpgfcGGyPjZGYvPC4cg+3q7JJxcNSsEaTg==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.43.0", + "@algolia/requester-browser-xhr": "5.43.0", + "@algolia/requester-fetch": "5.43.0", + "@algolia/requester-node-http": "5.43.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-personalization": { + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.43.0.tgz", + "integrity": "sha512-Bs4zMLXvkAr19FSOZWNizlNUpRFxZVxtvyEJ+q3n3+hPZUcKjo0LIh15qghhRcQPEihjBN6Gr/U+AqRfOCsvnA==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.43.0", + "@algolia/requester-browser-xhr": "5.43.0", + "@algolia/requester-fetch": "5.43.0", + "@algolia/requester-node-http": "5.43.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-query-suggestions": { + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.43.0.tgz", + "integrity": "sha512-pwHv+z8TZAKbwAWt9+v2gIqlqcCFiMdteTdgdPn2yOBRx4WUQdsIWAaG9GiV3by8jO51FuFQnTohhauuI63y3A==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.43.0", + "@algolia/requester-browser-xhr": "5.43.0", + "@algolia/requester-fetch": "5.43.0", + "@algolia/requester-node-http": "5.43.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-search": { + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.43.0.tgz", + "integrity": "sha512-wKy6x6fKcnB1CsfeNNdGp4dzLzz04k8II3JLt6Sp81F8s57Ks3/K9qsysmL9SJa8P486s719bBttVLE8JJYurQ==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.43.0", + "@algolia/requester-browser-xhr": "5.43.0", + "@algolia/requester-fetch": "5.43.0", + "@algolia/requester-node-http": "5.43.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/events": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz", + "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==", + "license": "MIT" + }, + "node_modules/@algolia/ingestion": { + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.43.0.tgz", + "integrity": "sha512-TA21h2KwqCUyPXhSAWF3R2UES/FAnzjaVPDI6cRPXeadX+pdrGN0GWat5gSUATJVcMHECn+lGvuMMRxO86o2Pg==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.43.0", + "@algolia/requester-browser-xhr": "5.43.0", + "@algolia/requester-fetch": "5.43.0", + "@algolia/requester-node-http": "5.43.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/monitoring": { + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.43.0.tgz", + "integrity": "sha512-rvWVEiA1iLcFmHS3oIXGIBreHIxNZqEFDjiNyRtLEffgd62kul2DjXM7H5bOouDMTo1ywMWT9OeQnzrhlTGAwA==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.43.0", + "@algolia/requester-browser-xhr": "5.43.0", + "@algolia/requester-fetch": "5.43.0", + "@algolia/requester-node-http": "5.43.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/recommend": { + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.43.0.tgz", + "integrity": "sha512-scCijGd38npvH2uHbYhO4f1SR8It5R2FZqOjNcMfw/7Ph7Hxvl+cd7Mo6RzIxsNRcLW5RrwjtpTK3gpDe8r/WQ==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.43.0", + "@algolia/requester-browser-xhr": "5.43.0", + "@algolia/requester-fetch": "5.43.0", + "@algolia/requester-node-http": "5.43.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-browser-xhr": { + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.43.0.tgz", + "integrity": "sha512-jMkRLWJYr4Hcmpl89e4vIWs69Mkf8Uwx7MG5ZKk2UxW3G3TmouGjI0Ph5mVPmg3Jf1UG3AdmVDc4XupzycT1Jw==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.43.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-fetch": { + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.43.0.tgz", + "integrity": "sha512-KyQiVz+HdYtissC0J9KIGhHhKytQyJX+82GVsbv5rSCXbETnAoojvUyCn+3KRtWUvMDYCsZ+Y7hM71STTUJUJg==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.43.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-node-http": { + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.43.0.tgz", + "integrity": "sha512-UnUBNY0U+oT0bkYDsEqVsCkErC2w7idk4CRiLSzicqY8tGylD9oP0j13X/fse1CuiAFCCr3jfl+cBlN6dC0OFw==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.43.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", + "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", + "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", + "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.5.tgz", + "integrity": "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-member-expression-to-functions": "^7.28.5", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.28.5", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz", + "integrity": "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "regexpu-core": "^6.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz", + "integrity": "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "debug": "^4.4.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.22.10" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", + "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", + "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", + "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-wrap-function": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", + "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", + "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.3.tgz", + "integrity": "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.3", + "@babel/types": "^7.28.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.5" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz", + "integrity": "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz", + "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz", + "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", + "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.3.tgz", + "integrity": "sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz", + "integrity": "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", + "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", + "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", + "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", + "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz", + "integrity": "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-remap-async-to-generator": "^7.27.1", + "@babel/traverse": "^7.28.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz", + "integrity": "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-remap-async-to-generator": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", + "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.5.tgz", + "integrity": "sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz", + "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.3.tgz", + "integrity": "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.28.3", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz", + "integrity": "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-globals": "^7.28.0", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/traverse": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz", + "integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/template": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz", + "integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz", + "integrity": "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", + "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz", + "integrity": "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz", + "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-explicit-resource-management": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.0.tgz", + "integrity": "sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.5.tgz", + "integrity": "sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", + "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", + "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", + "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz", + "integrity": "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", + "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.5.tgz", + "integrity": "sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", + "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", + "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", + "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz", + "integrity": "sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", + "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz", + "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", + "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz", + "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz", + "integrity": "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz", + "integrity": "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.0", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/traverse": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", + "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz", + "integrity": "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.5.tgz", + "integrity": "sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.27.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", + "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz", + "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz", + "integrity": "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", + "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-constant-elements": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.27.1.tgz", + "integrity": "sha512-edoidOjl/ZxvYo4lSBOQGDSyToYVkTAwyVoa2tkuYTSmjrB1+uAedoL5iROVLXkxH+vRgA7uP4tMg2pUJpZ3Ug==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.28.0.tgz", + "integrity": "sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.27.1.tgz", + "integrity": "sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.27.1.tgz", + "integrity": "sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==", + "license": "MIT", + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.27.1.tgz", + "integrity": "sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz", + "integrity": "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz", + "integrity": "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", + "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.28.5.tgz", + "integrity": "sha512-20NUVgOrinudkIBzQ2bNxP08YpKprUkRTiRSd2/Z5GOdPImJGkoN4Z7IQe1T5AdyKI1i5L6RBmluqdSzvaq9/w==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "babel-plugin-polyfill-corejs2": "^0.4.14", + "babel-plugin-polyfill-corejs3": "^0.13.0", + "babel-plugin-polyfill-regenerator": "^0.6.5", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", + "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz", + "integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", + "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", + "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", + "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.5.tgz", + "integrity": "sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", + "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz", + "integrity": "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", + "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz", + "integrity": "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.5.tgz", + "integrity": "sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.5", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.3", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.27.1", + "@babel/plugin-syntax-import-attributes": "^7.27.1", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.27.1", + "@babel/plugin-transform-async-generator-functions": "^7.28.0", + "@babel/plugin-transform-async-to-generator": "^7.27.1", + "@babel/plugin-transform-block-scoped-functions": "^7.27.1", + "@babel/plugin-transform-block-scoping": "^7.28.5", + "@babel/plugin-transform-class-properties": "^7.27.1", + "@babel/plugin-transform-class-static-block": "^7.28.3", + "@babel/plugin-transform-classes": "^7.28.4", + "@babel/plugin-transform-computed-properties": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.5", + "@babel/plugin-transform-dotall-regex": "^7.27.1", + "@babel/plugin-transform-duplicate-keys": "^7.27.1", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-dynamic-import": "^7.27.1", + "@babel/plugin-transform-explicit-resource-management": "^7.28.0", + "@babel/plugin-transform-exponentiation-operator": "^7.28.5", + "@babel/plugin-transform-export-namespace-from": "^7.27.1", + "@babel/plugin-transform-for-of": "^7.27.1", + "@babel/plugin-transform-function-name": "^7.27.1", + "@babel/plugin-transform-json-strings": "^7.27.1", + "@babel/plugin-transform-literals": "^7.27.1", + "@babel/plugin-transform-logical-assignment-operators": "^7.28.5", + "@babel/plugin-transform-member-expression-literals": "^7.27.1", + "@babel/plugin-transform-modules-amd": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.27.1", + "@babel/plugin-transform-modules-systemjs": "^7.28.5", + "@babel/plugin-transform-modules-umd": "^7.27.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-new-target": "^7.27.1", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", + "@babel/plugin-transform-numeric-separator": "^7.27.1", + "@babel/plugin-transform-object-rest-spread": "^7.28.4", + "@babel/plugin-transform-object-super": "^7.27.1", + "@babel/plugin-transform-optional-catch-binding": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.28.5", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/plugin-transform-private-methods": "^7.27.1", + "@babel/plugin-transform-private-property-in-object": "^7.27.1", + "@babel/plugin-transform-property-literals": "^7.27.1", + "@babel/plugin-transform-regenerator": "^7.28.4", + "@babel/plugin-transform-regexp-modifiers": "^7.27.1", + "@babel/plugin-transform-reserved-words": "^7.27.1", + "@babel/plugin-transform-shorthand-properties": "^7.27.1", + "@babel/plugin-transform-spread": "^7.27.1", + "@babel/plugin-transform-sticky-regex": "^7.27.1", + "@babel/plugin-transform-template-literals": "^7.27.1", + "@babel/plugin-transform-typeof-symbol": "^7.27.1", + "@babel/plugin-transform-unicode-escapes": "^7.27.1", + "@babel/plugin-transform-unicode-property-regex": "^7.27.1", + "@babel/plugin-transform-unicode-regex": "^7.27.1", + "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.14", + "babel-plugin-polyfill-corejs3": "^0.13.0", + "babel-plugin-polyfill-regenerator": "^0.6.5", + "core-js-compat": "^3.43.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-react": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.28.5.tgz", + "integrity": "sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-transform-react-display-name": "^7.28.0", + "@babel/plugin-transform-react-jsx": "^7.27.1", + "@babel/plugin-transform-react-jsx-development": "^7.27.1", + "@babel/plugin-transform-react-pure-annotations": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.28.5.tgz", + "integrity": "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.27.1", + "@babel/plugin-transform-typescript": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", + "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime-corejs3": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.28.4.tgz", + "integrity": "sha512-h7iEYiW4HebClDEhtvFObtPmIvrd1SSfpI9EhOeKk4CtIK/ngBWFpuhCzhdmRKtg71ylcue+9I6dv54XYO1epQ==", + "license": "MIT", + "dependencies": { + "core-js-pure": "^3.43.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", + "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.5", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@csstools/cascade-layer-name-parser": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-2.0.5.tgz", + "integrity": "sha512-p1ko5eHgV+MgXFVa4STPKpvPxr6ReS8oS2jzTukjR74i5zJNyWO1ZM1m8YKBXnzDKWfBN1ztLYlHxbVemDD88A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/color-helpers": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", + "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-calc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", + "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", + "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^5.1.0", + "@csstools/css-calc": "^2.1.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", + "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/media-query-list-parser": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.3.tgz", + "integrity": "sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/postcss-alpha-function": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-alpha-function/-/postcss-alpha-function-1.0.1.tgz", + "integrity": "sha512-isfLLwksH3yHkFXfCI2Gcaqg7wGGHZZwunoJzEZk0yKYIokgre6hYVFibKL3SYAoR1kBXova8LB+JoO5vZzi9w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-cascade-layers": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-5.0.2.tgz", + "integrity": "sha512-nWBE08nhO8uWl6kSAeCx4im7QfVko3zLrtgWZY4/bP87zrSPpSyN/3W3TDqz1jJuH+kbKOHXg5rJnK+ZVYcFFg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/selector-specificity": "^5.0.0", + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-cascade-layers/node_modules/@csstools/selector-specificity": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", + "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/@csstools/postcss-cascade-layers/node_modules/postcss-selector-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@csstools/postcss-color-function": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-4.0.12.tgz", + "integrity": "sha512-yx3cljQKRaSBc2hfh8rMZFZzChaFgwmO2JfFgFr1vMcF3C/uyy5I4RFIBOIWGq1D+XbKCG789CGkG6zzkLpagA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-color-function-display-p3-linear": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function-display-p3-linear/-/postcss-color-function-display-p3-linear-1.0.1.tgz", + "integrity": "sha512-E5qusdzhlmO1TztYzDIi8XPdPoYOjoTY6HBYBCYSj+Gn4gQRBlvjgPQXzfzuPQqt8EhkC/SzPKObg4Mbn8/xMg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-color-mix-function": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-mix-function/-/postcss-color-mix-function-3.0.12.tgz", + "integrity": "sha512-4STERZfCP5Jcs13P1U5pTvI9SkgLgfMUMhdXW8IlJWkzOOOqhZIjcNhWtNJZes2nkBDsIKJ0CJtFtuaZ00moag==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-color-mix-variadic-function-arguments": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-mix-variadic-function-arguments/-/postcss-color-mix-variadic-function-arguments-1.0.2.tgz", + "integrity": "sha512-rM67Gp9lRAkTo+X31DUqMEq+iK+EFqsidfecmhrteErxJZb6tUoJBVQca1Vn1GpDql1s1rD1pKcuYzMsg7Z1KQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-content-alt-text": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@csstools/postcss-content-alt-text/-/postcss-content-alt-text-2.0.8.tgz", + "integrity": "sha512-9SfEW9QCxEpTlNMnpSqFaHyzsiRpZ5J5+KqCu1u5/eEJAWsMhzT40qf0FIbeeglEvrGRMdDzAxMIz3wqoGSb+Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-contrast-color-function": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@csstools/postcss-contrast-color-function/-/postcss-contrast-color-function-2.0.12.tgz", + "integrity": "sha512-YbwWckjK3qwKjeYz/CijgcS7WDUCtKTd8ShLztm3/i5dhh4NaqzsbYnhm4bjrpFpnLZ31jVcbK8YL77z3GBPzA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-exponential-functions": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@csstools/postcss-exponential-functions/-/postcss-exponential-functions-2.0.9.tgz", + "integrity": "sha512-abg2W/PI3HXwS/CZshSa79kNWNZHdJPMBXeZNyPQFbbj8sKO3jXxOt/wF7juJVjyDTc6JrvaUZYFcSBZBhaxjw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-font-format-keywords": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-4.0.0.tgz", + "integrity": "sha512-usBzw9aCRDvchpok6C+4TXC57btc4bJtmKQWOHQxOVKen1ZfVqBUuCZ/wuqdX5GHsD0NRSr9XTP+5ID1ZZQBXw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-gamut-mapping": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@csstools/postcss-gamut-mapping/-/postcss-gamut-mapping-2.0.11.tgz", + "integrity": "sha512-fCpCUgZNE2piVJKC76zFsgVW1apF6dpYsqGyH8SIeCcM4pTEsRTWTLCaJIMKFEundsCKwY1rwfhtrio04RJ4Dw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-gradients-interpolation-method": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/@csstools/postcss-gradients-interpolation-method/-/postcss-gradients-interpolation-method-5.0.12.tgz", + "integrity": "sha512-jugzjwkUY0wtNrZlFeyXzimUL3hN4xMvoPnIXxoZqxDvjZRiSh+itgHcVUWzJ2VwD/VAMEgCLvtaJHX+4Vj3Ow==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-hwb-function": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-4.0.12.tgz", + "integrity": "sha512-mL/+88Z53KrE4JdePYFJAQWFrcADEqsLprExCM04GDNgHIztwFzj0Mbhd/yxMBngq0NIlz58VVxjt5abNs1VhA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-ic-unit": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-4.0.4.tgz", + "integrity": "sha512-yQ4VmossuOAql65sCPppVO1yfb7hDscf4GseF0VCA/DTDaBc0Wtf8MTqVPfjGYlT5+2buokG0Gp7y0atYZpwjg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-initial": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-initial/-/postcss-initial-2.0.1.tgz", + "integrity": "sha512-L1wLVMSAZ4wovznquK0xmC7QSctzO4D0Is590bxpGqhqjboLXYA16dWZpfwImkdOgACdQ9PqXsuRroW6qPlEsg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-is-pseudo-class": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-5.0.3.tgz", + "integrity": "sha512-jS/TY4SpG4gszAtIg7Qnf3AS2pjcUM5SzxpApOrlndMeGhIbaTzWBzzP/IApXoNWEW7OhcjkRT48jnAUIFXhAQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/selector-specificity": "^5.0.0", + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-is-pseudo-class/node_modules/@csstools/selector-specificity": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", + "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/@csstools/postcss-is-pseudo-class/node_modules/postcss-selector-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@csstools/postcss-light-dark-function": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@csstools/postcss-light-dark-function/-/postcss-light-dark-function-2.0.11.tgz", + "integrity": "sha512-fNJcKXJdPM3Lyrbmgw2OBbaioU7yuKZtiXClf4sGdQttitijYlZMD5K7HrC/eF83VRWRrYq6OZ0Lx92leV2LFA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-float-and-clear": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-float-and-clear/-/postcss-logical-float-and-clear-3.0.0.tgz", + "integrity": "sha512-SEmaHMszwakI2rqKRJgE+8rpotFfne1ZS6bZqBoQIicFyV+xT1UF42eORPxJkVJVrH9C0ctUgwMSn3BLOIZldQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-overflow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-overflow/-/postcss-logical-overflow-2.0.0.tgz", + "integrity": "sha512-spzR1MInxPuXKEX2csMamshR4LRaSZ3UXVaRGjeQxl70ySxOhMpP2252RAFsg8QyyBXBzuVOOdx1+bVO5bPIzA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-overscroll-behavior": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-overscroll-behavior/-/postcss-logical-overscroll-behavior-2.0.0.tgz", + "integrity": "sha512-e/webMjoGOSYfqLunyzByZj5KKe5oyVg/YSbie99VEaSDE2kimFm0q1f6t/6Jo+VVCQ/jbe2Xy+uX+C4xzWs4w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-resize": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-resize/-/postcss-logical-resize-3.0.0.tgz", + "integrity": "sha512-DFbHQOFW/+I+MY4Ycd/QN6Dg4Hcbb50elIJCfnwkRTCX05G11SwViI5BbBlg9iHRl4ytB7pmY5ieAFk3ws7yyg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-viewport-units": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-viewport-units/-/postcss-logical-viewport-units-3.0.4.tgz", + "integrity": "sha512-q+eHV1haXA4w9xBwZLKjVKAWn3W2CMqmpNpZUk5kRprvSiBEGMgrNH3/sJZ8UA3JgyHaOt3jwT9uFa4wLX4EqQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-media-minmax": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@csstools/postcss-media-minmax/-/postcss-media-minmax-2.0.9.tgz", + "integrity": "sha512-af9Qw3uS3JhYLnCbqtZ9crTvvkR+0Se+bBqSr7ykAnl9yKhk6895z9rf+2F4dClIDJWxgn0iZZ1PSdkhrbs2ig==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/media-query-list-parser": "^4.0.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-media-queries-aspect-ratio-number-values": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/postcss-media-queries-aspect-ratio-number-values/-/postcss-media-queries-aspect-ratio-number-values-3.0.5.tgz", + "integrity": "sha512-zhAe31xaaXOY2Px8IYfoVTB3wglbJUVigGphFLj6exb7cjZRH9A6adyE22XfFK3P2PzwRk0VDeTJmaxpluyrDg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/media-query-list-parser": "^4.0.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-nested-calc": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-4.0.0.tgz", + "integrity": "sha512-jMYDdqrQQxE7k9+KjstC3NbsmC063n1FTPLCgCRS2/qHUbHM0mNy9pIn4QIiQGs9I/Bg98vMqw7mJXBxa0N88A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-normalize-display-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.0.tgz", + "integrity": "sha512-HlEoG0IDRoHXzXnkV4in47dzsxdsjdz6+j7MLjaACABX2NfvjFS6XVAnpaDyGesz9gK2SC7MbNwdCHusObKJ9Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-oklab-function": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-4.0.12.tgz", + "integrity": "sha512-HhlSmnE1NKBhXsTnNGjxvhryKtO7tJd1w42DKOGFD6jSHtYOrsJTQDKPMwvOfrzUAk8t7GcpIfRyM7ssqHpFjg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-progressive-custom-properties": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-4.2.1.tgz", + "integrity": "sha512-uPiiXf7IEKtUQXsxu6uWtOlRMXd2QWWy5fhxHDnPdXKCQckPP3E34ZgDoZ62r2iT+UOgWsSbM4NvHE5m3mAEdw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-random-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-random-function/-/postcss-random-function-2.0.1.tgz", + "integrity": "sha512-q+FQaNiRBhnoSNo+GzqGOIBKoHQ43lYz0ICrV+UudfWnEF6ksS6DsBIJSISKQT2Bvu3g4k6r7t0zYrk5pDlo8w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-relative-color-syntax": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@csstools/postcss-relative-color-syntax/-/postcss-relative-color-syntax-3.0.12.tgz", + "integrity": "sha512-0RLIeONxu/mtxRtf3o41Lq2ghLimw0w9ByLWnnEVuy89exmEEq8bynveBxNW3nyHqLAFEeNtVEmC1QK9MZ8Huw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-scope-pseudo-class": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-scope-pseudo-class/-/postcss-scope-pseudo-class-4.0.1.tgz", + "integrity": "sha512-IMi9FwtH6LMNuLea1bjVMQAsUhFxJnyLSgOp/cpv5hrzWmrUYU5fm0EguNDIIOHUqzXode8F/1qkC/tEo/qN8Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-scope-pseudo-class/node_modules/postcss-selector-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@csstools/postcss-sign-functions": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@csstools/postcss-sign-functions/-/postcss-sign-functions-1.1.4.tgz", + "integrity": "sha512-P97h1XqRPcfcJndFdG95Gv/6ZzxUBBISem0IDqPZ7WMvc/wlO+yU0c5D/OCpZ5TJoTt63Ok3knGk64N+o6L2Pg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-stepped-value-functions": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-4.0.9.tgz", + "integrity": "sha512-h9btycWrsex4dNLeQfyU3y3w40LMQooJWFMm/SK9lrKguHDcFl4VMkncKKoXi2z5rM9YGWbUQABI8BT2UydIcA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-text-decoration-shorthand": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-4.0.3.tgz", + "integrity": "sha512-KSkGgZfx0kQjRIYnpsD7X2Om9BUXX/Kii77VBifQW9Ih929hK0KNjVngHDH0bFB9GmfWcR9vJYJJRvw/NQjkrA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/color-helpers": "^5.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-trigonometric-functions": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-4.0.9.tgz", + "integrity": "sha512-Hnh5zJUdpNrJqK9v1/E3BbrQhaDTj5YiX7P61TOvUhoDHnUmsNNxcDAgkQ32RrcWx9GVUvfUNPcUkn8R3vIX6A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-unset-value": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-4.0.0.tgz", + "integrity": "sha512-cBz3tOCI5Fw6NIFEwU3RiwK6mn3nKegjpJuzCndoGq3BZPkUjnsq7uQmIeMNeMbMk7YD2MfKcgCpZwX5jyXqCA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/utilities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@csstools/utilities/-/utilities-2.0.0.tgz", + "integrity": "sha512-5VdOr0Z71u+Yp3ozOx8T11N703wIFGVRgOWbOZMKgglPJsWA54MRIoMNVMa7shUToIhx5J8vX4sOZgD2XiihiQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@docsearch/core": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@docsearch/core/-/core-4.3.1.tgz", + "integrity": "sha512-ktVbkePE+2h9RwqCUMbWXOoebFyDOxHqImAqfs+lC8yOU+XwEW4jgvHGJK079deTeHtdhUNj0PXHSnhJINvHzQ==", + "license": "MIT", + "peerDependencies": { + "@types/react": ">= 16.8.0 < 20.0.0", + "react": ">= 16.8.0 < 20.0.0", + "react-dom": ">= 16.8.0 < 20.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/@docsearch/css": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-4.3.2.tgz", + "integrity": "sha512-K3Yhay9MgkBjJJ0WEL5MxnACModX9xuNt3UlQQkDEDZJZ0+aeWKtOkxHNndMRkMBnHdYvQjxkm6mdlneOtU1IQ==", + "license": "MIT" + }, + "node_modules/@docsearch/react": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-4.3.2.tgz", + "integrity": "sha512-74SFD6WluwvgsOPqifYOviEEVwDxslxfhakTlra+JviaNcs7KK/rjsPj89kVEoQc9FUxRkAofaJnHIR7pb4TSQ==", + "license": "MIT", + "dependencies": { + "@ai-sdk/react": "^2.0.30", + "@algolia/autocomplete-core": "1.19.2", + "@docsearch/core": "4.3.1", + "@docsearch/css": "4.3.2", + "ai": "^5.0.30", + "algoliasearch": "^5.28.0", + "marked": "^16.3.0", + "zod": "^4.1.8" + }, + "peerDependencies": { + "@types/react": ">= 16.8.0 < 20.0.0", + "react": ">= 16.8.0 < 20.0.0", + "react-dom": ">= 16.8.0 < 20.0.0", + "search-insights": ">= 1 < 3" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "search-insights": { + "optional": true + } + } + }, + "node_modules/@docusaurus/babel": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/babel/-/babel-3.9.2.tgz", + "integrity": "sha512-GEANdi/SgER+L7Japs25YiGil/AUDnFFHaCGPBbundxoWtCkA2lmy7/tFmgED4y1htAy6Oi4wkJEQdGssnw9MA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-transform-runtime": "^7.25.9", + "@babel/preset-env": "^7.25.9", + "@babel/preset-react": "^7.25.9", + "@babel/preset-typescript": "^7.25.9", + "@babel/runtime": "^7.25.9", + "@babel/runtime-corejs3": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@docusaurus/logger": "3.9.2", + "@docusaurus/utils": "3.9.2", + "babel-plugin-dynamic-import-node": "^2.3.3", + "fs-extra": "^11.1.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/bundler": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/bundler/-/bundler-3.9.2.tgz", + "integrity": "sha512-ZOVi6GYgTcsZcUzjblpzk3wH1Fya2VNpd5jtHoCCFcJlMQ1EYXZetfAnRHLcyiFeBABaI1ltTYbOBtH/gahGVA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.25.9", + "@docusaurus/babel": "3.9.2", + "@docusaurus/cssnano-preset": "3.9.2", + "@docusaurus/logger": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "babel-loader": "^9.2.1", + "clean-css": "^5.3.3", + "copy-webpack-plugin": "^11.0.0", + "css-loader": "^6.11.0", + "css-minimizer-webpack-plugin": "^5.0.1", + "cssnano": "^6.1.2", + "file-loader": "^6.2.0", + "html-minifier-terser": "^7.2.0", + "mini-css-extract-plugin": "^2.9.2", + "null-loader": "^4.0.1", + "postcss": "^8.5.4", + "postcss-loader": "^7.3.4", + "postcss-preset-env": "^10.2.1", + "terser-webpack-plugin": "^5.3.9", + "tslib": "^2.6.0", + "url-loader": "^4.1.1", + "webpack": "^5.95.0", + "webpackbar": "^6.0.1" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "@docusaurus/faster": "*" + }, + "peerDependenciesMeta": { + "@docusaurus/faster": { + "optional": true + } + } + }, + "node_modules/@docusaurus/core": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.9.2.tgz", + "integrity": "sha512-HbjwKeC+pHUFBfLMNzuSjqFE/58+rLVKmOU3lxQrpsxLBOGosYco/Q0GduBb0/jEMRiyEqjNT/01rRdOMWq5pw==", + "license": "MIT", + "dependencies": { + "@docusaurus/babel": "3.9.2", + "@docusaurus/bundler": "3.9.2", + "@docusaurus/logger": "3.9.2", + "@docusaurus/mdx-loader": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "boxen": "^6.2.1", + "chalk": "^4.1.2", + "chokidar": "^3.5.3", + "cli-table3": "^0.6.3", + "combine-promises": "^1.1.0", + "commander": "^5.1.0", + "core-js": "^3.31.1", + "detect-port": "^1.5.1", + "escape-html": "^1.0.3", + "eta": "^2.2.0", + "eval": "^0.1.8", + "execa": "5.1.1", + "fs-extra": "^11.1.1", + "html-tags": "^3.3.1", + "html-webpack-plugin": "^5.6.0", + "leven": "^3.1.0", + "lodash": "^4.17.21", + "open": "^8.4.0", + "p-map": "^4.0.0", + "prompts": "^2.4.2", + "react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0", + "react-loadable": "npm:@docusaurus/react-loadable@6.0.0", + "react-loadable-ssr-addon-v5-slorber": "^1.0.1", + "react-router": "^5.3.4", + "react-router-config": "^5.1.1", + "react-router-dom": "^5.3.4", + "semver": "^7.5.4", + "serve-handler": "^6.1.6", + "tinypool": "^1.0.2", + "tslib": "^2.6.0", + "update-notifier": "^6.0.2", + "webpack": "^5.95.0", + "webpack-bundle-analyzer": "^4.10.2", + "webpack-dev-server": "^5.2.2", + "webpack-merge": "^6.0.1" + }, + "bin": { + "docusaurus": "bin/docusaurus.mjs" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "@mdx-js/react": "^3.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/cssnano-preset": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.9.2.tgz", + "integrity": "sha512-8gBKup94aGttRduABsj7bpPFTX7kbwu+xh3K9NMCF5K4bWBqTFYW+REKHF6iBVDHRJ4grZdIPbvkiHd/XNKRMQ==", + "license": "MIT", + "dependencies": { + "cssnano-preset-advanced": "^6.1.2", + "postcss": "^8.5.4", + "postcss-sort-media-queries": "^5.2.0", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/logger": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.9.2.tgz", + "integrity": "sha512-/SVCc57ByARzGSU60c50rMyQlBuMIJCjcsJlkphxY6B0GV4UH3tcA1994N8fFfbJ9kX3jIBe/xg3XP5qBtGDbA==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/mdx-loader": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.9.2.tgz", + "integrity": "sha512-wiYoGwF9gdd6rev62xDU8AAM8JuLI/hlwOtCzMmYcspEkzecKrP8J8X+KpYnTlACBUUtXNJpSoCwFWJhLRevzQ==", + "license": "MIT", + "dependencies": { + "@docusaurus/logger": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "@mdx-js/mdx": "^3.0.0", + "@slorber/remark-comment": "^1.0.0", + "escape-html": "^1.0.3", + "estree-util-value-to-estree": "^3.0.1", + "file-loader": "^6.2.0", + "fs-extra": "^11.1.1", + "image-size": "^2.0.2", + "mdast-util-mdx": "^3.0.0", + "mdast-util-to-string": "^4.0.0", + "rehype-raw": "^7.0.0", + "remark-directive": "^3.0.0", + "remark-emoji": "^4.0.0", + "remark-frontmatter": "^5.0.0", + "remark-gfm": "^4.0.0", + "stringify-object": "^3.3.0", + "tslib": "^2.6.0", + "unified": "^11.0.3", + "unist-util-visit": "^5.0.0", + "url-loader": "^4.1.1", + "vfile": "^6.0.1", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/module-type-aliases": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.9.2.tgz", + "integrity": "sha512-8qVe2QA9hVLzvnxP46ysuofJUIc/yYQ82tvA/rBTrnpXtCjNSFLxEZfd5U8cYZuJIVlkPxamsIgwd5tGZXfvew==", + "license": "MIT", + "dependencies": { + "@docusaurus/types": "3.9.2", + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router-config": "*", + "@types/react-router-dom": "*", + "react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0", + "react-loadable": "npm:@docusaurus/react-loadable@6.0.0" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/@docusaurus/plugin-content-blog": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.9.2.tgz", + "integrity": "sha512-3I2HXy3L1QcjLJLGAoTvoBnpOwa6DPUa3Q0dMK19UTY9mhPkKQg/DYhAGTiBUKcTR0f08iw7kLPqOhIgdV3eVQ==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/logger": "3.9.2", + "@docusaurus/mdx-loader": "3.9.2", + "@docusaurus/theme-common": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "cheerio": "1.0.0-rc.12", + "feed": "^4.2.2", + "fs-extra": "^11.1.1", + "lodash": "^4.17.21", + "schema-dts": "^1.1.2", + "srcset": "^4.0.0", + "tslib": "^2.6.0", + "unist-util-visit": "^5.0.0", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "@docusaurus/plugin-content-docs": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-content-docs": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.9.2.tgz", + "integrity": "sha512-C5wZsGuKTY8jEYsqdxhhFOe1ZDjH0uIYJ9T/jebHwkyxqnr4wW0jTkB72OMqNjsoQRcb0JN3PcSeTwFlVgzCZg==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/logger": "3.9.2", + "@docusaurus/mdx-loader": "3.9.2", + "@docusaurus/module-type-aliases": "3.9.2", + "@docusaurus/theme-common": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "@types/react-router-config": "^5.0.7", + "combine-promises": "^1.1.0", + "fs-extra": "^11.1.1", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "schema-dts": "^1.1.2", + "tslib": "^2.6.0", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-content-pages": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.9.2.tgz", + "integrity": "sha512-s4849w/p4noXUrGpPUF0BPqIAfdAe76BLaRGAGKZ1gTDNiGxGcpsLcwJ9OTi1/V8A+AzvsmI9pkjie2zjIQZKA==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/mdx-loader": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "fs-extra": "^11.1.1", + "tslib": "^2.6.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-css-cascade-layers": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-css-cascade-layers/-/plugin-css-cascade-layers-3.9.2.tgz", + "integrity": "sha512-w1s3+Ss+eOQbscGM4cfIFBlVg/QKxyYgj26k5AnakuHkKxH6004ZtuLe5awMBotIYF2bbGDoDhpgQ4r/kcj4rQ==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/plugin-debug": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.9.2.tgz", + "integrity": "sha512-j7a5hWuAFxyQAkilZwhsQ/b3T7FfHZ+0dub6j/GxKNFJp2h9qk/P1Bp7vrGASnvA9KNQBBL1ZXTe7jlh4VdPdA==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "fs-extra": "^11.1.1", + "react-json-view-lite": "^2.3.0", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-google-analytics": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.9.2.tgz", + "integrity": "sha512-mAwwQJ1Us9jL/lVjXtErXto4p4/iaLlweC54yDUK1a97WfkC6Z2k5/769JsFgwOwOP+n5mUQGACXOEQ0XDuVUw==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-google-gtag": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.9.2.tgz", + "integrity": "sha512-YJ4lDCphabBtw19ooSlc1MnxtYGpjFV9rEdzjLsUnBCeis2djUyCozZaFhCg6NGEwOn7HDDyMh0yzcdRpnuIvA==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "@types/gtag.js": "^0.0.12", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-google-tag-manager": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.9.2.tgz", + "integrity": "sha512-LJtIrkZN/tuHD8NqDAW1Tnw0ekOwRTfobWPsdO15YxcicBo2ykKF0/D6n0vVBfd3srwr9Z6rzrIWYrMzBGrvNw==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-sitemap": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.9.2.tgz", + "integrity": "sha512-WLh7ymgDXjG8oPoM/T4/zUP7KcSuFYRZAUTl8vR6VzYkfc18GBM4xLhcT+AKOwun6kBivYKUJf+vlqYJkm+RHw==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/logger": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "fs-extra": "^11.1.1", + "sitemap": "^7.1.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-svgr": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-svgr/-/plugin-svgr-3.9.2.tgz", + "integrity": "sha512-n+1DE+5b3Lnf27TgVU5jM1d4x5tUh2oW5LTsBxJX4PsAPV0JGcmI6p3yLYtEY0LRVEIJh+8RsdQmRE66wSV8mw==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "@svgr/core": "8.1.0", + "@svgr/webpack": "^8.1.0", + "tslib": "^2.6.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/preset-classic": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.9.2.tgz", + "integrity": "sha512-IgyYO2Gvaigi21LuDIe+nvmN/dfGXAiMcV/murFqcpjnZc7jxFAxW+9LEjdPt61uZLxG4ByW/oUmX/DDK9t/8w==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/plugin-content-blog": "3.9.2", + "@docusaurus/plugin-content-docs": "3.9.2", + "@docusaurus/plugin-content-pages": "3.9.2", + "@docusaurus/plugin-css-cascade-layers": "3.9.2", + "@docusaurus/plugin-debug": "3.9.2", + "@docusaurus/plugin-google-analytics": "3.9.2", + "@docusaurus/plugin-google-gtag": "3.9.2", + "@docusaurus/plugin-google-tag-manager": "3.9.2", + "@docusaurus/plugin-sitemap": "3.9.2", + "@docusaurus/plugin-svgr": "3.9.2", + "@docusaurus/theme-classic": "3.9.2", + "@docusaurus/theme-common": "3.9.2", + "@docusaurus/theme-search-algolia": "3.9.2", + "@docusaurus/types": "3.9.2" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/theme-classic": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.9.2.tgz", + "integrity": "sha512-IGUsArG5hhekXd7RDb11v94ycpJpFdJPkLnt10fFQWOVxAtq5/D7hT6lzc2fhyQKaaCE62qVajOMKL7OiAFAIA==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/logger": "3.9.2", + "@docusaurus/mdx-loader": "3.9.2", + "@docusaurus/module-type-aliases": "3.9.2", + "@docusaurus/plugin-content-blog": "3.9.2", + "@docusaurus/plugin-content-docs": "3.9.2", + "@docusaurus/plugin-content-pages": "3.9.2", + "@docusaurus/theme-common": "3.9.2", + "@docusaurus/theme-translations": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "@mdx-js/react": "^3.0.0", + "clsx": "^2.0.0", + "infima": "0.2.0-alpha.45", + "lodash": "^4.17.21", + "nprogress": "^0.2.0", + "postcss": "^8.5.4", + "prism-react-renderer": "^2.3.0", + "prismjs": "^1.29.0", + "react-router-dom": "^5.3.4", + "rtlcss": "^4.1.0", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/theme-common": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.9.2.tgz", + "integrity": "sha512-6c4DAbR6n6nPbnZhY2V3tzpnKnGL+6aOsLvFL26VRqhlczli9eWG0VDUNoCQEPnGwDMhPS42UhSAnz5pThm5Ag==", + "license": "MIT", + "dependencies": { + "@docusaurus/mdx-loader": "3.9.2", + "@docusaurus/module-type-aliases": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router-config": "*", + "clsx": "^2.0.0", + "parse-numeric-range": "^1.3.0", + "prism-react-renderer": "^2.3.0", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "@docusaurus/plugin-content-docs": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/theme-search-algolia": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.9.2.tgz", + "integrity": "sha512-GBDSFNwjnh5/LdkxCKQHkgO2pIMX1447BxYUBG2wBiajS21uj64a+gH/qlbQjDLxmGrbrllBrtJkUHxIsiwRnw==", + "license": "MIT", + "dependencies": { + "@docsearch/react": "^3.9.0 || ^4.1.0", + "@docusaurus/core": "3.9.2", + "@docusaurus/logger": "3.9.2", + "@docusaurus/plugin-content-docs": "3.9.2", + "@docusaurus/theme-common": "3.9.2", + "@docusaurus/theme-translations": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-validation": "3.9.2", + "algoliasearch": "^5.37.0", + "algoliasearch-helper": "^3.26.0", + "clsx": "^2.0.0", + "eta": "^2.2.0", + "fs-extra": "^11.1.1", + "lodash": "^4.17.21", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/theme-translations": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.9.2.tgz", + "integrity": "sha512-vIryvpP18ON9T9rjgMRFLr2xJVDpw1rtagEGf8Ccce4CkTrvM/fRB8N2nyWYOW5u3DdjkwKw5fBa+3tbn9P4PA==", + "license": "MIT", + "dependencies": { + "fs-extra": "^11.1.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/tsconfig": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/tsconfig/-/tsconfig-3.9.2.tgz", + "integrity": "sha512-j6/Fp4Rlpxsc632cnRnl5HpOWeb6ZKssDj6/XzzAzVGXXfm9Eptx3rxCC+fDzySn9fHTS+CWJjPineCR1bB5WQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@docusaurus/types": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.9.2.tgz", + "integrity": "sha512-Ux1JUNswg+EfUEmajJjyhIohKceitY/yzjRUpu04WXgvVz+fbhVC0p+R0JhvEu4ytw8zIAys2hrdpQPBHRIa8Q==", + "license": "MIT", + "dependencies": { + "@mdx-js/mdx": "^3.0.0", + "@types/history": "^4.7.11", + "@types/mdast": "^4.0.2", + "@types/react": "*", + "commander": "^5.1.0", + "joi": "^17.9.2", + "react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0", + "utility-types": "^3.10.0", + "webpack": "^5.95.0", + "webpack-merge": "^5.9.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/types/node_modules/webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@docusaurus/utils": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.9.2.tgz", + "integrity": "sha512-lBSBiRruFurFKXr5Hbsl2thmGweAPmddhF3jb99U4EMDA5L+e5Y1rAkOS07Nvrup7HUMBDrCV45meaxZnt28nQ==", + "license": "MIT", + "dependencies": { + "@docusaurus/logger": "3.9.2", + "@docusaurus/types": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "escape-string-regexp": "^4.0.0", + "execa": "5.1.1", + "file-loader": "^6.2.0", + "fs-extra": "^11.1.1", + "github-slugger": "^1.5.0", + "globby": "^11.1.0", + "gray-matter": "^4.0.3", + "jiti": "^1.20.0", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "micromatch": "^4.0.5", + "p-queue": "^6.6.2", + "prompts": "^2.4.2", + "resolve-pathname": "^3.0.0", + "tslib": "^2.6.0", + "url-loader": "^4.1.1", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/utils-common": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.9.2.tgz", + "integrity": "sha512-I53UC1QctruA6SWLvbjbhCpAw7+X7PePoe5pYcwTOEXD/PxeP8LnECAhTHHwWCblyUX5bMi4QLRkxvyZ+IT8Aw==", + "license": "MIT", + "dependencies": { + "@docusaurus/types": "3.9.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/utils-validation": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.9.2.tgz", + "integrity": "sha512-l7yk3X5VnNmATbwijJkexdhulNsQaNDwoagiwujXoxFbWLcxHQqNQ+c/IAlzrfMMOfa/8xSBZ7KEKDesE/2J7A==", + "license": "MIT", + "dependencies": { + "@docusaurus/logger": "3.9.2", + "@docusaurus/utils": "3.9.2", + "@docusaurus/utils-common": "3.9.2", + "fs-extra": "^11.2.0", + "joi": "^17.9.2", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsonjoy.com/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/buffers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", + "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/codegen": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-1.0.0.tgz", + "integrity": "sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.21.0.tgz", + "integrity": "sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/base64": "^1.1.2", + "@jsonjoy.com/buffers": "^1.2.0", + "@jsonjoy.com/codegen": "^1.0.0", + "@jsonjoy.com/json-pointer": "^1.0.2", + "@jsonjoy.com/util": "^1.9.0", + "hyperdyperid": "^1.2.0", + "thingies": "^2.5.0", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pointer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-1.0.2.tgz", + "integrity": "sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/codegen": "^1.0.0", + "@jsonjoy.com/util": "^1.9.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.9.0.tgz", + "integrity": "sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/buffers": "^1.0.0", + "@jsonjoy.com/codegen": "^1.0.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "license": "MIT" + }, + "node_modules/@mdx-js/mdx": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.1.tgz", + "integrity": "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdx": "^2.0.0", + "acorn": "^8.0.0", + "collapse-white-space": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-util-scope": "^1.0.0", + "estree-walker": "^3.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "markdown-extensions": "^2.0.0", + "recma-build-jsx": "^1.0.0", + "recma-jsx": "^1.0.0", + "recma-stringify": "^1.0.0", + "rehype-recma": "^1.0.0", + "remark-mdx": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "source-map": "^0.7.0", + "unified": "^11.0.0", + "unist-util-position-from-estree": "^2.0.0", + "unist-util-stringify-position": "^4.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/react": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.1.tgz", + "integrity": "sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==", + "license": "MIT", + "dependencies": { + "@types/mdx": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=16", + "react": ">=16" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@pnpm/config.env-replace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", + "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", + "license": "MIT", + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", + "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", + "license": "MIT", + "dependencies": { + "graceful-fs": "4.2.10" + }, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "license": "ISC" + }, + "node_modules/@pnpm/npm-conf": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.3.1.tgz", + "integrity": "sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==", + "license": "MIT", + "dependencies": { + "@pnpm/config.env-replace": "^1.1.0", + "@pnpm/network.ca-file": "^1.0.1", + "config-chain": "^1.1.11" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.29", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", + "license": "MIT" + }, + "node_modules/@sideway/address": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@sideway/formula": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==", + "license": "BSD-3-Clause" + }, + "node_modules/@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "license": "MIT" + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@slorber/remark-comment": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@slorber/remark-comment/-/remark-comment-1.0.0.tgz", + "integrity": "sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA==", + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.1.0", + "micromark-util-symbol": "^1.0.1" + } + }, + "node_modules/@standard-schema/spec": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", + "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", + "license": "MIT" + }, + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", + "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", + "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", + "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", + "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", + "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", + "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-preset": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", + "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", + "license": "MIT", + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", + "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", + "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", + "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", + "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", + "@svgr/babel-plugin-transform-svg-component": "8.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/core": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", + "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^8.1.3", + "snake-case": "^3.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", + "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.21.3", + "entities": "^4.4.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-jsx": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", + "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "@svgr/hast-util-to-babel-ast": "8.0.0", + "svg-parser": "^2.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, + "node_modules/@svgr/plugin-svgo": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz", + "integrity": "sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==", + "license": "MIT", + "dependencies": { + "cosmiconfig": "^8.1.3", + "deepmerge": "^4.3.1", + "svgo": "^3.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, + "node_modules/@svgr/webpack": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-8.1.0.tgz", + "integrity": "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.21.3", + "@babel/plugin-transform-react-constant-elements": "^7.21.3", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.21.0", + "@svgr/core": "8.1.0", + "@svgr/plugin-jsx": "8.1.0", + "@svgr/plugin-svgo": "8.1.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "license": "MIT", + "dependencies": { + "defer-to-connect": "^2.0.1" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "license": "ISC", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "license": "MIT", + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.25", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.25.tgz", + "integrity": "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==", + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "^1" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.7", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.7.tgz", + "integrity": "sha512-FvPtiIf1LfhzsaIXhv/PHan/2FeQBbtBDtfX2QfvPxdUelMDEckK08SM6nqo1MIZY3RUlfA+HV8+hFUSio78qg==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/gtag.js": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.12.tgz", + "integrity": "sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg==", + "license": "MIT" + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/history": { + "version": "4.7.11", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", + "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==", + "license": "MIT" + }, + "node_modules/@types/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", + "license": "MIT" + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "license": "MIT" + }, + "node_modules/@types/http-errors": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", + "license": "MIT" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.17", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.17.tgz", + "integrity": "sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "license": "MIT" + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdx": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", + "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==", + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "license": "MIT" + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz", + "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.14", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.14.tgz", + "integrity": "sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/prismjs": { + "version": "1.26.5", + "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.5.tgz", + "integrity": "sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==", + "license": "MIT" + }, + "node_modules/@types/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.4.tgz", + "integrity": "sha512-tBFxBp9Nfyy5rsmefN+WXc1JeW/j2BpBHFdLZbEVfs9wn3E3NRFxwV0pJg8M1qQAexFpvz73hJXFofV0ZAu92A==", + "license": "MIT", + "dependencies": { + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-router": { + "version": "5.1.20", + "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", + "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", + "license": "MIT", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*" + } + }, + "node_modules/@types/react-router-config": { + "version": "5.0.11", + "resolved": "https://registry.npmjs.org/@types/react-router-config/-/react-router-config-5.0.11.tgz", + "integrity": "sha512-WmSAg7WgqW7m4x8Mt4N6ZyKz0BubSj/2tVUMsAHp+Yd2AMwcSbeFq9WympT19p5heCFmF97R9eD5uUR/t4HEqw==", + "license": "MIT", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router": "^5.1.0" + } + }, + "node_modules/@types/react-router-dom": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", + "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", + "license": "MIT", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router": "*" + } + }, + "node_modules/@types/retry": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", + "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", + "license": "MIT" + }, + "node_modules/@types/sax": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", + "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", + "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "license": "MIT", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.10", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.10.tgz", + "integrity": "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==", + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "<1" + } + }, + "node_modules/@types/serve-static/node_modules/@types/send": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.6.tgz", + "integrity": "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==", + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "17.0.34", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.34.tgz", + "integrity": "sha512-KExbHVa92aJpw9WDQvzBaGVE2/Pz+pLZQloT2hjL8IqsZnV62rlPOYvNnLmf/L2dyllfVUOVBj64M0z/46eR2A==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "license": "MIT" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "license": "ISC" + }, + "node_modules/@vercel/oidc": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@vercel/oidc/-/oidc-3.0.3.tgz", + "integrity": "sha512-yNEQvPcVrK9sIe637+I0jD6leluPxzwJKx/Haw6F4H77CdDsszUn5V3o96LPziXkSNE2B83+Z3mjqGKBK/R6Gg==", + "license": "Apache-2.0", + "engines": { + "node": ">= 20" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "license": "Apache-2.0", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "license": "Apache-2.0" + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "acorn": "^8.14.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/address": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", + "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ai": { + "version": "5.0.93", + "resolved": "https://registry.npmjs.org/ai/-/ai-5.0.93.tgz", + "integrity": "sha512-9eGcu+1PJgPg4pRNV4L7tLjRR3wdJC9CXQoNMvtqvYNOLZHFCzjHtVIOr2SIkoJJeu2+sOy3hyiSuTmy2MA40g==", + "license": "Apache-2.0", + "dependencies": { + "@ai-sdk/gateway": "2.0.9", + "@ai-sdk/provider": "2.0.0", + "@ai-sdk/provider-utils": "3.0.17", + "@opentelemetry/api": "1.9.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "zod": "^3.25.76 || ^4.1.8" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/algoliasearch": { + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.43.0.tgz", + "integrity": "sha512-hbkK41JsuGYhk+atBDxlcKxskjDCh3OOEDpdKZPtw+3zucBqhlojRG5e5KtCmByGyYvwZswVeaSWglgLn2fibg==", + "license": "MIT", + "dependencies": { + "@algolia/abtesting": "1.9.0", + "@algolia/client-abtesting": "5.43.0", + "@algolia/client-analytics": "5.43.0", + "@algolia/client-common": "5.43.0", + "@algolia/client-insights": "5.43.0", + "@algolia/client-personalization": "5.43.0", + "@algolia/client-query-suggestions": "5.43.0", + "@algolia/client-search": "5.43.0", + "@algolia/ingestion": "1.43.0", + "@algolia/monitoring": "1.43.0", + "@algolia/recommend": "5.43.0", + "@algolia/requester-browser-xhr": "5.43.0", + "@algolia/requester-fetch": "5.43.0", + "@algolia/requester-node-http": "5.43.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/algoliasearch-helper": { + "version": "3.26.1", + "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.26.1.tgz", + "integrity": "sha512-CAlCxm4fYBXtvc5MamDzP6Svu8rW4z9me4DCBY1rQ2UDJ0u0flWmusQ8M3nOExZsLLRcUwUPoRAPMrhzOG3erw==", + "license": "MIT", + "dependencies": { + "@algolia/events": "^4.0.1" + }, + "peerDependencies": { + "algoliasearch": ">= 3.1 < 6" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "license": "ISC", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-align/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/ansi-align/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "engines": [ + "node >= 0.8.0" + ], + "license": "Apache-2.0", + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "license": "MIT" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/astring": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", + "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", + "license": "MIT", + "bin": { + "astring": "bin/astring" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.22", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.22.tgz", + "integrity": "sha512-ARe0v/t9gO28Bznv6GgqARmVqcWOV3mfgUPn9becPHMiD3o9BwlRgaeccZnwTpZ7Zwqrm+c1sUSsMxIzQzc8Xg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.27.0", + "caniuse-lite": "^1.0.30001754", + "fraction.js": "^5.3.4", + "normalize-range": "^0.1.2", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/babel-loader": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.2.1.tgz", + "integrity": "sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==", + "license": "MIT", + "dependencies": { + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0", + "webpack": ">=5" + } + }, + "node_modules/babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "license": "MIT", + "dependencies": { + "object.assign": "^4.1.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz", + "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.7", + "@babel/helper-define-polyfill-provider": "^0.6.5", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz", + "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.5", + "core-js-compat": "^3.43.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz", + "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.5" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.8.28", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.28.tgz", + "integrity": "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "license": "MIT" + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/bonjour-service": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", + "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, + "node_modules/boxen": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-6.2.1.tgz", + "integrity": "sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw==", + "license": "MIT", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^6.2.0", + "chalk": "^4.1.2", + "cli-boxes": "^3.0.0", + "string-width": "^5.0.1", + "type-fest": "^2.5.0", + "widest-line": "^4.0.1", + "wrap-ansi": "^8.0.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.0.tgz", + "integrity": "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.8.25", + "caniuse-lite": "^1.0.30001754", + "electron-to-chromium": "^1.5.249", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.1.4" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacheable-lookup": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "license": "MIT", + "engines": { + "node": ">=14.16" + } + }, + "node_modules/cacheable-request": { + "version": "10.2.14", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", + "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", + "license": "MIT", + "dependencies": { + "@types/http-cache-semantics": "^4.0.2", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.3", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "license": "MIT", + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001754", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001754.tgz", + "integrity": "sha512-x6OeBXueoAceOmotzx3PO4Zpt4rzpeIFsSr6AAePTZxSkXiYDUmpypEl7e2+8NCd9bD7bXjqyef8CJYPC1jfxg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/cheerio": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" + }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/clean-css": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", + "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", + "license": "MIT", + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 10.0" + } + }, + "node_modules/clean-css/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-boxes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", + "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-table3/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/cli-table3/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/collapse-white-space": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", + "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "license": "MIT" + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "license": "MIT" + }, + "node_modules/combine-promises": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/combine-promises/-/combine-promises-1.2.0.tgz", + "integrity": "sha512-VcQB1ziGD0NXrhKxiwyNbCDmRzs/OShMs2GqW2DlU2A/Sd0nQxE1oWDAE5O0ygSx5mgQOn9eIFh7yKPgFRVkPQ==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "license": "ISC" + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compressible/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", + "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "compressible": "~2.0.18", + "debug": "2.6.9", + "negotiator": "~0.6.4", + "on-headers": "~1.1.0", + "safe-buffer": "5.2.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" + }, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "license": "MIT", + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "node_modules/config-chain/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/configstore": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-6.0.0.tgz", + "integrity": "sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==", + "license": "BSD-2-Clause", + "dependencies": { + "dot-prop": "^6.0.1", + "graceful-fs": "^4.2.6", + "unique-string": "^3.0.0", + "write-file-atomic": "^3.0.3", + "xdg-basedir": "^5.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/yeoman/configstore?sponsor=1" + } + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "license": "MIT" + }, + "node_modules/copy-webpack-plugin": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", + "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", + "license": "MIT", + "dependencies": { + "fast-glob": "^3.2.11", + "glob-parent": "^6.0.1", + "globby": "^13.1.1", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/globby": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", + "license": "MIT", + "dependencies": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/copy-webpack-plugin/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/core-js": { + "version": "3.46.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.46.0.tgz", + "integrity": "sha512-vDMm9B0xnqqZ8uSBpZ8sNtRtOdmfShrvT6h2TuQGLs0Is+cR0DYbj/KWP6ALVNbWPpqA/qPLoOuppJN07humpA==", + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat": { + "version": "3.46.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.46.0.tgz", + "integrity": "sha512-p9hObIIEENxSV8xIu+V68JjSeARg6UVMG5mR+JEUguG3sI6MsiS1njz2jHmyJDvA+8jX/sytkBHup6kxhM9law==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.26.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-pure": { + "version": "3.46.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.46.0.tgz", + "integrity": "sha512-NMCW30bHNofuhwLhYPt66OLOKTMbOhgTTatKVbaQC3KRHpTCiRIBYvtshr+NBYSnBxwAFhjW/RfJ0XbIjS16rw==", + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "license": "MIT", + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-random-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", + "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", + "license": "MIT", + "dependencies": { + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/crypto-random-string/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/css-blank-pseudo": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-7.0.1.tgz", + "integrity": "sha512-jf+twWGDf6LDoXDUode+nc7ZlrqfaNphrBIBrcmeP3D8yw1uPaix1gCC8LUQUGQ6CycuK2opkbFFWFuq/a94ag==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-blank-pseudo/node_modules/postcss-selector-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/css-declaration-sorter": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.3.0.tgz", + "integrity": "sha512-LQF6N/3vkAMYF4xoHLJfG718HRJh34Z8BnNhd6bosOMIVjMlhuZK5++oZa3uYAgrI5+7x2o27gUqTR2U/KjUOQ==", + "license": "ISC", + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/css-has-pseudo": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-7.0.3.tgz", + "integrity": "sha512-oG+vKuGyqe/xvEMoxAQrhi7uY16deJR3i7wwhBerVrGQKSqUC5GiOVxTpM9F9B9hw0J+eKeOWLH7E9gZ1Dr5rA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/selector-specificity": "^5.0.0", + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-has-pseudo/node_modules/@csstools/selector-specificity": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", + "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/css-has-pseudo/node_modules/postcss-selector-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/css-loader": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", + "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==", + "license": "MIT", + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/css-minimizer-webpack-plugin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-5.0.1.tgz", + "integrity": "sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==", + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "cssnano": "^6.0.1", + "jest-worker": "^29.4.3", + "postcss": "^8.4.24", + "schema-utils": "^4.0.1", + "serialize-javascript": "^6.0.1" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@parcel/css": { + "optional": true + }, + "@swc/css": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "lightningcss": { + "optional": true + } + } + }, + "node_modules/css-prefers-color-scheme": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-10.0.0.tgz", + "integrity": "sha512-VCtXZAWivRglTZditUfB4StnsWr6YVZ2PRtuxQLKTNRdtAf8tpzaVPE9zXIF3VaSc7O70iK/j1+NXxyQCqdPjQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssdb": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-8.4.2.tgz", + "integrity": "sha512-PzjkRkRUS+IHDJohtxkIczlxPPZqRo0nXplsYXOMBRPjcVRjj1W4DfvRgshUYTVuUigU7ptVYkFJQ7abUB0nyg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + } + ], + "license": "MIT-0" + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz", + "integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==", + "license": "MIT", + "dependencies": { + "cssnano-preset-default": "^6.1.2", + "lilconfig": "^3.1.1" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-preset-advanced": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-6.1.2.tgz", + "integrity": "sha512-Nhao7eD8ph2DoHolEzQs5CfRpiEP0xa1HBdnFZ82kvqdmbwVBUr2r1QuQ4t1pi+D1ZpqpcO4T+wy/7RxzJ/WPQ==", + "license": "MIT", + "dependencies": { + "autoprefixer": "^10.4.19", + "browserslist": "^4.23.0", + "cssnano-preset-default": "^6.1.2", + "postcss-discard-unused": "^6.0.5", + "postcss-merge-idents": "^6.0.3", + "postcss-reduce-idents": "^6.0.3", + "postcss-zindex": "^6.0.2" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-preset-default": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz", + "integrity": "sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "css-declaration-sorter": "^7.2.0", + "cssnano-utils": "^4.0.2", + "postcss-calc": "^9.0.1", + "postcss-colormin": "^6.1.0", + "postcss-convert-values": "^6.1.0", + "postcss-discard-comments": "^6.0.2", + "postcss-discard-duplicates": "^6.0.3", + "postcss-discard-empty": "^6.0.3", + "postcss-discard-overridden": "^6.0.2", + "postcss-merge-longhand": "^6.0.5", + "postcss-merge-rules": "^6.1.1", + "postcss-minify-font-values": "^6.1.0", + "postcss-minify-gradients": "^6.0.3", + "postcss-minify-params": "^6.1.0", + "postcss-minify-selectors": "^6.0.4", + "postcss-normalize-charset": "^6.0.2", + "postcss-normalize-display-values": "^6.0.2", + "postcss-normalize-positions": "^6.0.2", + "postcss-normalize-repeat-style": "^6.0.2", + "postcss-normalize-string": "^6.0.2", + "postcss-normalize-timing-functions": "^6.0.2", + "postcss-normalize-unicode": "^6.1.0", + "postcss-normalize-url": "^6.0.2", + "postcss-normalize-whitespace": "^6.0.2", + "postcss-ordered-values": "^6.0.2", + "postcss-reduce-initial": "^6.1.0", + "postcss-reduce-transforms": "^6.0.2", + "postcss-svgo": "^6.0.3", + "postcss-unique-selectors": "^6.0.4" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-utils": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.2.tgz", + "integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "license": "MIT", + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "license": "CC0-1.0" + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz", + "integrity": "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-browser": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.3.0.tgz", + "integrity": "sha512-Qq68+VkJlc8tjnPV1i7HtbIn7ohmjZa88qUvHMIK0ZKUXMCuV45cT7cEXALPUmeXCe0q1DWQkQTemHVaLIFSrg==", + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "license": "MIT" + }, + "node_modules/detect-port": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.6.1.tgz", + "integrity": "sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==", + "license": "MIT", + "dependencies": { + "address": "^1.0.1", + "debug": "4" + }, + "bin": { + "detect": "bin/detect-port.js", + "detect-port": "bin/detect-port.js" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "license": "MIT", + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "license": "MIT", + "dependencies": { + "utila": "~0.4" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/dot-prop": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "license": "MIT", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dot-prop/node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "license": "MIT" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.250", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.250.tgz", + "integrity": "sha512-/5UMj9IiGDMOFBnN4i7/Ry5onJrAGSbOGo3s9FEKmwobGq6xw832ccET0CE3CkkMBZ8GJSlUIesZofpyurqDXw==", + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, + "node_modules/emojilib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", + "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", + "license": "MIT" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/emoticon": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/emoticon/-/emoticon-4.1.0.tgz", + "integrity": "sha512-VWZfnxqwNcc51hIy/sbOdEem6D+cVtpPzEEtVAFdaas30+1dgkyaOQ4sQ6Bp0tOMqWO1v+HQfYaoodOkdhK6SQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", + "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esast-util-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/esast-util-from-estree/-/esast-util-from-estree-2.0.0.tgz", + "integrity": "sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/esast-util-from-js": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esast-util-from-js/-/esast-util-from-js-2.0.1.tgz", + "integrity": "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "acorn": "^8.0.0", + "esast-util-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-goat": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-4.0.0.tgz", + "integrity": "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-util-attach-comments": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", + "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-build-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", + "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-walker": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-scope": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/estree-util-scope/-/estree-util-scope-1.0.0.tgz", + "integrity": "sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-to-js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", + "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "astring": "^1.8.0", + "source-map": "^0.7.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-value-to-estree": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.5.0.tgz", + "integrity": "sha512-aMV56R27Gv3QmfmF1MY12GWkGzzeAezAX+UplqHVASfjc9wNzI/X6hC0S9oxq61WT4aQesLGslWP9tKk6ghRZQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/remcohaszing" + } + }, + "node_modules/estree-util-visit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", + "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eta": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/eta/-/eta-2.2.0.tgz", + "integrity": "sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "url": "https://github.com/eta-dev/eta?sponsor=1" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eval": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eval/-/eval-0.1.8.tgz", + "integrity": "sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==", + "dependencies": { + "@types/node": "*", + "require-like": ">= 0.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/eventsource-parser": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", + "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/express/node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "license": "MIT" + }, + "node_modules/express/node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fault": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", + "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", + "license": "MIT", + "dependencies": { + "format": "^0.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/feed": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/feed/-/feed-4.2.2.tgz", + "integrity": "sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==", + "license": "MIT", + "dependencies": { + "xml-js": "^1.6.11" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/file-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/file-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/file-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/file-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "license": "MIT" + }, + "node_modules/file-loader/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/find-cache-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", + "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", + "license": "MIT", + "dependencies": { + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "license": "MIT", + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data-encoder": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", + "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", + "license": "MIT", + "engines": { + "node": ">= 14.17" + } + }, + "node_modules/format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", + "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==", + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "11.3.2", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.2.tgz", + "integrity": "sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "license": "ISC" + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/github-slugger": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", + "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==", + "license": "ISC" + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regex.js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/glob-to-regex.js/-/glob-to-regex.js-1.2.0.tgz", + "integrity": "sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "license": "BSD-2-Clause" + }, + "node_modules/global-dirs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", + "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", + "license": "MIT", + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", + "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.8", + "decompress-response": "^6.0.0", + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/got/node_modules/@sindresorhus/is": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", + "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/gray-matter": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", + "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", + "license": "MIT", + "dependencies": { + "js-yaml": "^3.13.1", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/gray-matter/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/gray-matter/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "license": "MIT", + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-yarn": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-3.0.0.tgz", + "integrity": "sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", + "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^9.0.0", + "property-information": "^7.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz", + "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "parse5": "^7.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-estree": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.3.tgz", + "integrity": "sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-attach-comments": "^3.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", + "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-parse5": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", + "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-parse5/node_modules/property-information": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", + "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz", + "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "license": "MIT" + }, + "node_modules/html-minifier-terser": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz", + "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==", + "license": "MIT", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "~5.3.2", + "commander": "^10.0.0", + "entities": "^4.4.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.15.1" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": "^14.13.1 || >=16.0.0" + } + }, + "node_modules/html-minifier-terser/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/html-tags": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/html-webpack-plugin": { + "version": "5.6.4", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.4.tgz", + "integrity": "sha512-V/PZeWsqhfpE27nKeX9EO2sbR+D17A+tLf6qU+ht66jdUsN0QLKJN27Z+1+gHrVMKgndBahes0PU6rRihDgHTw==", + "license": "MIT", + "dependencies": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/html-webpack-plugin" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.20.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/html-webpack-plugin/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/html-webpack-plugin/node_modules/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "license": "MIT", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "license": "BSD-2-Clause" + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "license": "MIT" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", + "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", + "license": "MIT" + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-middleware": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz", + "integrity": "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==", + "license": "MIT", + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/http-proxy-middleware/node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/http2-wrapper": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "license": "MIT", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/hyperdyperid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", + "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", + "license": "MIT", + "engines": { + "node": ">=10.18" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/image-size": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-2.0.2.tgz", + "integrity": "sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w==", + "license": "MIT", + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=16.x" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/infima": { + "version": "0.2.0-alpha.45", + "resolved": "https://registry.npmjs.org/infima/-/infima-0.2.0-alpha.45.tgz", + "integrity": "sha512-uyH0zfr1erU1OohLk0fT4Rrb94AOhguWNOcD9uGrSpRvNB+6gZXUoJX5J0NtvzBO10YZ9PgvA4NFgt+fYg8ojw==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/inline-style-parser": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.6.tgz", + "integrity": "sha512-gtGXVaBdl5mAes3rPcMedEBm12ibjt1kDMFfheul1wUAOVEJW60voNdMVzVkfLN06O7ZaD/rxhfKgtlgtTbMjg==", + "license": "MIT" + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "license": "MIT", + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-inside-container/node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "license": "MIT", + "dependencies": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-network-error": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.0.tgz", + "integrity": "sha512-6oIwpsgRfnDiyEDLMay/GqCl3HoAtH5+RUKW29gYkL0QA+ipzpDLA16yQs7/RHCSu+BwgbJaOUqa4A99qNVQVw==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-npm": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.1.0.tgz", + "integrity": "sha512-O2z4/kNgyjhQwVR1Wpkbfc19JIhggF97NZNCpWTnjH7kVcZMUrnut9XSN7txI7VdyIYk5ZatOq3zvSuWpU8hoA==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "license": "MIT" + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-yarn-global": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz", + "integrity": "sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/joi": { + "version": "17.13.3", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", + "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.5", + "@sideway/formula": "^3.0.1", + "@sideway/pinpoint": "^2.0.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT" + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "license": "(AFL-2.1 OR BSD-3-Clause)" + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/latest-version": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", + "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==", + "license": "MIT", + "dependencies": { + "package-json": "^8.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/launch-editor": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.12.0.tgz", + "integrity": "sha512-giOHXoOtifjdHqUamwKq6c49GzBdLjvxrd2D+Q4V6uOHopJv7p9VJxikDsQ/CBXZbEITgUqSVHXLTG3VhPP1Dg==", + "license": "MIT", + "dependencies": { + "picocolors": "^1.1.1", + "shell-quote": "^1.8.3" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, + "node_modules/loader-runner": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", + "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", + "license": "MIT", + "engines": { + "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "license": "MIT", + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "license": "MIT" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "license": "MIT" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "license": "MIT" + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/markdown-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", + "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/marked": { + "version": "16.4.2", + "resolved": "https://registry.npmjs.org/marked/-/marked-16.4.2.tgz", + "integrity": "sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mdast-util-directive": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.1.0.tgz", + "integrity": "sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/mdast-util-frontmatter": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz", + "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "escape-string-regexp": "^5.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-extension-frontmatter": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-frontmatter/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", + "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", + "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", + "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", + "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "license": "CC0-1.0" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "4.51.0", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.51.0.tgz", + "integrity": "sha512-4zngfkVM/GpIhC8YazOsM6E8hoB33NP0BCESPOA6z7qaL6umPJNqkO8CNYaLV2FB2MV6H1O3x2luHHOSqppv+A==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/json-pack": "^1.11.0", + "@jsonjoy.com/util": "^1.9.0", + "glob-to-regex.js": "^1.0.1", + "thingies": "^2.5.0", + "tree-dump": "^1.0.3", + "tslib": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-directive": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.2.tgz", + "integrity": "sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "parse-entities": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-frontmatter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz", + "integrity": "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==", + "license": "MIT", + "dependencies": { + "fault": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-mdx-expression": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.1.tgz", + "integrity": "sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-expression/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-mdx-jsx": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.2.tgz", + "integrity": "sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-mdx-md": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", + "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", + "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", + "license": "MIT", + "dependencies": { + "acorn": "^8.0.0", + "acorn-jsx": "^5.0.0", + "micromark-extension-mdx-expression": "^3.0.0", + "micromark-extension-mdx-jsx": "^3.0.0", + "micromark-extension-mdx-md": "^2.0.0", + "micromark-extension-mdxjs-esm": "^3.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", + "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-destination/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-destination/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-mdx-expression": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.3.tgz", + "integrity": "sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-space": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", + "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-space/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-character/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-events-to-acorn": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.3.tgz", + "integrity": "sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-util-events-to-acorn/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-normalize-identifier/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "license": "MIT", + "dependencies": { + "mime-db": "~1.33.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.4.tgz", + "integrity": "sha512-ZWYT7ln73Hptxqxk2DxPU9MmapXRhxkJD6tkSR04dnQxm8BGu2hzgKLugK5yySD97u/8yy7Ma7E76k9ZdvtjkQ==", + "license": "MIT", + "dependencies": { + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "license": "ISC" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "license": "MIT", + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "license": "MIT" + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "license": "MIT", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-emoji": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.2.0.tgz", + "integrity": "sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==", + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^4.6.0", + "char-regex": "^1.0.2", + "emojilib": "^2.4.0", + "skin-tone": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.1.0.tgz", + "integrity": "sha512-X06Mfd/5aKsRHc0O0J5CUedwnPmnDtLF2+nq+KN9KSDlJHkPuh0JUviWjEWMe0SW/9TDdSLVPuk7L5gGTIA1/w==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nprogress": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", + "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==", + "license": "MIT" + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/null-loader": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/null-loader/-/null-loader-4.0.1.tgz", + "integrity": "sha512-pxqVbi4U6N26lq+LmgIbB5XATP0VdZKOG25DhHi8btMmJJefGArFyDg1yc4U3hWCJbMqSrw0qyrz1UQX+qYXqg==", + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/null-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/null-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/null-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "license": "MIT" + }, + "node_modules/null-loader/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "license": "MIT" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", + "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "license": "(WTFPL OR MIT)", + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/p-cancelable": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "license": "MIT", + "engines": { + "node": ">=12.20" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "license": "MIT", + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz", + "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==", + "license": "MIT", + "dependencies": { + "@types/retry": "0.12.2", + "is-network-error": "^1.0.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "license": "MIT", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/package-json": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz", + "integrity": "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==", + "license": "MIT", + "dependencies": { + "got": "^12.1.0", + "registry-auth-token": "^5.0.1", + "registry-url": "^6.0.0", + "semver": "^7.3.7" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "license": "MIT", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-numeric-range": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", + "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==", + "license": "ISC" + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", + "license": "(WTFPL OR MIT)" + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/path-to-regexp": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", + "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", + "license": "MIT", + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", + "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "license": "MIT", + "dependencies": { + "find-up": "^6.3.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-attribute-case-insensitive": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-7.0.1.tgz", + "integrity": "sha512-Uai+SupNSqzlschRyNx3kbCTWgY/2hcwtHEI/ej2LJWc9JJ77qKgGptd8DHwY1mXtZ7Aoh4z4yxfwMBue9eNgw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-attribute-case-insensitive/node_modules/postcss-selector-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-calc": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", + "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.11", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.2" + } + }, + "node_modules/postcss-clamp": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz", + "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=7.6.0" + }, + "peerDependencies": { + "postcss": "^8.4.6" + } + }, + "node_modules/postcss-color-functional-notation": { + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-7.0.12.tgz", + "integrity": "sha512-TLCW9fN5kvO/u38/uesdpbx3e8AkTYhMvDZYa9JpmImWuTE99bDQ7GU7hdOADIZsiI9/zuxfAJxny/khknp1Zw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-color-hex-alpha": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-10.0.0.tgz", + "integrity": "sha512-1kervM2cnlgPs2a8Vt/Qbe5cQ++N7rkYo/2rz2BkqJZIHQwaVuJgQH38REHrAi4uM0b1fqxMkWYmese94iMp3w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-color-rebeccapurple": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-10.0.0.tgz", + "integrity": "sha512-JFta737jSP+hdAIEhk1Vs0q0YF5P8fFcj+09pweS8ktuGuZ8pPlykHsk6mPxZ8awDl4TrcxUqJo9l1IhVr/OjQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-colormin": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.1.0.tgz", + "integrity": "sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0", + "colord": "^2.9.3", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-convert-values": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.1.0.tgz", + "integrity": "sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-custom-media": { + "version": "11.0.6", + "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-11.0.6.tgz", + "integrity": "sha512-C4lD4b7mUIw+RZhtY7qUbf4eADmb7Ey8BFA2px9jUbwg7pjTZDl4KY4bvlUV+/vXQvzQRfiGEVJyAbtOsCMInw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/cascade-layer-name-parser": "^2.0.5", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/media-query-list-parser": "^4.0.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-custom-properties": { + "version": "14.0.6", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-14.0.6.tgz", + "integrity": "sha512-fTYSp3xuk4BUeVhxCSJdIPhDLpJfNakZKoiTDx7yRGCdlZrSJR7mWKVOBS4sBF+5poPQFMj2YdXx1VHItBGihQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/cascade-layer-name-parser": "^2.0.5", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-custom-selectors": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-8.0.5.tgz", + "integrity": "sha512-9PGmckHQswiB2usSO6XMSswO2yFWVoCAuih1yl9FVcwkscLjRKjwsjM3t+NIWpSU2Jx3eOiK2+t4vVTQaoCHHg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/cascade-layer-name-parser": "^2.0.5", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-custom-selectors/node_modules/postcss-selector-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-dir-pseudo-class": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-9.0.1.tgz", + "integrity": "sha512-tRBEK0MHYvcMUrAuYMEOa0zg9APqirBcgzi6P21OhxtJyJADo/SWBwY1CAwEohQ/6HDaa9jCjLRG7K3PVQYHEA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-dir-pseudo-class/node_modules/postcss-selector-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-discard-comments": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.2.tgz", + "integrity": "sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.3.tgz", + "integrity": "sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-empty": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.3.tgz", + "integrity": "sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.2.tgz", + "integrity": "sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-unused": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-6.0.5.tgz", + "integrity": "sha512-wHalBlRHkaNnNwfC8z+ppX57VhvS+HWgjW508esjdaEYr3Mx7Gnn2xA4R/CKf5+Z9S5qsqC+Uzh4ueENWwCVUA==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-double-position-gradients": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-6.0.4.tgz", + "integrity": "sha512-m6IKmxo7FxSP5nF2l63QbCC3r+bWpFUWmZXZf096WxG0m7Vl1Q1+ruFOhpdDRmKrRS+S3Jtk+TVk/7z0+BVK6g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-focus-visible": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-10.0.1.tgz", + "integrity": "sha512-U58wyjS/I1GZgjRok33aE8juW9qQgQUNwTSdxQGuShHzwuYdcklnvK/+qOWX1Q9kr7ysbraQ6ht6r+udansalA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-focus-visible/node_modules/postcss-selector-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-focus-within": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-9.0.1.tgz", + "integrity": "sha512-fzNUyS1yOYa7mOjpci/bR+u+ESvdar6hk8XNK/TRR0fiGTp2QT5N+ducP0n3rfH/m9I7H/EQU6lsa2BrgxkEjw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-focus-within/node_modules/postcss-selector-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-font-variant": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", + "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", + "license": "MIT", + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-gap-properties": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-6.0.0.tgz", + "integrity": "sha512-Om0WPjEwiM9Ru+VhfEDPZJAKWUd0mV1HmNXqp2C29z80aQ2uP9UVhLc7e3aYMIor/S5cVhoPgYQ7RtfeZpYTRw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-image-set-function": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-7.0.0.tgz", + "integrity": "sha512-QL7W7QNlZuzOwBTeXEmbVckNt1FSmhQtbMRvGGqqU4Nf4xk6KUEQhAoWuMzwbSv5jxiRiSZ5Tv7eiDB9U87znA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-lab-function": { + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-7.0.12.tgz", + "integrity": "sha512-tUcyRk1ZTPec3OuKFsqtRzW2Go5lehW29XA21lZ65XmzQkz43VY2tyWEC202F7W3mILOjw0voOiuxRGTsN+J9w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-loader": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.4.tgz", + "integrity": "sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A==", + "license": "MIT", + "dependencies": { + "cosmiconfig": "^8.3.5", + "jiti": "^1.20.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + } + }, + "node_modules/postcss-logical": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-8.1.0.tgz", + "integrity": "sha512-pL1hXFQ2fEXNKiNiAgtfA005T9FBxky5zkX6s4GZM2D8RkVgRqz3f4g1JUoq925zXv495qk8UNldDwh8uGEDoA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-merge-idents": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-6.0.3.tgz", + "integrity": "sha512-1oIoAsODUs6IHQZkLQGO15uGEbK3EAl5wi9SS8hs45VgsxQfMnxvt+L+zIr7ifZFIH14cfAeVe2uCTa+SPRa3g==", + "license": "MIT", + "dependencies": { + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-merge-longhand": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.5.tgz", + "integrity": "sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^6.1.1" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-merge-rules": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.1.1.tgz", + "integrity": "sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^4.0.2", + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.1.0.tgz", + "integrity": "sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.3.tgz", + "integrity": "sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==", + "license": "MIT", + "dependencies": { + "colord": "^2.9.3", + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-params": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.1.0.tgz", + "integrity": "sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.4.tgz", + "integrity": "sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", + "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", + "license": "MIT", + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default/node_modules/postcss-selector-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", + "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope/node_modules/postcss-selector-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "license": "ISC", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-nesting": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-13.0.2.tgz", + "integrity": "sha512-1YCI290TX+VP0U/K/aFxzHzQWHWURL+CtHMSbex1lCdpXD1SoR2sYuxDu5aNI9lPoXpKTCggFZiDJbwylU0LEQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/selector-resolve-nested": "^3.1.0", + "@csstools/selector-specificity": "^5.0.0", + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-nesting/node_modules/@csstools/selector-resolve-nested": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-3.1.0.tgz", + "integrity": "sha512-mf1LEW0tJLKfWyvn5KdDrhpxHyuxpbNwTIwOYLIvsTffeyOf85j5oIzfG0yosxDgx/sswlqBnESYUcQH0vgZ0g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/postcss-nesting/node_modules/@csstools/selector-specificity": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", + "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/postcss-nesting/node_modules/postcss-selector-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.2.tgz", + "integrity": "sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.2.tgz", + "integrity": "sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-positions": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.2.tgz", + "integrity": "sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.2.tgz", + "integrity": "sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-string": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.2.tgz", + "integrity": "sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.2.tgz", + "integrity": "sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-unicode": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.1.0.tgz", + "integrity": "sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-url": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.2.tgz", + "integrity": "sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-whitespace": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.2.tgz", + "integrity": "sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-opacity-percentage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-3.0.0.tgz", + "integrity": "sha512-K6HGVzyxUxd/VgZdX04DCtdwWJ4NGLG212US4/LA1TLAbHgmAsTWVR86o+gGIbFtnTkfOpb9sCRBx8K7HO66qQ==", + "funding": [ + { + "type": "kofi", + "url": "https://ko-fi.com/mrcgrtz" + }, + { + "type": "liberapay", + "url": "https://liberapay.com/mrcgrtz" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-ordered-values": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.2.tgz", + "integrity": "sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==", + "license": "MIT", + "dependencies": { + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-overflow-shorthand": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-6.0.0.tgz", + "integrity": "sha512-BdDl/AbVkDjoTofzDQnwDdm/Ym6oS9KgmO7Gr+LHYjNWJ6ExORe4+3pcLQsLA9gIROMkiGVjjwZNoL/mpXHd5Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-page-break": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", + "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", + "license": "MIT", + "peerDependencies": { + "postcss": "^8" + } + }, + "node_modules/postcss-place": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-10.0.0.tgz", + "integrity": "sha512-5EBrMzat2pPAxQNWYavwAfoKfYcTADJ8AXGVPcUZ2UkNloUTWzJQExgrzrDkh3EKzmAx1evfTAzF9I8NGcc+qw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-preset-env": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-10.4.0.tgz", + "integrity": "sha512-2kqpOthQ6JhxqQq1FSAAZGe9COQv75Aw8WbsOvQVNJ2nSevc9Yx/IKZGuZ7XJ+iOTtVon7LfO7ELRzg8AZ+sdw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/postcss-alpha-function": "^1.0.1", + "@csstools/postcss-cascade-layers": "^5.0.2", + "@csstools/postcss-color-function": "^4.0.12", + "@csstools/postcss-color-function-display-p3-linear": "^1.0.1", + "@csstools/postcss-color-mix-function": "^3.0.12", + "@csstools/postcss-color-mix-variadic-function-arguments": "^1.0.2", + "@csstools/postcss-content-alt-text": "^2.0.8", + "@csstools/postcss-contrast-color-function": "^2.0.12", + "@csstools/postcss-exponential-functions": "^2.0.9", + "@csstools/postcss-font-format-keywords": "^4.0.0", + "@csstools/postcss-gamut-mapping": "^2.0.11", + "@csstools/postcss-gradients-interpolation-method": "^5.0.12", + "@csstools/postcss-hwb-function": "^4.0.12", + "@csstools/postcss-ic-unit": "^4.0.4", + "@csstools/postcss-initial": "^2.0.1", + "@csstools/postcss-is-pseudo-class": "^5.0.3", + "@csstools/postcss-light-dark-function": "^2.0.11", + "@csstools/postcss-logical-float-and-clear": "^3.0.0", + "@csstools/postcss-logical-overflow": "^2.0.0", + "@csstools/postcss-logical-overscroll-behavior": "^2.0.0", + "@csstools/postcss-logical-resize": "^3.0.0", + "@csstools/postcss-logical-viewport-units": "^3.0.4", + "@csstools/postcss-media-minmax": "^2.0.9", + "@csstools/postcss-media-queries-aspect-ratio-number-values": "^3.0.5", + "@csstools/postcss-nested-calc": "^4.0.0", + "@csstools/postcss-normalize-display-values": "^4.0.0", + "@csstools/postcss-oklab-function": "^4.0.12", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/postcss-random-function": "^2.0.1", + "@csstools/postcss-relative-color-syntax": "^3.0.12", + "@csstools/postcss-scope-pseudo-class": "^4.0.1", + "@csstools/postcss-sign-functions": "^1.1.4", + "@csstools/postcss-stepped-value-functions": "^4.0.9", + "@csstools/postcss-text-decoration-shorthand": "^4.0.3", + "@csstools/postcss-trigonometric-functions": "^4.0.9", + "@csstools/postcss-unset-value": "^4.0.0", + "autoprefixer": "^10.4.21", + "browserslist": "^4.26.0", + "css-blank-pseudo": "^7.0.1", + "css-has-pseudo": "^7.0.3", + "css-prefers-color-scheme": "^10.0.0", + "cssdb": "^8.4.2", + "postcss-attribute-case-insensitive": "^7.0.1", + "postcss-clamp": "^4.1.0", + "postcss-color-functional-notation": "^7.0.12", + "postcss-color-hex-alpha": "^10.0.0", + "postcss-color-rebeccapurple": "^10.0.0", + "postcss-custom-media": "^11.0.6", + "postcss-custom-properties": "^14.0.6", + "postcss-custom-selectors": "^8.0.5", + "postcss-dir-pseudo-class": "^9.0.1", + "postcss-double-position-gradients": "^6.0.4", + "postcss-focus-visible": "^10.0.1", + "postcss-focus-within": "^9.0.1", + "postcss-font-variant": "^5.0.0", + "postcss-gap-properties": "^6.0.0", + "postcss-image-set-function": "^7.0.0", + "postcss-lab-function": "^7.0.12", + "postcss-logical": "^8.1.0", + "postcss-nesting": "^13.0.2", + "postcss-opacity-percentage": "^3.0.0", + "postcss-overflow-shorthand": "^6.0.0", + "postcss-page-break": "^3.0.4", + "postcss-place": "^10.0.0", + "postcss-pseudo-class-any-link": "^10.0.1", + "postcss-replace-overflow-wrap": "^4.0.0", + "postcss-selector-not": "^8.0.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-pseudo-class-any-link": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-10.0.1.tgz", + "integrity": "sha512-3el9rXlBOqTFaMFkWDOkHUTQekFIYnaQY55Rsp8As8QQkpiSgIYEcF/6Ond93oHiDsGb4kad8zjt+NPlOC1H0Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-pseudo-class-any-link/node_modules/postcss-selector-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-reduce-idents": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-6.0.3.tgz", + "integrity": "sha512-G3yCqZDpsNPoQgbDUy3T0E6hqOQ5xigUtBQyrmq3tn2GxlyiL0yyl7H+T8ulQR6kOcHJ9t7/9H4/R2tv8tJbMA==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-reduce-initial": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.1.0.tgz", + "integrity": "sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.2.tgz", + "integrity": "sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-replace-overflow-wrap": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", + "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", + "license": "MIT", + "peerDependencies": { + "postcss": "^8.0.3" + } + }, + "node_modules/postcss-selector-not": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-8.0.1.tgz", + "integrity": "sha512-kmVy/5PYVb2UOhy0+LqUYAhKj7DUGDpSWa5LZqlkWJaaAV+dxxsOG3+St0yNLu6vsKD7Dmqx+nWQt0iil89+WA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-selector-not/node_modules/postcss-selector-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-sort-media-queries": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-5.2.0.tgz", + "integrity": "sha512-AZ5fDMLD8SldlAYlvi8NIqo0+Z8xnXU2ia0jxmuhxAU+Lqt9K+AlmLNJ/zWEnE9x+Zx3qL3+1K20ATgNOr3fAA==", + "license": "MIT", + "dependencies": { + "sort-css-media-queries": "2.2.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.4.23" + } + }, + "node_modules/postcss-svgo": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.3.tgz", + "integrity": "sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "svgo": "^3.2.0" + }, + "engines": { + "node": "^14 || ^16 || >= 18" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.4.tgz", + "integrity": "sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "license": "MIT" + }, + "node_modules/postcss-zindex": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-6.0.2.tgz", + "integrity": "sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/pretty-error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", + "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "node_modules/pretty-time": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", + "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/prism-react-renderer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.4.1.tgz", + "integrity": "sha512-ey8Ls/+Di31eqzUxC46h8MksNuGx/n0AAC8uKpwFau4RPDYLuE3EXTp8N8G2vX2N7UC/+IXeNUnlWBGGcAG+Ig==", + "license": "MIT", + "dependencies": { + "@types/prismjs": "^1.26.0", + "clsx": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.0.0" + } + }, + "node_modules/prismjs": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", + "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/property-information": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", + "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "license": "ISC" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pupa": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.3.0.tgz", + "integrity": "sha512-LjgDO2zPtoXP2wJpDjZrGdojii1uqO0cnwKoIoUzkfS98HDmbeiGmYiXo3lXeFlq2xvne1QFQhwYXSUCLKtEuA==", + "license": "MIT", + "dependencies": { + "escape-goat": "^4.0.0" + }, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react": { + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", + "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz", + "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.0" + } + }, + "node_modules/react-fast-compare": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", + "license": "MIT" + }, + "node_modules/react-helmet-async": { + "name": "@slorber/react-helmet-async", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@slorber/react-helmet-async/-/react-helmet-async-1.3.0.tgz", + "integrity": "sha512-e9/OK8VhwUSc67diWI8Rb3I0YgI9/SBQtnhe9aEuK6MhZm7ntZZimXgwXnd8W96YTmSOb9M4d8LwhRZyhWr/1A==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.12.5", + "invariant": "^2.2.4", + "prop-types": "^15.7.2", + "react-fast-compare": "^3.2.0", + "shallowequal": "^1.1.0" + }, + "peerDependencies": { + "react": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/react-json-view-lite": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-2.5.0.tgz", + "integrity": "sha512-tk7o7QG9oYyELWHL8xiMQ8x4WzjCzbWNyig3uexmkLb54r8jO0yH3WCWx8UZS0c49eSA4QUmG5caiRJ8fAn58g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/react-loadable": { + "name": "@docusaurus/react-loadable", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz", + "integrity": "sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==", + "license": "MIT", + "dependencies": { + "@types/react": "*" + }, + "peerDependencies": { + "react": "*" + } + }, + "node_modules/react-loadable-ssr-addon-v5-slorber": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.1.tgz", + "integrity": "sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.3" + }, + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "react-loadable": "*", + "webpack": ">=4.41.1 || 5.x" + } + }, + "node_modules/react-router": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", + "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.13", + "history": "^4.9.0", + "hoist-non-react-statics": "^3.1.0", + "loose-envify": "^1.3.1", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.2", + "react-is": "^16.6.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/react-router-config": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/react-router-config/-/react-router-config-5.1.1.tgz", + "integrity": "sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.1.2" + }, + "peerDependencies": { + "react": ">=15", + "react-router": ">=5" + } + }, + "node_modules/react-router-dom": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz", + "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.13", + "history": "^4.9.0", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.2", + "react-router": "5.3.4", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/recma-build-jsx": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-build-jsx/-/recma-build-jsx-1.0.0.tgz", + "integrity": "sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-build-jsx": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-jsx": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/recma-jsx/-/recma-jsx-1.0.1.tgz", + "integrity": "sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==", + "license": "MIT", + "dependencies": { + "acorn-jsx": "^5.0.0", + "estree-util-to-js": "^2.0.0", + "recma-parse": "^1.0.0", + "recma-stringify": "^1.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/recma-parse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-parse/-/recma-parse-1.0.0.tgz", + "integrity": "sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "esast-util-from-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-stringify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-stringify/-/recma-stringify-1.0.0.tgz", + "integrity": "sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-to-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", + "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regexpu-core": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz", + "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.2", + "regjsgen": "^0.8.0", + "regjsparser": "^0.13.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.2.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/registry-auth-token": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.1.0.tgz", + "integrity": "sha512-GdekYuwLXLxMuFTwAPg5UKGLW/UXzQrZvH/Zj791BQif5T05T0RsaLfHc9q3ZOKi7n+BoprPD9mJ0O0k4xzUlw==", + "license": "MIT", + "dependencies": { + "@pnpm/npm-conf": "^2.1.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/registry-url": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz", + "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==", + "license": "MIT", + "dependencies": { + "rc": "1.2.8" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.0.tgz", + "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==", + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~3.1.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/rehype-raw": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-raw": "^9.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-recma": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rehype-recma/-/rehype-recma-1.0.0.tgz", + "integrity": "sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "hast-util-to-estree": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/remark-directive": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.1.tgz", + "integrity": "sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-directive": "^3.0.0", + "micromark-extension-directive": "^3.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-emoji": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-emoji/-/remark-emoji-4.0.1.tgz", + "integrity": "sha512-fHdvsTR1dHkWKev9eNyhTo4EFwbUvJ8ka9SgeWkMPYFX4WoI7ViVBms3PjlQYgw5TLvNQso3GUB/b/8t3yo+dg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.2", + "emoticon": "^4.0.1", + "mdast-util-find-and-replace": "^3.0.1", + "node-emoji": "^2.1.0", + "unified": "^11.0.4" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/remark-frontmatter": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz", + "integrity": "sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-frontmatter": "^2.0.0", + "micromark-extension-frontmatter": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-mdx": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.1.1.tgz", + "integrity": "sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==", + "license": "MIT", + "dependencies": { + "mdast-util-mdx": "^3.0.0", + "micromark-extension-mdxjs": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", + "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/renderkid": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", + "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", + "license": "MIT", + "dependencies": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^6.0.1" + } + }, + "node_modules/renderkid/node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/renderkid/node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-like": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", + "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", + "engines": { + "node": "*" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "license": "MIT" + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pathname": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==", + "license": "MIT" + }, + "node_modules/responselike": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", + "license": "MIT", + "dependencies": { + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rtlcss": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.3.0.tgz", + "integrity": "sha512-FI+pHEn7Wc4NqKXMXFM+VAYKEj/mRIcW4h24YVwVtyjI+EqGrLc2Hx/Ny0lrZ21cBWU2goLy36eqMcNj3AQJig==", + "license": "MIT", + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0", + "postcss": "^8.4.21", + "strip-json-comments": "^3.1.1" + }, + "bin": { + "rtlcss": "bin/rtlcss.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/run-applescript": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/sax": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.3.tgz", + "integrity": "sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==", + "license": "BlueOak-1.0.0" + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/schema-dts": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/schema-dts/-/schema-dts-1.1.5.tgz", + "integrity": "sha512-RJr9EaCmsLzBX2NDiO5Z3ux2BVosNZN5jo0gWgsyKvxKIUL5R3swNvoorulAeL9kLB0iTSX7V6aokhla2m7xbg==", + "license": "Apache-2.0" + }, + "node_modules/schema-utils": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/search-insights": { + "version": "2.17.3", + "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz", + "integrity": "sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==", + "license": "MIT", + "peer": true + }, + "node_modules/section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "license": "MIT" + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "license": "MIT", + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", + "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-handler": { + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.6.tgz", + "integrity": "sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==", + "license": "MIT", + "dependencies": { + "bytes": "3.0.0", + "content-disposition": "0.5.2", + "mime-types": "2.1.18", + "minimatch": "3.1.2", + "path-is-inside": "1.0.2", + "path-to-regexp": "3.3.0", + "range-parser": "1.2.0" + } + }, + "node_modules/serve-handler/node_modules/path-to-regexp": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz", + "integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==", + "license": "MIT" + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "license": "ISC" + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "license": "ISC" + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" + }, + "node_modules/sirv": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", + "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "license": "MIT" + }, + "node_modules/sitemap": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.2.tgz", + "integrity": "sha512-ARCqzHJ0p4gWt+j7NlU5eDlIO9+Rkr/JhPFZKKQ1l5GCus7rJH4UdrlVAh0xC/gDS/Qir2UMxqYNHtsKr2rpCw==", + "license": "MIT", + "dependencies": { + "@types/node": "^17.0.5", + "@types/sax": "^1.2.1", + "arg": "^5.0.0", + "sax": "^1.2.4" + }, + "bin": { + "sitemap": "dist/cli.js" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.6.0" + } + }, + "node_modules/sitemap/node_modules/@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", + "license": "MIT" + }, + "node_modules/skin-tone": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", + "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", + "license": "MIT", + "dependencies": { + "unicode-emoji-modifier-base": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "license": "MIT", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "license": "MIT", + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/sort-css-media-queries": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/sort-css-media-queries/-/sort-css-media-queries-2.2.0.tgz", + "integrity": "sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA==", + "license": "MIT", + "engines": { + "node": ">= 6.3.0" + } + }, + "node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "license": "BSD-3-Clause" + }, + "node_modules/srcset": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/srcset/-/srcset-4.0.0.tgz", + "integrity": "sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "license": "MIT" + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "license": "BSD-2-Clause", + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-to-js": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.19.tgz", + "integrity": "sha512-Ev+SgeqiNGT1ufsXyVC5RrJRXdrkRJ1Gol9Qw7Pb72YCKJXrBvP0ckZhBeVSrw2m06DJpei2528uIpjMb4TsoQ==", + "license": "MIT", + "dependencies": { + "style-to-object": "1.0.12" + } + }, + "node_modules/style-to-object": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.12.tgz", + "integrity": "sha512-ddJqYnoT4t97QvN2C95bCgt+m7AAgXjVnkk/jxAfmp7EAB8nnqqZYEbMd3em7/vEomDb2LAQKAy1RFfv41mdNw==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.2.6" + } + }, + "node_modules/stylehacks": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.1.1.tgz", + "integrity": "sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", + "license": "MIT" + }, + "node_modules/svgo": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", + "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", + "license": "MIT", + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^5.1.0", + "css-tree": "^2.3.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/svgo/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/swr": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/swr/-/swr-2.3.6.tgz", + "integrity": "sha512-wfHRmHWk/isGNMwlLGlZX5Gzz/uTgo0o2IRuTMcf4CPuPFJZlq0rDaKUx+ozB5nBOReNV1kiOyzMfj+MBMikLw==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.3", + "use-sync-external-store": "^1.4.0" + }, + "peerDependencies": { + "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/tapable": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser": { + "version": "5.44.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.1.tgz", + "integrity": "sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==", + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", + "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" + }, + "node_modules/thingies": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-2.5.0.tgz", + "integrity": "sha512-s+2Bwztg6PhWUD7XMfeYm5qliDdSiZm7M7n8KjTkIsm3l/2lgVRc2/Gx/v+ZX8lT4FMA+i8aQvhcWylldc+ZNw==", + "license": "MIT", + "engines": { + "node": ">=10.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "^2" + } + }, + "node_modules/throttleit": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-2.1.0.tgz", + "integrity": "sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "license": "MIT" + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "license": "MIT" + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", + "license": "MIT" + }, + "node_modules/tinypool": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tree-dump": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.1.0.tgz", + "integrity": "sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "license": "MIT", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "devOptional": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "license": "MIT" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-emoji-modifier-base": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", + "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", + "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", + "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unique-string": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", + "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", + "license": "MIT", + "dependencies": { + "crypto-random-string": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", + "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", + "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", + "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/update-notifier": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-6.0.2.tgz", + "integrity": "sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==", + "license": "BSD-2-Clause", + "dependencies": { + "boxen": "^7.0.0", + "chalk": "^5.0.1", + "configstore": "^6.0.0", + "has-yarn": "^3.0.0", + "import-lazy": "^4.0.0", + "is-ci": "^3.0.1", + "is-installed-globally": "^0.4.0", + "is-npm": "^6.0.0", + "is-yarn-global": "^0.4.0", + "latest-version": "^7.0.0", + "pupa": "^3.1.0", + "semver": "^7.3.7", + "semver-diff": "^4.0.0", + "xdg-basedir": "^5.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/yeoman/update-notifier?sponsor=1" + } + }, + "node_modules/update-notifier/node_modules/boxen": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", + "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", + "license": "MIT", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^7.0.1", + "chalk": "^5.2.0", + "cli-boxes": "^3.0.0", + "string-width": "^5.1.2", + "type-fest": "^2.13.0", + "widest-line": "^4.0.1", + "wrap-ansi": "^8.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-notifier/node_modules/camelcase": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", + "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-notifier/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-loader": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", + "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "mime-types": "^2.1.27", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "file-loader": "*", + "webpack": "^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "file-loader": { + "optional": true + } + } + }, + "node_modules/url-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/url-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/url-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "license": "MIT" + }, + "node_modules/url-loader/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/url-loader/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/url-loader/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", + "license": "MIT" + }, + "node_modules/utility-types": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", + "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/value-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==", + "license": "MIT" + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/watchpack": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", + "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", + "license": "MIT", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "license": "MIT", + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/webpack": { + "version": "5.102.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.102.1.tgz", + "integrity": "sha512-7h/weGm9d/ywQ6qzJ+Xy+r9n/3qgp/thalBbpOi5i223dPXKi04IBtqPN9nTd+jBc7QKfvDbaBnFipYp4sJAUQ==", + "license": "MIT", + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.15.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.26.3", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.3", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", + "terser-webpack-plugin": "^5.3.11", + "watchpack": "^2.4.4", + "webpack-sources": "^3.3.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-bundle-analyzer": { + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz", + "integrity": "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==", + "license": "MIT", + "dependencies": { + "@discoveryjs/json-ext": "0.5.7", + "acorn": "^8.0.4", + "acorn-walk": "^8.0.0", + "commander": "^7.2.0", + "debounce": "^1.2.1", + "escape-string-regexp": "^4.0.0", + "gzip-size": "^6.0.0", + "html-escaper": "^2.0.2", + "opener": "^1.5.2", + "picocolors": "^1.0.0", + "sirv": "^2.0.3", + "ws": "^7.3.1" + }, + "bin": { + "webpack-bundle-analyzer": "lib/bin/analyzer.js" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/webpack-bundle-analyzer/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/webpack-dev-middleware": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.5.tgz", + "integrity": "sha512-uxQ6YqGdE4hgDKNf7hUiPXOdtkXvBJXrfEGYSx7P7LC8hnUYGK70X6xQXUvXeNyBDDcsiQXpG2m3G9vxowaEuA==", + "license": "MIT", + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^4.43.1", + "mime-types": "^3.0.1", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-middleware/node_modules/mime-types": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", + "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-middleware/node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-server": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.2.tgz", + "integrity": "sha512-QcQ72gh8a+7JO63TAx/6XZf/CWhgMzu5m0QirvPfGvptOusAxG12w2+aua1Jkjr7hzaWDnJ2n6JFeexMHI+Zjg==", + "license": "MIT", + "dependencies": { + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^4.17.21", + "@types/express-serve-static-core": "^4.17.21", + "@types/serve-index": "^1.9.4", + "@types/serve-static": "^1.15.5", + "@types/sockjs": "^0.3.36", + "@types/ws": "^8.5.10", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.2.1", + "chokidar": "^3.6.0", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "express": "^4.21.2", + "graceful-fs": "^4.2.6", + "http-proxy-middleware": "^2.0.9", + "ipaddr.js": "^2.1.0", + "launch-editor": "^2.6.1", + "open": "^10.0.3", + "p-retry": "^6.2.0", + "schema-utils": "^4.2.0", + "selfsigned": "^2.4.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^7.4.2", + "ws": "^8.18.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/webpack-dev-server/node_modules/open": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", + "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "wsl-utils": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/webpack-merge": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", + "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", + "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpackbar": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-6.0.1.tgz", + "integrity": "sha512-TnErZpmuKdwWBdMoexjio3KKX6ZtoKHRVvLIU0A47R0VVBDtx3ZyOJDktgYixhoJokZTYTt1Z37OkO9pnGJa9Q==", + "license": "MIT", + "dependencies": { + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "consola": "^3.2.3", + "figures": "^3.2.0", + "markdown-table": "^2.0.0", + "pretty-time": "^1.1.0", + "std-env": "^3.7.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=14.21.3" + }, + "peerDependencies": { + "webpack": "3 || 4 || 5" + } + }, + "node_modules/webpackbar/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/webpackbar/node_modules/markdown-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", + "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", + "license": "MIT", + "dependencies": { + "repeat-string": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/webpackbar/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/webpackbar/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/widest-line": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", + "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", + "license": "MIT", + "dependencies": { + "string-width": "^5.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/wsl-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", + "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wsl-utils/node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/xdg-basedir": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", + "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/xml-js": { + "version": "1.6.11", + "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", + "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", + "license": "MIT", + "dependencies": { + "sax": "^1.2.4" + }, + "bin": { + "xml-js": "bin/cli.js" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", + "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.12.tgz", + "integrity": "sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/docs/package.json b/docs/package.json new file mode 100644 index 000000000..1c9f52156 --- /dev/null +++ b/docs/package.json @@ -0,0 +1,50 @@ +{ + "name": "docs", + "version": "0.0.0", + "private": true, + "scripts": { + "docusaurus": "docusaurus", + "start": "docusaurus start", + "build": "docusaurus build", + "swizzle": "docusaurus swizzle", + "deploy": "docusaurus deploy", + "clear": "docusaurus clear", + "serve": "docusaurus serve", + "write-translations": "docusaurus write-translations", + "write-heading-ids": "docusaurus write-heading-ids", + "typecheck": "tsc" + }, + "dependencies": { + "@docusaurus/core": "3.9.2", + "@docusaurus/plugin-client-redirects": "^3.9.2", + "@docusaurus/preset-classic": "3.9.2", + "@mdx-js/react": "^3.0.0", + "@scalar/docusaurus": "^0.7.21", + "clsx": "^2.0.0", + "prism-react-renderer": "^2.3.0", + "react": "^19.0.0", + "react-dom": "^19.0.0" + }, + "devDependencies": { + "@docusaurus/module-type-aliases": "3.9.2", + "@docusaurus/tsconfig": "3.9.2", + "@docusaurus/types": "3.9.2", + "typescript": "~5.6.2" + }, + "browserslist": { + "production": [ + ">0.5%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 3 chrome version", + "last 3 firefox version", + "last 5 safari version" + ] + }, + "engines": { + "node": ">=20.0" + }, + "packageManager": "pnpm@10.22.0+sha512.bf049efe995b28f527fd2b41ae0474ce29186f7edcb3bf545087bd61fbbebb2bf75362d1307fda09c2d288e1e499787ac12d4fcb617a974718a6051f2eee741c" +} diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml new file mode 100644 index 000000000..7692b806f --- /dev/null +++ b/docs/pnpm-lock.yaml @@ -0,0 +1,11448 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@docusaurus/core': + specifier: 3.9.2 + version: 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/plugin-client-redirects': + specifier: ^3.9.2 + version: 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/preset-classic': + specifier: 3.9.2 + version: 3.9.2(@algolia/client-search@5.43.0)(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(search-insights@2.17.3)(typescript@5.6.3) + '@mdx-js/react': + specifier: ^3.0.0 + version: 3.1.1(@types/react@19.2.4)(react@19.2.0) + '@scalar/docusaurus': + specifier: ^0.7.21 + version: 0.7.21(@docusaurus/utils@3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0) + clsx: + specifier: ^2.0.0 + version: 2.1.1 + prism-react-renderer: + specifier: ^2.3.0 + version: 2.4.1(react@19.2.0) + react: + specifier: ^19.0.0 + version: 19.2.0 + react-dom: + specifier: ^19.0.0 + version: 19.2.0(react@19.2.0) + devDependencies: + '@docusaurus/module-type-aliases': + specifier: 3.9.2 + version: 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/tsconfig': + specifier: 3.9.2 + version: 3.9.2 + '@docusaurus/types': + specifier: 3.9.2 + version: 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + typescript: + specifier: ~5.6.2 + version: 5.6.3 + +packages: + + '@ai-sdk/gateway@2.0.9': + resolution: {integrity: sha512-E6x4h5CPPPJ0za1r5HsLtHbeI+Tp3H+YFtcH8G3dSSPFE6w+PZINzB4NxLZmg1QqSeA5HTP3ZEzzsohp0o2GEw==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/provider-utils@3.0.17': + resolution: {integrity: sha512-TR3Gs4I3Tym4Ll+EPdzRdvo/rc8Js6c4nVhFLuvGLX/Y4V9ZcQMa/HTiYsHEgmYrf1zVi6Q145UEZUfleOwOjw==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/provider@2.0.0': + resolution: {integrity: sha512-6o7Y2SeO9vFKB8lArHXehNuusnpddKPk7xqL7T2/b+OvXMRIXUO1rR4wcv1hAFUAT9avGZshty3Wlua/XA7TvA==} + engines: {node: '>=18'} + + '@ai-sdk/react@2.0.93': + resolution: {integrity: sha512-2TzhpQr10HuWxpqyHpSAUMRUqD1G2O73J2sAaJChomVDbjr7BwpM0mdR3aRamCXNtuLiJmTFQhbNzw8fXMBdYw==} + engines: {node: '>=18'} + peerDependencies: + react: ^18 || ^19 || ^19.0.0-rc + zod: ^3.25.76 || ^4.1.8 + peerDependenciesMeta: + zod: + optional: true + + '@algolia/abtesting@1.9.0': + resolution: {integrity: sha512-4q9QCxFPiDIx1n5w41A1JMkrXI8p0ugCQnCGFtCKZPmWtwgWCqwVRncIbp++81xSELFZVQUfiB7Kbsla1tIBSw==} + engines: {node: '>= 14.0.0'} + + '@algolia/autocomplete-core@1.19.2': + resolution: {integrity: sha512-mKv7RyuAzXvwmq+0XRK8HqZXt9iZ5Kkm2huLjgn5JoCPtDy+oh9yxUMfDDaVCw0oyzZ1isdJBc7l9nuCyyR7Nw==} + + '@algolia/autocomplete-plugin-algolia-insights@1.19.2': + resolution: {integrity: sha512-TjxbcC/r4vwmnZaPwrHtkXNeqvlpdyR+oR9Wi2XyfORkiGkLTVhX2j+O9SaCCINbKoDfc+c2PB8NjfOnz7+oKg==} + peerDependencies: + search-insights: '>= 1 < 3' + + '@algolia/autocomplete-shared@1.19.2': + resolution: {integrity: sha512-jEazxZTVD2nLrC+wYlVHQgpBoBB5KPStrJxLzsIFl6Kqd1AlG9sIAGl39V5tECLpIQzB3Qa2T6ZPJ1ChkwMK/w==} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + + '@algolia/client-abtesting@5.43.0': + resolution: {integrity: sha512-YsKYkohIMxiYEAu8nppZi5EioYDUIo9Heoor8K8vMUnkUtGCOEU/Q4p5OWaYSSBx3evo09Ga9rG4jsKViIcDzQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-analytics@5.43.0': + resolution: {integrity: sha512-kDGJWt3nzf0nu5RPFXQhNGl6Q0cn35fazxVWXhd0Fw3Vo6gcVfrcezcBenHb66laxnVJ7uwr1uKhmsu3Wy25sQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-common@5.43.0': + resolution: {integrity: sha512-RAFipkAnI8xhL/Sgi/gpXgNWN5HDM6F7z4NNNOcI8ZMYysZEBsqVXojg/WdKEKkQCOHVTZ3mooIjc5BaQdyVtA==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-insights@5.43.0': + resolution: {integrity: sha512-PmVs83THco8Qig3cAjU9a5eAGaSxsfgh7PdmWMQFE/MCmIcLPv0MVpgfcGGyPjZGYvPC4cg+3q7JJxcNSsEaTg==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-personalization@5.43.0': + resolution: {integrity: sha512-Bs4zMLXvkAr19FSOZWNizlNUpRFxZVxtvyEJ+q3n3+hPZUcKjo0LIh15qghhRcQPEihjBN6Gr/U+AqRfOCsvnA==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-query-suggestions@5.43.0': + resolution: {integrity: sha512-pwHv+z8TZAKbwAWt9+v2gIqlqcCFiMdteTdgdPn2yOBRx4WUQdsIWAaG9GiV3by8jO51FuFQnTohhauuI63y3A==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-search@5.43.0': + resolution: {integrity: sha512-wKy6x6fKcnB1CsfeNNdGp4dzLzz04k8II3JLt6Sp81F8s57Ks3/K9qsysmL9SJa8P486s719bBttVLE8JJYurQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/events@4.0.1': + resolution: {integrity: sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==} + + '@algolia/ingestion@1.43.0': + resolution: {integrity: sha512-TA21h2KwqCUyPXhSAWF3R2UES/FAnzjaVPDI6cRPXeadX+pdrGN0GWat5gSUATJVcMHECn+lGvuMMRxO86o2Pg==} + engines: {node: '>= 14.0.0'} + + '@algolia/monitoring@1.43.0': + resolution: {integrity: sha512-rvWVEiA1iLcFmHS3oIXGIBreHIxNZqEFDjiNyRtLEffgd62kul2DjXM7H5bOouDMTo1ywMWT9OeQnzrhlTGAwA==} + engines: {node: '>= 14.0.0'} + + '@algolia/recommend@5.43.0': + resolution: {integrity: sha512-scCijGd38npvH2uHbYhO4f1SR8It5R2FZqOjNcMfw/7Ph7Hxvl+cd7Mo6RzIxsNRcLW5RrwjtpTK3gpDe8r/WQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-browser-xhr@5.43.0': + resolution: {integrity: sha512-jMkRLWJYr4Hcmpl89e4vIWs69Mkf8Uwx7MG5ZKk2UxW3G3TmouGjI0Ph5mVPmg3Jf1UG3AdmVDc4XupzycT1Jw==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-fetch@5.43.0': + resolution: {integrity: sha512-KyQiVz+HdYtissC0J9KIGhHhKytQyJX+82GVsbv5rSCXbETnAoojvUyCn+3KRtWUvMDYCsZ+Y7hM71STTUJUJg==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-node-http@5.43.0': + resolution: {integrity: sha512-UnUBNY0U+oT0bkYDsEqVsCkErC2w7idk4CRiLSzicqY8tGylD9oP0j13X/fse1CuiAFCCr3jfl+cBlN6dC0OFw==} + engines: {node: '>= 14.0.0'} + + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.28.5': + resolution: {integrity: sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.28.5': + resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.28.5': + resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.27.3': + resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.27.2': + resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.28.5': + resolution: {integrity: sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-create-regexp-features-plugin@7.28.5': + resolution: {integrity: sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-define-polyfill-provider@0.6.5': + resolution: {integrity: sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-member-expression-to-functions@7.28.5': + resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.27.1': + resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.3': + resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-remap-async-to-generator@7.27.1': + resolution: {integrity: sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-replace-supers@7.27.1': + resolution: {integrity: sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-wrap-function@7.28.3': + resolution: {integrity: sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.28.4': + resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.28.5': + resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5': + resolution: {integrity: sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1': + resolution: {integrity: sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1': + resolution: {integrity: sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1': + resolution: {integrity: sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.13.0 + + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3': + resolution: {integrity: sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2': + resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-dynamic-import@7.8.3': + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-assertions@7.27.1': + resolution: {integrity: sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-attributes@7.27.1': + resolution: {integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.27.1': + resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.27.1': + resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-unicode-sets-regex@7.18.6': + resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-arrow-functions@7.27.1': + resolution: {integrity: sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-async-generator-functions@7.28.0': + resolution: {integrity: sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-async-to-generator@7.27.1': + resolution: {integrity: sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-block-scoped-functions@7.27.1': + resolution: {integrity: sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-block-scoping@7.28.5': + resolution: {integrity: sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-class-properties@7.27.1': + resolution: {integrity: sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-class-static-block@7.28.3': + resolution: {integrity: sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.12.0 + + '@babel/plugin-transform-classes@7.28.4': + resolution: {integrity: sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-computed-properties@7.27.1': + resolution: {integrity: sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-destructuring@7.28.5': + resolution: {integrity: sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-dotall-regex@7.27.1': + resolution: {integrity: sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-duplicate-keys@7.27.1': + resolution: {integrity: sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1': + resolution: {integrity: sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-dynamic-import@7.27.1': + resolution: {integrity: sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-explicit-resource-management@7.28.0': + resolution: {integrity: sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-exponentiation-operator@7.28.5': + resolution: {integrity: sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-export-namespace-from@7.27.1': + resolution: {integrity: sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-for-of@7.27.1': + resolution: {integrity: sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-function-name@7.27.1': + resolution: {integrity: sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-json-strings@7.27.1': + resolution: {integrity: sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-literals@7.27.1': + resolution: {integrity: sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-logical-assignment-operators@7.28.5': + resolution: {integrity: sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-member-expression-literals@7.27.1': + resolution: {integrity: sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-amd@7.27.1': + resolution: {integrity: sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-commonjs@7.27.1': + resolution: {integrity: sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-systemjs@7.28.5': + resolution: {integrity: sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-umd@7.27.1': + resolution: {integrity: sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-named-capturing-groups-regex@7.27.1': + resolution: {integrity: sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-new-target@7.27.1': + resolution: {integrity: sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-nullish-coalescing-operator@7.27.1': + resolution: {integrity: sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-numeric-separator@7.27.1': + resolution: {integrity: sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-object-rest-spread@7.28.4': + resolution: {integrity: sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-object-super@7.27.1': + resolution: {integrity: sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-optional-catch-binding@7.27.1': + resolution: {integrity: sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-optional-chaining@7.28.5': + resolution: {integrity: sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-parameters@7.27.7': + resolution: {integrity: sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-private-methods@7.27.1': + resolution: {integrity: sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-private-property-in-object@7.27.1': + resolution: {integrity: sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-property-literals@7.27.1': + resolution: {integrity: sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-constant-elements@7.27.1': + resolution: {integrity: sha512-edoidOjl/ZxvYo4lSBOQGDSyToYVkTAwyVoa2tkuYTSmjrB1+uAedoL5iROVLXkxH+vRgA7uP4tMg2pUJpZ3Ug==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-display-name@7.28.0': + resolution: {integrity: sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-development@7.27.1': + resolution: {integrity: sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx@7.27.1': + resolution: {integrity: sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-pure-annotations@7.27.1': + resolution: {integrity: sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-regenerator@7.28.4': + resolution: {integrity: sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-regexp-modifiers@7.27.1': + resolution: {integrity: sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-reserved-words@7.27.1': + resolution: {integrity: sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-runtime@7.28.5': + resolution: {integrity: sha512-20NUVgOrinudkIBzQ2bNxP08YpKprUkRTiRSd2/Z5GOdPImJGkoN4Z7IQe1T5AdyKI1i5L6RBmluqdSzvaq9/w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-shorthand-properties@7.27.1': + resolution: {integrity: sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-spread@7.27.1': + resolution: {integrity: sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-sticky-regex@7.27.1': + resolution: {integrity: sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-template-literals@7.27.1': + resolution: {integrity: sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typeof-symbol@7.27.1': + resolution: {integrity: sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.28.5': + resolution: {integrity: sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-escapes@7.27.1': + resolution: {integrity: sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-property-regex@7.27.1': + resolution: {integrity: sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-regex@7.27.1': + resolution: {integrity: sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-sets-regex@7.27.1': + resolution: {integrity: sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/preset-env@7.28.5': + resolution: {integrity: sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-modules@0.1.6-no-external-plugins': + resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} + peerDependencies: + '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 + + '@babel/preset-react@7.28.5': + resolution: {integrity: sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-typescript@7.28.5': + resolution: {integrity: sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime-corejs3@7.28.4': + resolution: {integrity: sha512-h7iEYiW4HebClDEhtvFObtPmIvrd1SSfpI9EhOeKk4CtIK/ngBWFpuhCzhdmRKtg71ylcue+9I6dv54XYO1epQ==} + engines: {node: '>=6.9.0'} + + '@babel/runtime@7.28.4': + resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.27.2': + resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.28.5': + resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.28.5': + resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + engines: {node: '>=6.9.0'} + + '@colors/colors@1.5.0': + resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} + engines: {node: '>=0.1.90'} + + '@csstools/cascade-layer-name-parser@2.0.5': + resolution: {integrity: sha512-p1ko5eHgV+MgXFVa4STPKpvPxr6ReS8oS2jzTukjR74i5zJNyWO1ZM1m8YKBXnzDKWfBN1ztLYlHxbVemDD88A==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/color-helpers@5.1.0': + resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} + engines: {node: '>=18'} + + '@csstools/css-calc@2.1.4': + resolution: {integrity: sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-color-parser@3.1.0': + resolution: {integrity: sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-parser-algorithms@3.0.5': + resolution: {integrity: sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-tokenizer@3.0.4': + resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} + engines: {node: '>=18'} + + '@csstools/media-query-list-parser@4.0.3': + resolution: {integrity: sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/postcss-alpha-function@1.0.1': + resolution: {integrity: sha512-isfLLwksH3yHkFXfCI2Gcaqg7wGGHZZwunoJzEZk0yKYIokgre6hYVFibKL3SYAoR1kBXova8LB+JoO5vZzi9w==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-cascade-layers@5.0.2': + resolution: {integrity: sha512-nWBE08nhO8uWl6kSAeCx4im7QfVko3zLrtgWZY4/bP87zrSPpSyN/3W3TDqz1jJuH+kbKOHXg5rJnK+ZVYcFFg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-color-function-display-p3-linear@1.0.1': + resolution: {integrity: sha512-E5qusdzhlmO1TztYzDIi8XPdPoYOjoTY6HBYBCYSj+Gn4gQRBlvjgPQXzfzuPQqt8EhkC/SzPKObg4Mbn8/xMg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-color-function@4.0.12': + resolution: {integrity: sha512-yx3cljQKRaSBc2hfh8rMZFZzChaFgwmO2JfFgFr1vMcF3C/uyy5I4RFIBOIWGq1D+XbKCG789CGkG6zzkLpagA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-color-mix-function@3.0.12': + resolution: {integrity: sha512-4STERZfCP5Jcs13P1U5pTvI9SkgLgfMUMhdXW8IlJWkzOOOqhZIjcNhWtNJZes2nkBDsIKJ0CJtFtuaZ00moag==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-color-mix-variadic-function-arguments@1.0.2': + resolution: {integrity: sha512-rM67Gp9lRAkTo+X31DUqMEq+iK+EFqsidfecmhrteErxJZb6tUoJBVQca1Vn1GpDql1s1rD1pKcuYzMsg7Z1KQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-content-alt-text@2.0.8': + resolution: {integrity: sha512-9SfEW9QCxEpTlNMnpSqFaHyzsiRpZ5J5+KqCu1u5/eEJAWsMhzT40qf0FIbeeglEvrGRMdDzAxMIz3wqoGSb+Q==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-contrast-color-function@2.0.12': + resolution: {integrity: sha512-YbwWckjK3qwKjeYz/CijgcS7WDUCtKTd8ShLztm3/i5dhh4NaqzsbYnhm4bjrpFpnLZ31jVcbK8YL77z3GBPzA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-exponential-functions@2.0.9': + resolution: {integrity: sha512-abg2W/PI3HXwS/CZshSa79kNWNZHdJPMBXeZNyPQFbbj8sKO3jXxOt/wF7juJVjyDTc6JrvaUZYFcSBZBhaxjw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-font-format-keywords@4.0.0': + resolution: {integrity: sha512-usBzw9aCRDvchpok6C+4TXC57btc4bJtmKQWOHQxOVKen1ZfVqBUuCZ/wuqdX5GHsD0NRSr9XTP+5ID1ZZQBXw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-gamut-mapping@2.0.11': + resolution: {integrity: sha512-fCpCUgZNE2piVJKC76zFsgVW1apF6dpYsqGyH8SIeCcM4pTEsRTWTLCaJIMKFEundsCKwY1rwfhtrio04RJ4Dw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-gradients-interpolation-method@5.0.12': + resolution: {integrity: sha512-jugzjwkUY0wtNrZlFeyXzimUL3hN4xMvoPnIXxoZqxDvjZRiSh+itgHcVUWzJ2VwD/VAMEgCLvtaJHX+4Vj3Ow==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-hwb-function@4.0.12': + resolution: {integrity: sha512-mL/+88Z53KrE4JdePYFJAQWFrcADEqsLprExCM04GDNgHIztwFzj0Mbhd/yxMBngq0NIlz58VVxjt5abNs1VhA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-ic-unit@4.0.4': + resolution: {integrity: sha512-yQ4VmossuOAql65sCPppVO1yfb7hDscf4GseF0VCA/DTDaBc0Wtf8MTqVPfjGYlT5+2buokG0Gp7y0atYZpwjg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-initial@2.0.1': + resolution: {integrity: sha512-L1wLVMSAZ4wovznquK0xmC7QSctzO4D0Is590bxpGqhqjboLXYA16dWZpfwImkdOgACdQ9PqXsuRroW6qPlEsg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-is-pseudo-class@5.0.3': + resolution: {integrity: sha512-jS/TY4SpG4gszAtIg7Qnf3AS2pjcUM5SzxpApOrlndMeGhIbaTzWBzzP/IApXoNWEW7OhcjkRT48jnAUIFXhAQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-light-dark-function@2.0.11': + resolution: {integrity: sha512-fNJcKXJdPM3Lyrbmgw2OBbaioU7yuKZtiXClf4sGdQttitijYlZMD5K7HrC/eF83VRWRrYq6OZ0Lx92leV2LFA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-logical-float-and-clear@3.0.0': + resolution: {integrity: sha512-SEmaHMszwakI2rqKRJgE+8rpotFfne1ZS6bZqBoQIicFyV+xT1UF42eORPxJkVJVrH9C0ctUgwMSn3BLOIZldQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-logical-overflow@2.0.0': + resolution: {integrity: sha512-spzR1MInxPuXKEX2csMamshR4LRaSZ3UXVaRGjeQxl70ySxOhMpP2252RAFsg8QyyBXBzuVOOdx1+bVO5bPIzA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-logical-overscroll-behavior@2.0.0': + resolution: {integrity: sha512-e/webMjoGOSYfqLunyzByZj5KKe5oyVg/YSbie99VEaSDE2kimFm0q1f6t/6Jo+VVCQ/jbe2Xy+uX+C4xzWs4w==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-logical-resize@3.0.0': + resolution: {integrity: sha512-DFbHQOFW/+I+MY4Ycd/QN6Dg4Hcbb50elIJCfnwkRTCX05G11SwViI5BbBlg9iHRl4ytB7pmY5ieAFk3ws7yyg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-logical-viewport-units@3.0.4': + resolution: {integrity: sha512-q+eHV1haXA4w9xBwZLKjVKAWn3W2CMqmpNpZUk5kRprvSiBEGMgrNH3/sJZ8UA3JgyHaOt3jwT9uFa4wLX4EqQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-media-minmax@2.0.9': + resolution: {integrity: sha512-af9Qw3uS3JhYLnCbqtZ9crTvvkR+0Se+bBqSr7ykAnl9yKhk6895z9rf+2F4dClIDJWxgn0iZZ1PSdkhrbs2ig==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-media-queries-aspect-ratio-number-values@3.0.5': + resolution: {integrity: sha512-zhAe31xaaXOY2Px8IYfoVTB3wglbJUVigGphFLj6exb7cjZRH9A6adyE22XfFK3P2PzwRk0VDeTJmaxpluyrDg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-nested-calc@4.0.0': + resolution: {integrity: sha512-jMYDdqrQQxE7k9+KjstC3NbsmC063n1FTPLCgCRS2/qHUbHM0mNy9pIn4QIiQGs9I/Bg98vMqw7mJXBxa0N88A==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-normalize-display-values@4.0.0': + resolution: {integrity: sha512-HlEoG0IDRoHXzXnkV4in47dzsxdsjdz6+j7MLjaACABX2NfvjFS6XVAnpaDyGesz9gK2SC7MbNwdCHusObKJ9Q==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-oklab-function@4.0.12': + resolution: {integrity: sha512-HhlSmnE1NKBhXsTnNGjxvhryKtO7tJd1w42DKOGFD6jSHtYOrsJTQDKPMwvOfrzUAk8t7GcpIfRyM7ssqHpFjg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-progressive-custom-properties@4.2.1': + resolution: {integrity: sha512-uPiiXf7IEKtUQXsxu6uWtOlRMXd2QWWy5fhxHDnPdXKCQckPP3E34ZgDoZ62r2iT+UOgWsSbM4NvHE5m3mAEdw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-random-function@2.0.1': + resolution: {integrity: sha512-q+FQaNiRBhnoSNo+GzqGOIBKoHQ43lYz0ICrV+UudfWnEF6ksS6DsBIJSISKQT2Bvu3g4k6r7t0zYrk5pDlo8w==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-relative-color-syntax@3.0.12': + resolution: {integrity: sha512-0RLIeONxu/mtxRtf3o41Lq2ghLimw0w9ByLWnnEVuy89exmEEq8bynveBxNW3nyHqLAFEeNtVEmC1QK9MZ8Huw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-scope-pseudo-class@4.0.1': + resolution: {integrity: sha512-IMi9FwtH6LMNuLea1bjVMQAsUhFxJnyLSgOp/cpv5hrzWmrUYU5fm0EguNDIIOHUqzXode8F/1qkC/tEo/qN8Q==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-sign-functions@1.1.4': + resolution: {integrity: sha512-P97h1XqRPcfcJndFdG95Gv/6ZzxUBBISem0IDqPZ7WMvc/wlO+yU0c5D/OCpZ5TJoTt63Ok3knGk64N+o6L2Pg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-stepped-value-functions@4.0.9': + resolution: {integrity: sha512-h9btycWrsex4dNLeQfyU3y3w40LMQooJWFMm/SK9lrKguHDcFl4VMkncKKoXi2z5rM9YGWbUQABI8BT2UydIcA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-text-decoration-shorthand@4.0.3': + resolution: {integrity: sha512-KSkGgZfx0kQjRIYnpsD7X2Om9BUXX/Kii77VBifQW9Ih929hK0KNjVngHDH0bFB9GmfWcR9vJYJJRvw/NQjkrA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-trigonometric-functions@4.0.9': + resolution: {integrity: sha512-Hnh5zJUdpNrJqK9v1/E3BbrQhaDTj5YiX7P61TOvUhoDHnUmsNNxcDAgkQ32RrcWx9GVUvfUNPcUkn8R3vIX6A==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/postcss-unset-value@4.0.0': + resolution: {integrity: sha512-cBz3tOCI5Fw6NIFEwU3RiwK6mn3nKegjpJuzCndoGq3BZPkUjnsq7uQmIeMNeMbMk7YD2MfKcgCpZwX5jyXqCA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@csstools/selector-resolve-nested@3.1.0': + resolution: {integrity: sha512-mf1LEW0tJLKfWyvn5KdDrhpxHyuxpbNwTIwOYLIvsTffeyOf85j5oIzfG0yosxDgx/sswlqBnESYUcQH0vgZ0g==} + engines: {node: '>=18'} + peerDependencies: + postcss-selector-parser: ^7.0.0 + + '@csstools/selector-specificity@5.0.0': + resolution: {integrity: sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==} + engines: {node: '>=18'} + peerDependencies: + postcss-selector-parser: ^7.0.0 + + '@csstools/utilities@2.0.0': + resolution: {integrity: sha512-5VdOr0Z71u+Yp3ozOx8T11N703wIFGVRgOWbOZMKgglPJsWA54MRIoMNVMa7shUToIhx5J8vX4sOZgD2XiihiQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + '@discoveryjs/json-ext@0.5.7': + resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} + engines: {node: '>=10.0.0'} + + '@docsearch/core@4.3.1': + resolution: {integrity: sha512-ktVbkePE+2h9RwqCUMbWXOoebFyDOxHqImAqfs+lC8yOU+XwEW4jgvHGJK079deTeHtdhUNj0PXHSnhJINvHzQ==} + peerDependencies: + '@types/react': '>= 16.8.0 < 20.0.0' + react: '>= 16.8.0 < 20.0.0' + react-dom: '>= 16.8.0 < 20.0.0' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + react-dom: + optional: true + + '@docsearch/css@4.3.2': + resolution: {integrity: sha512-K3Yhay9MgkBjJJ0WEL5MxnACModX9xuNt3UlQQkDEDZJZ0+aeWKtOkxHNndMRkMBnHdYvQjxkm6mdlneOtU1IQ==} + + '@docsearch/react@4.3.2': + resolution: {integrity: sha512-74SFD6WluwvgsOPqifYOviEEVwDxslxfhakTlra+JviaNcs7KK/rjsPj89kVEoQc9FUxRkAofaJnHIR7pb4TSQ==} + peerDependencies: + '@types/react': '>= 16.8.0 < 20.0.0' + react: '>= 16.8.0 < 20.0.0' + react-dom: '>= 16.8.0 < 20.0.0' + search-insights: '>= 1 < 3' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + react-dom: + optional: true + search-insights: + optional: true + + '@docusaurus/babel@3.9.2': + resolution: {integrity: sha512-GEANdi/SgER+L7Japs25YiGil/AUDnFFHaCGPBbundxoWtCkA2lmy7/tFmgED4y1htAy6Oi4wkJEQdGssnw9MA==} + engines: {node: '>=20.0'} + + '@docusaurus/bundler@3.9.2': + resolution: {integrity: sha512-ZOVi6GYgTcsZcUzjblpzk3wH1Fya2VNpd5jtHoCCFcJlMQ1EYXZetfAnRHLcyiFeBABaI1ltTYbOBtH/gahGVA==} + engines: {node: '>=20.0'} + peerDependencies: + '@docusaurus/faster': '*' + peerDependenciesMeta: + '@docusaurus/faster': + optional: true + + '@docusaurus/core@3.9.2': + resolution: {integrity: sha512-HbjwKeC+pHUFBfLMNzuSjqFE/58+rLVKmOU3lxQrpsxLBOGosYco/Q0GduBb0/jEMRiyEqjNT/01rRdOMWq5pw==} + engines: {node: '>=20.0'} + hasBin: true + peerDependencies: + '@mdx-js/react': ^3.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/cssnano-preset@3.9.2': + resolution: {integrity: sha512-8gBKup94aGttRduABsj7bpPFTX7kbwu+xh3K9NMCF5K4bWBqTFYW+REKHF6iBVDHRJ4grZdIPbvkiHd/XNKRMQ==} + engines: {node: '>=20.0'} + + '@docusaurus/logger@3.9.2': + resolution: {integrity: sha512-/SVCc57ByARzGSU60c50rMyQlBuMIJCjcsJlkphxY6B0GV4UH3tcA1994N8fFfbJ9kX3jIBe/xg3XP5qBtGDbA==} + engines: {node: '>=20.0'} + + '@docusaurus/mdx-loader@3.9.2': + resolution: {integrity: sha512-wiYoGwF9gdd6rev62xDU8AAM8JuLI/hlwOtCzMmYcspEkzecKrP8J8X+KpYnTlACBUUtXNJpSoCwFWJhLRevzQ==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/module-type-aliases@3.9.2': + resolution: {integrity: sha512-8qVe2QA9hVLzvnxP46ysuofJUIc/yYQ82tvA/rBTrnpXtCjNSFLxEZfd5U8cYZuJIVlkPxamsIgwd5tGZXfvew==} + peerDependencies: + react: '*' + react-dom: '*' + + '@docusaurus/plugin-client-redirects@3.9.2': + resolution: {integrity: sha512-lUgMArI9vyOYMzLRBUILcg9vcPTCyyI2aiuXq/4npcMVqOr6GfmwtmBYWSbNMlIUM0147smm4WhpXD0KFboffw==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/plugin-content-blog@3.9.2': + resolution: {integrity: sha512-3I2HXy3L1QcjLJLGAoTvoBnpOwa6DPUa3Q0dMK19UTY9mhPkKQg/DYhAGTiBUKcTR0f08iw7kLPqOhIgdV3eVQ==} + engines: {node: '>=20.0'} + peerDependencies: + '@docusaurus/plugin-content-docs': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/plugin-content-docs@3.9.2': + resolution: {integrity: sha512-C5wZsGuKTY8jEYsqdxhhFOe1ZDjH0uIYJ9T/jebHwkyxqnr4wW0jTkB72OMqNjsoQRcb0JN3PcSeTwFlVgzCZg==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/plugin-content-pages@3.9.2': + resolution: {integrity: sha512-s4849w/p4noXUrGpPUF0BPqIAfdAe76BLaRGAGKZ1gTDNiGxGcpsLcwJ9OTi1/V8A+AzvsmI9pkjie2zjIQZKA==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/plugin-css-cascade-layers@3.9.2': + resolution: {integrity: sha512-w1s3+Ss+eOQbscGM4cfIFBlVg/QKxyYgj26k5AnakuHkKxH6004ZtuLe5awMBotIYF2bbGDoDhpgQ4r/kcj4rQ==} + engines: {node: '>=20.0'} + + '@docusaurus/plugin-debug@3.9.2': + resolution: {integrity: sha512-j7a5hWuAFxyQAkilZwhsQ/b3T7FfHZ+0dub6j/GxKNFJp2h9qk/P1Bp7vrGASnvA9KNQBBL1ZXTe7jlh4VdPdA==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/plugin-google-analytics@3.9.2': + resolution: {integrity: sha512-mAwwQJ1Us9jL/lVjXtErXto4p4/iaLlweC54yDUK1a97WfkC6Z2k5/769JsFgwOwOP+n5mUQGACXOEQ0XDuVUw==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/plugin-google-gtag@3.9.2': + resolution: {integrity: sha512-YJ4lDCphabBtw19ooSlc1MnxtYGpjFV9rEdzjLsUnBCeis2djUyCozZaFhCg6NGEwOn7HDDyMh0yzcdRpnuIvA==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/plugin-google-tag-manager@3.9.2': + resolution: {integrity: sha512-LJtIrkZN/tuHD8NqDAW1Tnw0ekOwRTfobWPsdO15YxcicBo2ykKF0/D6n0vVBfd3srwr9Z6rzrIWYrMzBGrvNw==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/plugin-sitemap@3.9.2': + resolution: {integrity: sha512-WLh7ymgDXjG8oPoM/T4/zUP7KcSuFYRZAUTl8vR6VzYkfc18GBM4xLhcT+AKOwun6kBivYKUJf+vlqYJkm+RHw==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/plugin-svgr@3.9.2': + resolution: {integrity: sha512-n+1DE+5b3Lnf27TgVU5jM1d4x5tUh2oW5LTsBxJX4PsAPV0JGcmI6p3yLYtEY0LRVEIJh+8RsdQmRE66wSV8mw==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/preset-classic@3.9.2': + resolution: {integrity: sha512-IgyYO2Gvaigi21LuDIe+nvmN/dfGXAiMcV/murFqcpjnZc7jxFAxW+9LEjdPt61uZLxG4ByW/oUmX/DDK9t/8w==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/react-loadable@6.0.0': + resolution: {integrity: sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==} + peerDependencies: + react: '*' + + '@docusaurus/theme-classic@3.9.2': + resolution: {integrity: sha512-IGUsArG5hhekXd7RDb11v94ycpJpFdJPkLnt10fFQWOVxAtq5/D7hT6lzc2fhyQKaaCE62qVajOMKL7OiAFAIA==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/theme-common@3.9.2': + resolution: {integrity: sha512-6c4DAbR6n6nPbnZhY2V3tzpnKnGL+6aOsLvFL26VRqhlczli9eWG0VDUNoCQEPnGwDMhPS42UhSAnz5pThm5Ag==} + engines: {node: '>=20.0'} + peerDependencies: + '@docusaurus/plugin-content-docs': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/theme-search-algolia@3.9.2': + resolution: {integrity: sha512-GBDSFNwjnh5/LdkxCKQHkgO2pIMX1447BxYUBG2wBiajS21uj64a+gH/qlbQjDLxmGrbrllBrtJkUHxIsiwRnw==} + engines: {node: '>=20.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/theme-translations@3.9.2': + resolution: {integrity: sha512-vIryvpP18ON9T9rjgMRFLr2xJVDpw1rtagEGf8Ccce4CkTrvM/fRB8N2nyWYOW5u3DdjkwKw5fBa+3tbn9P4PA==} + engines: {node: '>=20.0'} + + '@docusaurus/tsconfig@3.9.2': + resolution: {integrity: sha512-j6/Fp4Rlpxsc632cnRnl5HpOWeb6ZKssDj6/XzzAzVGXXfm9Eptx3rxCC+fDzySn9fHTS+CWJjPineCR1bB5WQ==} + + '@docusaurus/types@3.9.2': + resolution: {integrity: sha512-Ux1JUNswg+EfUEmajJjyhIohKceitY/yzjRUpu04WXgvVz+fbhVC0p+R0JhvEu4ytw8zIAys2hrdpQPBHRIa8Q==} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@docusaurus/utils-common@3.9.2': + resolution: {integrity: sha512-I53UC1QctruA6SWLvbjbhCpAw7+X7PePoe5pYcwTOEXD/PxeP8LnECAhTHHwWCblyUX5bMi4QLRkxvyZ+IT8Aw==} + engines: {node: '>=20.0'} + + '@docusaurus/utils-validation@3.9.2': + resolution: {integrity: sha512-l7yk3X5VnNmATbwijJkexdhulNsQaNDwoagiwujXoxFbWLcxHQqNQ+c/IAlzrfMMOfa/8xSBZ7KEKDesE/2J7A==} + engines: {node: '>=20.0'} + + '@docusaurus/utils@3.9.2': + resolution: {integrity: sha512-lBSBiRruFurFKXr5Hbsl2thmGweAPmddhF3jb99U4EMDA5L+e5Y1rAkOS07Nvrup7HUMBDrCV45meaxZnt28nQ==} + engines: {node: '>=20.0'} + + '@hapi/hoek@9.3.0': + resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} + + '@hapi/topo@5.1.0': + resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==} + + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/types@29.6.3': + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/source-map@0.3.11': + resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@jsonjoy.com/base64@1.1.2': + resolution: {integrity: sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/buffers@1.2.1': + resolution: {integrity: sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/codegen@1.0.0': + resolution: {integrity: sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/json-pack@1.21.0': + resolution: {integrity: sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/json-pointer@1.0.2': + resolution: {integrity: sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/util@1.9.0': + resolution: {integrity: sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@leichtgewicht/ip-codec@2.0.5': + resolution: {integrity: sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==} + + '@mdx-js/mdx@3.1.1': + resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==} + + '@mdx-js/react@3.1.1': + resolution: {integrity: sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==} + peerDependencies: + '@types/react': '>=16' + react: '>=16' + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@opentelemetry/api@1.9.0': + resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} + engines: {node: '>=8.0.0'} + + '@pnpm/config.env-replace@1.1.0': + resolution: {integrity: sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==} + engines: {node: '>=12.22.0'} + + '@pnpm/network.ca-file@1.0.2': + resolution: {integrity: sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==} + engines: {node: '>=12.22.0'} + + '@pnpm/npm-conf@2.3.1': + resolution: {integrity: sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==} + engines: {node: '>=12'} + + '@polka/url@1.0.0-next.29': + resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} + + '@scalar/docusaurus@0.7.21': + resolution: {integrity: sha512-Olh6qK05eC1wK2yoNSx8jkWpr7AUzZTwy8B4jsDzuQYTwyjKHnkWKkQ2UfH3yTRlXWtRH4YtI+eqDuc4ZkY9eQ==} + engines: {node: '>=20'} + peerDependencies: + '@docusaurus/utils': ^3.7.0 + react: ^18.0.0 || ^19.0.0 + + '@scalar/openapi-types@0.5.1': + resolution: {integrity: sha512-8g7s9lPolyDFtijyh3Ob459tpezPuZbkXoFgJwBTHjPZ7ap+TvOJTvLk56CFwxVBVz2BxCzWJqxYyy3FUdeLoA==} + engines: {node: '>=20'} + + '@scalar/types@0.4.0': + resolution: {integrity: sha512-vOD1GZez7kPdVA+UQit05QE9dbALfevhK9kqRTsqcPX7FvvZ9eQWSNl1GKmKtmRiAZGThv2agM5AvHRxkH2JSw==} + engines: {node: '>=20'} + + '@sideway/address@4.1.5': + resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==} + + '@sideway/formula@3.0.1': + resolution: {integrity: sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==} + + '@sideway/pinpoint@2.0.0': + resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} + + '@sinclair/typebox@0.27.8': + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + + '@sindresorhus/is@4.6.0': + resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} + engines: {node: '>=10'} + + '@sindresorhus/is@5.6.0': + resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==} + engines: {node: '>=14.16'} + + '@slorber/react-helmet-async@1.3.0': + resolution: {integrity: sha512-e9/OK8VhwUSc67diWI8Rb3I0YgI9/SBQtnhe9aEuK6MhZm7ntZZimXgwXnd8W96YTmSOb9M4d8LwhRZyhWr/1A==} + peerDependencies: + react: ^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@slorber/remark-comment@1.0.0': + resolution: {integrity: sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA==} + + '@standard-schema/spec@1.0.0': + resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} + + '@svgr/babel-plugin-add-jsx-attribute@8.0.0': + resolution: {integrity: sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-remove-jsx-attribute@8.0.0': + resolution: {integrity: sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0': + resolution: {integrity: sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0': + resolution: {integrity: sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-svg-dynamic-title@8.0.0': + resolution: {integrity: sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-svg-em-dimensions@8.0.0': + resolution: {integrity: sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-transform-react-native-svg@8.1.0': + resolution: {integrity: sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-transform-svg-component@8.0.0': + resolution: {integrity: sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==} + engines: {node: '>=12'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-preset@8.1.0': + resolution: {integrity: sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/core@8.1.0': + resolution: {integrity: sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==} + engines: {node: '>=14'} + + '@svgr/hast-util-to-babel-ast@8.0.0': + resolution: {integrity: sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==} + engines: {node: '>=14'} + + '@svgr/plugin-jsx@8.1.0': + resolution: {integrity: sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==} + engines: {node: '>=14'} + peerDependencies: + '@svgr/core': '*' + + '@svgr/plugin-svgo@8.1.0': + resolution: {integrity: sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==} + engines: {node: '>=14'} + peerDependencies: + '@svgr/core': '*' + + '@svgr/webpack@8.1.0': + resolution: {integrity: sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==} + engines: {node: '>=14'} + + '@szmarczak/http-timer@5.0.1': + resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} + engines: {node: '>=14.16'} + + '@trysound/sax@0.2.0': + resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} + engines: {node: '>=10.13.0'} + + '@types/body-parser@1.19.6': + resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} + + '@types/bonjour@3.5.13': + resolution: {integrity: sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==} + + '@types/connect-history-api-fallback@1.5.4': + resolution: {integrity: sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==} + + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + + '@types/debug@4.1.12': + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + + '@types/eslint-scope@3.7.7': + resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} + + '@types/eslint@9.6.1': + resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} + + '@types/estree-jsx@1.0.5': + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/express-serve-static-core@4.19.7': + resolution: {integrity: sha512-FvPtiIf1LfhzsaIXhv/PHan/2FeQBbtBDtfX2QfvPxdUelMDEckK08SM6nqo1MIZY3RUlfA+HV8+hFUSio78qg==} + + '@types/express@4.17.25': + resolution: {integrity: sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==} + + '@types/gtag.js@0.0.12': + resolution: {integrity: sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg==} + + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + + '@types/history@4.7.11': + resolution: {integrity: sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==} + + '@types/html-minifier-terser@6.1.0': + resolution: {integrity: sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==} + + '@types/http-cache-semantics@4.0.4': + resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} + + '@types/http-errors@2.0.5': + resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} + + '@types/http-proxy@1.17.17': + resolution: {integrity: sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw==} + + '@types/istanbul-lib-coverage@2.0.6': + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + + '@types/istanbul-lib-report@3.0.3': + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + + '@types/istanbul-reports@3.0.4': + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/mdx@2.0.13': + resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} + + '@types/mime@1.3.5': + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/node-forge@1.3.14': + resolution: {integrity: sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw==} + + '@types/node@17.0.45': + resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} + + '@types/node@24.10.1': + resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==} + + '@types/prismjs@1.26.5': + resolution: {integrity: sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==} + + '@types/qs@6.14.0': + resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==} + + '@types/range-parser@1.2.7': + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + + '@types/react-router-config@5.0.11': + resolution: {integrity: sha512-WmSAg7WgqW7m4x8Mt4N6ZyKz0BubSj/2tVUMsAHp+Yd2AMwcSbeFq9WympT19p5heCFmF97R9eD5uUR/t4HEqw==} + + '@types/react-router-dom@5.3.3': + resolution: {integrity: sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==} + + '@types/react-router@5.1.20': + resolution: {integrity: sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==} + + '@types/react@19.2.4': + resolution: {integrity: sha512-tBFxBp9Nfyy5rsmefN+WXc1JeW/j2BpBHFdLZbEVfs9wn3E3NRFxwV0pJg8M1qQAexFpvz73hJXFofV0ZAu92A==} + + '@types/retry@0.12.2': + resolution: {integrity: sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==} + + '@types/sax@1.2.7': + resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==} + + '@types/send@0.17.6': + resolution: {integrity: sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==} + + '@types/send@1.2.1': + resolution: {integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==} + + '@types/serve-index@1.9.4': + resolution: {integrity: sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==} + + '@types/serve-static@1.15.10': + resolution: {integrity: sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==} + + '@types/sockjs@0.3.36': + resolution: {integrity: sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==} + + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + + '@types/yargs-parser@21.0.3': + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + + '@types/yargs@17.0.34': + resolution: {integrity: sha512-KExbHVa92aJpw9WDQvzBaGVE2/Pz+pLZQloT2hjL8IqsZnV62rlPOYvNnLmf/L2dyllfVUOVBj64M0z/46eR2A==} + + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + + '@vercel/oidc@3.0.3': + resolution: {integrity: sha512-yNEQvPcVrK9sIe637+I0jD6leluPxzwJKx/Haw6F4H77CdDsszUn5V3o96LPziXkSNE2B83+Z3mjqGKBK/R6Gg==} + engines: {node: '>= 20'} + + '@webassemblyjs/ast@1.14.1': + resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} + + '@webassemblyjs/floating-point-hex-parser@1.13.2': + resolution: {integrity: sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==} + + '@webassemblyjs/helper-api-error@1.13.2': + resolution: {integrity: sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==} + + '@webassemblyjs/helper-buffer@1.14.1': + resolution: {integrity: sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==} + + '@webassemblyjs/helper-numbers@1.13.2': + resolution: {integrity: sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==} + + '@webassemblyjs/helper-wasm-bytecode@1.13.2': + resolution: {integrity: sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==} + + '@webassemblyjs/helper-wasm-section@1.14.1': + resolution: {integrity: sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==} + + '@webassemblyjs/ieee754@1.13.2': + resolution: {integrity: sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==} + + '@webassemblyjs/leb128@1.13.2': + resolution: {integrity: sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==} + + '@webassemblyjs/utf8@1.13.2': + resolution: {integrity: sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==} + + '@webassemblyjs/wasm-edit@1.14.1': + resolution: {integrity: sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==} + + '@webassemblyjs/wasm-gen@1.14.1': + resolution: {integrity: sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==} + + '@webassemblyjs/wasm-opt@1.14.1': + resolution: {integrity: sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==} + + '@webassemblyjs/wasm-parser@1.14.1': + resolution: {integrity: sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==} + + '@webassemblyjs/wast-printer@1.14.1': + resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} + + '@xtuc/ieee754@1.2.0': + resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} + + '@xtuc/long@4.2.2': + resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + + accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + + acorn-import-phases@1.0.4: + resolution: {integrity: sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==} + engines: {node: '>=10.13.0'} + peerDependencies: + acorn: ^8.14.0 + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn-walk@8.3.4: + resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + engines: {node: '>=0.4.0'} + + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + + address@1.2.2: + resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==} + engines: {node: '>= 10.0.0'} + + aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + + ai@5.0.93: + resolution: {integrity: sha512-9eGcu+1PJgPg4pRNV4L7tLjRR3wdJC9CXQoNMvtqvYNOLZHFCzjHtVIOr2SIkoJJeu2+sOy3hyiSuTmy2MA40g==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + ajv-formats@2.1.1: + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv-keywords@3.5.2: + resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} + peerDependencies: + ajv: ^6.9.1 + + ajv-keywords@5.1.0: + resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} + peerDependencies: + ajv: ^8.8.2 + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + + algoliasearch-helper@3.26.1: + resolution: {integrity: sha512-CAlCxm4fYBXtvc5MamDzP6Svu8rW4z9me4DCBY1rQ2UDJ0u0flWmusQ8M3nOExZsLLRcUwUPoRAPMrhzOG3erw==} + peerDependencies: + algoliasearch: '>= 3.1 < 6' + + algoliasearch@5.43.0: + resolution: {integrity: sha512-hbkK41JsuGYhk+atBDxlcKxskjDCh3OOEDpdKZPtw+3zucBqhlojRG5e5KtCmByGyYvwZswVeaSWglgLn2fibg==} + engines: {node: '>= 14.0.0'} + + ansi-align@3.0.1: + resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} + + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + + ansi-html-community@0.0.8: + resolution: {integrity: sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==} + engines: {'0': node >= 0.8.0} + hasBin: true + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + astring@1.9.0: + resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} + hasBin: true + + autoprefixer@10.4.22: + resolution: {integrity: sha512-ARe0v/t9gO28Bznv6GgqARmVqcWOV3mfgUPn9becPHMiD3o9BwlRgaeccZnwTpZ7Zwqrm+c1sUSsMxIzQzc8Xg==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + + babel-loader@9.2.1: + resolution: {integrity: sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==} + engines: {node: '>= 14.15.0'} + peerDependencies: + '@babel/core': ^7.12.0 + webpack: '>=5' + + babel-plugin-dynamic-import-node@2.3.3: + resolution: {integrity: sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==} + + babel-plugin-polyfill-corejs2@0.4.14: + resolution: {integrity: sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-corejs3@0.13.0: + resolution: {integrity: sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-regenerator@0.6.5: + resolution: {integrity: sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + baseline-browser-mapping@2.8.28: + resolution: {integrity: sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ==} + hasBin: true + + batch@0.6.1: + resolution: {integrity: sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==} + + big.js@5.2.2: + resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + body-parser@1.20.3: + resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + bonjour-service@1.3.0: + resolution: {integrity: sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + boxen@6.2.1: + resolution: {integrity: sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + boxen@7.1.1: + resolution: {integrity: sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==} + engines: {node: '>=14.16'} + + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.28.0: + resolution: {integrity: sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} + + bytes@3.0.0: + resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} + engines: {node: '>= 0.8'} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + cacheable-lookup@7.0.0: + resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==} + engines: {node: '>=14.16'} + + cacheable-request@10.2.14: + resolution: {integrity: sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==} + engines: {node: '>=14.16'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camel-case@4.1.2: + resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + camelcase@7.0.1: + resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==} + engines: {node: '>=14.16'} + + caniuse-api@3.0.0: + resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} + + caniuse-lite@1.0.30001754: + resolution: {integrity: sha512-x6OeBXueoAceOmotzx3PO4Zpt4rzpeIFsSr6AAePTZxSkXiYDUmpypEl7e2+8NCd9bD7bXjqyef8CJYPC1jfxg==} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + + cheerio-select@2.1.0: + resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} + + cheerio@1.0.0-rc.12: + resolution: {integrity: sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==} + engines: {node: '>= 6'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chrome-trace-event@1.0.4: + resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} + engines: {node: '>=6.0'} + + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + + clean-css@5.3.3: + resolution: {integrity: sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==} + engines: {node: '>= 10.0'} + + clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + + cli-boxes@3.0.0: + resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} + engines: {node: '>=10'} + + cli-table3@0.6.5: + resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} + engines: {node: 10.* || >= 12.*} + + clone-deep@4.0.1: + resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} + engines: {node: '>=6'} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + collapse-white-space@2.1.0: + resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + colord@2.9.3: + resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} + + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + + combine-promises@1.2.0: + resolution: {integrity: sha512-VcQB1ziGD0NXrhKxiwyNbCDmRzs/OShMs2GqW2DlU2A/Sd0nQxE1oWDAE5O0ygSx5mgQOn9eIFh7yKPgFRVkPQ==} + engines: {node: '>=10'} + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + commander@10.0.1: + resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} + engines: {node: '>=14'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + commander@5.1.0: + resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==} + engines: {node: '>= 6'} + + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + + common-path-prefix@3.0.0: + resolution: {integrity: sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==} + + compressible@2.0.18: + resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} + engines: {node: '>= 0.6'} + + compression@1.8.1: + resolution: {integrity: sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==} + engines: {node: '>= 0.8.0'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + config-chain@1.1.13: + resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} + + configstore@6.0.0: + resolution: {integrity: sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==} + engines: {node: '>=12'} + + connect-history-api-fallback@2.0.0: + resolution: {integrity: sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==} + engines: {node: '>=0.8'} + + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + + content-disposition@0.5.2: + resolution: {integrity: sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==} + engines: {node: '>= 0.6'} + + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-signature@1.0.6: + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + + cookie@0.7.1: + resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} + engines: {node: '>= 0.6'} + + copy-webpack-plugin@11.0.0: + resolution: {integrity: sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==} + engines: {node: '>= 14.15.0'} + peerDependencies: + webpack: ^5.1.0 + + core-js-compat@3.46.0: + resolution: {integrity: sha512-p9hObIIEENxSV8xIu+V68JjSeARg6UVMG5mR+JEUguG3sI6MsiS1njz2jHmyJDvA+8jX/sytkBHup6kxhM9law==} + + core-js-pure@3.46.0: + resolution: {integrity: sha512-NMCW30bHNofuhwLhYPt66OLOKTMbOhgTTatKVbaQC3KRHpTCiRIBYvtshr+NBYSnBxwAFhjW/RfJ0XbIjS16rw==} + + core-js@3.46.0: + resolution: {integrity: sha512-vDMm9B0xnqqZ8uSBpZ8sNtRtOdmfShrvT6h2TuQGLs0Is+cR0DYbj/KWP6ALVNbWPpqA/qPLoOuppJN07humpA==} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + cosmiconfig@8.3.6: + resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + crypto-random-string@4.0.0: + resolution: {integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==} + engines: {node: '>=12'} + + css-blank-pseudo@7.0.1: + resolution: {integrity: sha512-jf+twWGDf6LDoXDUode+nc7ZlrqfaNphrBIBrcmeP3D8yw1uPaix1gCC8LUQUGQ6CycuK2opkbFFWFuq/a94ag==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + css-declaration-sorter@7.3.0: + resolution: {integrity: sha512-LQF6N/3vkAMYF4xoHLJfG718HRJh34Z8BnNhd6bosOMIVjMlhuZK5++oZa3uYAgrI5+7x2o27gUqTR2U/KjUOQ==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.0.9 + + css-has-pseudo@7.0.3: + resolution: {integrity: sha512-oG+vKuGyqe/xvEMoxAQrhi7uY16deJR3i7wwhBerVrGQKSqUC5GiOVxTpM9F9B9hw0J+eKeOWLH7E9gZ1Dr5rA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + css-loader@6.11.0: + resolution: {integrity: sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==} + engines: {node: '>= 12.13.0'} + peerDependencies: + '@rspack/core': 0.x || 1.x + webpack: ^5.0.0 + peerDependenciesMeta: + '@rspack/core': + optional: true + webpack: + optional: true + + css-minimizer-webpack-plugin@5.0.1: + resolution: {integrity: sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==} + engines: {node: '>= 14.15.0'} + peerDependencies: + '@parcel/css': '*' + '@swc/css': '*' + clean-css: '*' + csso: '*' + esbuild: '*' + lightningcss: '*' + webpack: ^5.0.0 + peerDependenciesMeta: + '@parcel/css': + optional: true + '@swc/css': + optional: true + clean-css: + optional: true + csso: + optional: true + esbuild: + optional: true + lightningcss: + optional: true + + css-prefers-color-scheme@10.0.0: + resolution: {integrity: sha512-VCtXZAWivRglTZditUfB4StnsWr6YVZ2PRtuxQLKTNRdtAf8tpzaVPE9zXIF3VaSc7O70iK/j1+NXxyQCqdPjQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + css-select@4.3.0: + resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} + + css-select@5.2.2: + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} + + css-tree@2.2.1: + resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + css-tree@2.3.1: + resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + engines: {node: '>= 6'} + + cssdb@8.4.2: + resolution: {integrity: sha512-PzjkRkRUS+IHDJohtxkIczlxPPZqRo0nXplsYXOMBRPjcVRjj1W4DfvRgshUYTVuUigU7ptVYkFJQ7abUB0nyg==} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + cssnano-preset-advanced@6.1.2: + resolution: {integrity: sha512-Nhao7eD8ph2DoHolEzQs5CfRpiEP0xa1HBdnFZ82kvqdmbwVBUr2r1QuQ4t1pi+D1ZpqpcO4T+wy/7RxzJ/WPQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + cssnano-preset-default@6.1.2: + resolution: {integrity: sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + cssnano-utils@4.0.2: + resolution: {integrity: sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + cssnano@6.1.2: + resolution: {integrity: sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + csso@5.0.5: + resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + debounce@1.2.1: + resolution: {integrity: sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decode-named-character-reference@1.2.0: + resolution: {integrity: sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==} + + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + default-browser-id@5.0.0: + resolution: {integrity: sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==} + engines: {node: '>=18'} + + default-browser@5.3.0: + resolution: {integrity: sha512-Qq68+VkJlc8tjnPV1i7HtbIn7ohmjZa88qUvHMIK0ZKUXMCuV45cT7cEXALPUmeXCe0q1DWQkQTemHVaLIFSrg==} + engines: {node: '>=18'} + + defer-to-connect@2.0.1: + resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} + engines: {node: '>=10'} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + depd@1.1.2: + resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} + engines: {node: '>= 0.6'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + detect-node@2.1.0: + resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} + + detect-port@1.6.1: + resolution: {integrity: sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==} + engines: {node: '>= 4.0.0'} + hasBin: true + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + dns-packet@5.6.1: + resolution: {integrity: sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==} + engines: {node: '>=6'} + + dom-converter@0.2.0: + resolution: {integrity: sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==} + + dom-serializer@1.4.1: + resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@4.3.1: + resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} + engines: {node: '>= 4'} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@2.8.0: + resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + + dot-case@3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + + dot-prop@6.0.1: + resolution: {integrity: sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==} + engines: {node: '>=10'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + duplexer@0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + electron-to-chromium@1.5.250: + resolution: {integrity: sha512-/5UMj9IiGDMOFBnN4i7/Ry5onJrAGSbOGo3s9FEKmwobGq6xw832ccET0CE3CkkMBZ8GJSlUIesZofpyurqDXw==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + emojilib@2.4.0: + resolution: {integrity: sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==} + + emojis-list@3.0.0: + resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} + engines: {node: '>= 4'} + + emoticon@4.1.0: + resolution: {integrity: sha512-VWZfnxqwNcc51hIy/sbOdEem6D+cVtpPzEEtVAFdaas30+1dgkyaOQ4sQ6Bp0tOMqWO1v+HQfYaoodOkdhK6SQ==} + + encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + enhanced-resolve@5.18.3: + resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==} + engines: {node: '>=10.13.0'} + + entities@2.2.0: + resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + esast-util-from-estree@2.0.0: + resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} + + esast-util-from-js@2.0.1: + resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-goat@4.0.0: + resolution: {integrity: sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==} + engines: {node: '>=12'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-util-attach-comments@3.0.0: + resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} + + estree-util-build-jsx@3.0.1: + resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==} + + estree-util-is-identifier-name@3.0.0: + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + + estree-util-scope@1.0.0: + resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==} + + estree-util-to-js@2.0.0: + resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} + + estree-util-value-to-estree@3.5.0: + resolution: {integrity: sha512-aMV56R27Gv3QmfmF1MY12GWkGzzeAezAX+UplqHVASfjc9wNzI/X6hC0S9oxq61WT4aQesLGslWP9tKk6ghRZQ==} + + estree-util-visit@2.0.0: + resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + eta@2.2.0: + resolution: {integrity: sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g==} + engines: {node: '>=6.0.0'} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + eval@0.1.8: + resolution: {integrity: sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==} + engines: {node: '>= 0.8'} + + eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + eventsource-parser@3.0.6: + resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} + engines: {node: '>=18.0.0'} + + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + + express@4.21.2: + resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==} + engines: {node: '>= 0.10.0'} + + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-uri@3.1.0: + resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + + fault@2.0.1: + resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==} + + faye-websocket@0.11.4: + resolution: {integrity: sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==} + engines: {node: '>=0.8.0'} + + feed@4.2.2: + resolution: {integrity: sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==} + engines: {node: '>=0.4.0'} + + figures@3.2.0: + resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} + engines: {node: '>=8'} + + file-loader@6.2.0: + resolution: {integrity: sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==} + engines: {node: '>= 10.13.0'} + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + finalhandler@1.3.1: + resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} + engines: {node: '>= 0.8'} + + find-cache-dir@4.0.0: + resolution: {integrity: sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==} + engines: {node: '>=14.16'} + + find-up@6.3.0: + resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data-encoder@2.1.4: + resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} + engines: {node: '>= 14.17'} + + format@0.2.2: + resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} + engines: {node: '>=0.4.x'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fraction.js@5.3.4: + resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} + + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + + fs-extra@11.3.2: + resolution: {integrity: sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==} + engines: {node: '>=14.14'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-own-enumerable-property-symbols@3.0.2: + resolution: {integrity: sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + + github-slugger@1.5.0: + resolution: {integrity: sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob-to-regex.js@1.2.0: + resolution: {integrity: sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + + global-dirs@3.0.1: + resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==} + engines: {node: '>=10'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + globby@13.2.2: + resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + got@12.6.1: + resolution: {integrity: sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==} + engines: {node: '>=14.16'} + + graceful-fs@4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + gray-matter@4.0.3: + resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} + engines: {node: '>=6.0'} + + gzip-size@6.0.0: + resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==} + engines: {node: '>=10'} + + handle-thing@2.0.1: + resolution: {integrity: sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-yarn@3.0.0: + resolution: {integrity: sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + hast-util-from-parse5@8.0.3: + resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==} + + hast-util-parse-selector@4.0.0: + resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} + + hast-util-raw@9.1.0: + resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==} + + hast-util-to-estree@3.1.3: + resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==} + + hast-util-to-jsx-runtime@2.3.6: + resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} + + hast-util-to-parse5@8.0.0: + resolution: {integrity: sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + hastscript@9.0.1: + resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} + + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + + history@4.10.1: + resolution: {integrity: sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==} + + hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + + hpack.js@2.1.6: + resolution: {integrity: sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + + html-minifier-terser@6.1.0: + resolution: {integrity: sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==} + engines: {node: '>=12'} + hasBin: true + + html-minifier-terser@7.2.0: + resolution: {integrity: sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==} + engines: {node: ^14.13.1 || >=16.0.0} + hasBin: true + + html-tags@3.3.1: + resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} + engines: {node: '>=8'} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + + html-webpack-plugin@5.6.4: + resolution: {integrity: sha512-V/PZeWsqhfpE27nKeX9EO2sbR+D17A+tLf6qU+ht66jdUsN0QLKJN27Z+1+gHrVMKgndBahes0PU6rRihDgHTw==} + engines: {node: '>=10.13.0'} + peerDependencies: + '@rspack/core': 0.x || 1.x + webpack: ^5.20.0 + peerDependenciesMeta: + '@rspack/core': + optional: true + webpack: + optional: true + + htmlparser2@6.1.0: + resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==} + + htmlparser2@8.0.2: + resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} + + http-cache-semantics@4.2.0: + resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} + + http-deceiver@1.2.7: + resolution: {integrity: sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==} + + http-errors@1.6.3: + resolution: {integrity: sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==} + engines: {node: '>= 0.6'} + + http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + + http-parser-js@0.5.10: + resolution: {integrity: sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==} + + http-proxy-middleware@2.0.9: + resolution: {integrity: sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@types/express': ^4.17.13 + peerDependenciesMeta: + '@types/express': + optional: true + + http-proxy@1.18.1: + resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} + engines: {node: '>=8.0.0'} + + http2-wrapper@2.2.1: + resolution: {integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==} + engines: {node: '>=10.19.0'} + + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + + hyperdyperid@1.2.0: + resolution: {integrity: sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==} + engines: {node: '>=10.18'} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + icss-utils@5.1.0: + resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + image-size@2.0.2: + resolution: {integrity: sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w==} + engines: {node: '>=16.x'} + hasBin: true + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + import-lazy@4.0.0: + resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} + engines: {node: '>=8'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + infima@0.2.0-alpha.45: + resolution: {integrity: sha512-uyH0zfr1erU1OohLk0fT4Rrb94AOhguWNOcD9uGrSpRvNB+6gZXUoJX5J0NtvzBO10YZ9PgvA4NFgt+fYg8ojw==} + engines: {node: '>=12'} + + inherits@2.0.3: + resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + ini@2.0.0: + resolution: {integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==} + engines: {node: '>=10'} + + inline-style-parser@0.2.6: + resolution: {integrity: sha512-gtGXVaBdl5mAes3rPcMedEBm12ibjt1kDMFfheul1wUAOVEJW60voNdMVzVkfLN06O7ZaD/rxhfKgtlgtTbMjg==} + + invariant@2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + ipaddr.js@2.2.0: + resolution: {integrity: sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==} + engines: {node: '>= 10'} + + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-ci@3.0.1: + resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} + hasBin: true + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + + is-installed-globally@0.4.0: + resolution: {integrity: sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==} + engines: {node: '>=10'} + + is-network-error@1.3.0: + resolution: {integrity: sha512-6oIwpsgRfnDiyEDLMay/GqCl3HoAtH5+RUKW29gYkL0QA+ipzpDLA16yQs7/RHCSu+BwgbJaOUqa4A99qNVQVw==} + engines: {node: '>=16'} + + is-npm@6.1.0: + resolution: {integrity: sha512-O2z4/kNgyjhQwVR1Wpkbfc19JIhggF97NZNCpWTnjH7kVcZMUrnut9XSN7txI7VdyIYk5ZatOq3zvSuWpU8hoA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-obj@1.0.1: + resolution: {integrity: sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==} + engines: {node: '>=0.10.0'} + + is-obj@2.0.0: + resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} + engines: {node: '>=8'} + + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + + is-plain-obj@3.0.0: + resolution: {integrity: sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==} + engines: {node: '>=10'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-plain-object@2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} + + is-regexp@1.0.0: + resolution: {integrity: sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==} + engines: {node: '>=0.10.0'} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-typedarray@1.0.0: + resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} + + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + + is-wsl@3.1.0: + resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} + engines: {node: '>=16'} + + is-yarn-global@0.4.1: + resolution: {integrity: sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==} + engines: {node: '>=12'} + + isarray@0.0.1: + resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isobject@3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} + + jest-util@29.7.0: + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-worker@27.5.1: + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} + engines: {node: '>= 10.13.0'} + + jest-worker@29.7.0: + resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jiti@1.21.7: + resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} + hasBin: true + + joi@17.13.3: + resolution: {integrity: sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonfile@6.2.0: + resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + latest-version@7.0.0: + resolution: {integrity: sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==} + engines: {node: '>=14.16'} + + launch-editor@2.12.0: + resolution: {integrity: sha512-giOHXoOtifjdHqUamwKq6c49GzBdLjvxrd2D+Q4V6uOHopJv7p9VJxikDsQ/CBXZbEITgUqSVHXLTG3VhPP1Dg==} + + leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + loader-runner@4.3.1: + resolution: {integrity: sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==} + engines: {node: '>=6.11.5'} + + loader-utils@2.0.4: + resolution: {integrity: sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==} + engines: {node: '>=8.9.0'} + + locate-path@7.2.0: + resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + + lodash.memoize@4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + + lodash.uniq@4.5.0: + resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + + lowercase-keys@3.0.0: + resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + markdown-extensions@2.0.0: + resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} + engines: {node: '>=16'} + + markdown-table@2.0.0: + resolution: {integrity: sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==} + + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + + marked@16.4.2: + resolution: {integrity: sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==} + engines: {node: '>= 20'} + hasBin: true + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mdast-util-directive@3.1.0: + resolution: {integrity: sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==} + + mdast-util-find-and-replace@3.0.2: + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} + + mdast-util-from-markdown@2.0.2: + resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} + + mdast-util-frontmatter@2.0.1: + resolution: {integrity: sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==} + + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + + mdast-util-gfm-footnote@2.1.0: + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.1.0: + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + + mdast-util-mdx-expression@2.0.1: + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} + + mdast-util-mdx-jsx@3.2.0: + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} + + mdast-util-mdx@3.0.0: + resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} + + mdast-util-mdxjs-esm@2.0.1: + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-hast@13.2.0: + resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} + + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + + mdn-data@2.0.28: + resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} + + mdn-data@2.0.30: + resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + + media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + memfs@4.51.0: + resolution: {integrity: sha512-4zngfkVM/GpIhC8YazOsM6E8hoB33NP0BCESPOA6z7qaL6umPJNqkO8CNYaLV2FB2MV6H1O3x2luHHOSqppv+A==} + + merge-descriptors@1.0.3: + resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-directive@3.0.2: + resolution: {integrity: sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==} + + micromark-extension-frontmatter@2.0.0: + resolution: {integrity: sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + + micromark-extension-mdx-expression@3.0.1: + resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==} + + micromark-extension-mdx-jsx@3.0.2: + resolution: {integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==} + + micromark-extension-mdx-md@2.0.0: + resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} + + micromark-extension-mdxjs-esm@3.0.0: + resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} + + micromark-extension-mdxjs@3.0.0: + resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-mdx-expression@2.0.3: + resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==} + + micromark-factory-space@1.1.0: + resolution: {integrity: sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@1.2.0: + resolution: {integrity: sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-events-to-acorn@2.0.3: + resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@1.1.0: + resolution: {integrity: sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@1.1.0: + resolution: {integrity: sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.33.0: + resolution: {integrity: sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==} + engines: {node: '>= 0.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@2.1.18: + resolution: {integrity: sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime-types@3.0.1: + resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==} + engines: {node: '>= 0.6'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + + mimic-response@4.0.0: + resolution: {integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + mini-css-extract-plugin@2.9.4: + resolution: {integrity: sha512-ZWYT7ln73Hptxqxk2DxPU9MmapXRhxkJD6tkSR04dnQxm8BGu2hzgKLugK5yySD97u/8yy7Ma7E76k9ZdvtjkQ==} + engines: {node: '>= 12.13.0'} + peerDependencies: + webpack: ^5.0.0 + + minimalistic-assert@1.0.1: + resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} + engines: {node: '>=10'} + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + multicast-dns@7.2.5: + resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==} + hasBin: true + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanoid@5.1.5: + resolution: {integrity: sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==} + engines: {node: ^18 || >=20} + hasBin: true + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + negotiator@0.6.4: + resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==} + engines: {node: '>= 0.6'} + + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + + node-emoji@2.2.0: + resolution: {integrity: sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==} + engines: {node: '>=18'} + + node-forge@1.3.1: + resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} + engines: {node: '>= 6.13.0'} + + node-releases@2.0.27: + resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-range@0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + + normalize-url@8.1.0: + resolution: {integrity: sha512-X06Mfd/5aKsRHc0O0J5CUedwnPmnDtLF2+nq+KN9KSDlJHkPuh0JUviWjEWMe0SW/9TDdSLVPuk7L5gGTIA1/w==} + engines: {node: '>=14.16'} + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + nprogress@0.2.0: + resolution: {integrity: sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + null-loader@4.0.1: + resolution: {integrity: sha512-pxqVbi4U6N26lq+LmgIbB5XATP0VdZKOG25DhHi8btMmJJefGArFyDg1yc4U3hWCJbMqSrw0qyrz1UQX+qYXqg==} + engines: {node: '>= 10.13.0'} + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + + obuf@1.1.2: + resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + on-headers@1.1.0: + resolution: {integrity: sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==} + engines: {node: '>= 0.8'} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + open@10.2.0: + resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==} + engines: {node: '>=18'} + + open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} + + opener@1.5.2: + resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==} + hasBin: true + + p-cancelable@3.0.0: + resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} + engines: {node: '>=12.20'} + + p-finally@1.0.0: + resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} + engines: {node: '>=4'} + + p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + p-locate@6.0.0: + resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + + p-queue@6.6.2: + resolution: {integrity: sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==} + engines: {node: '>=8'} + + p-retry@6.2.1: + resolution: {integrity: sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==} + engines: {node: '>=16.17'} + + p-timeout@3.2.0: + resolution: {integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==} + engines: {node: '>=8'} + + package-json@8.1.1: + resolution: {integrity: sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==} + engines: {node: '>=14.16'} + + param-case@3.0.4: + resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + parse-numeric-range@1.3.0: + resolution: {integrity: sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==} + + parse5-htmlparser2-tree-adapter@7.1.0: + resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==} + + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + pascal-case@3.1.2: + resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} + + path-exists@5.0.0: + resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + path-is-inside@1.0.2: + resolution: {integrity: sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-to-regexp@0.1.12: + resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} + + path-to-regexp@1.9.0: + resolution: {integrity: sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==} + + path-to-regexp@3.3.0: + resolution: {integrity: sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + pkg-dir@7.0.0: + resolution: {integrity: sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==} + engines: {node: '>=14.16'} + + postcss-attribute-case-insensitive@7.0.1: + resolution: {integrity: sha512-Uai+SupNSqzlschRyNx3kbCTWgY/2hcwtHEI/ej2LJWc9JJ77qKgGptd8DHwY1mXtZ7Aoh4z4yxfwMBue9eNgw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-calc@9.0.1: + resolution: {integrity: sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.2.2 + + postcss-clamp@4.1.0: + resolution: {integrity: sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==} + engines: {node: '>=7.6.0'} + peerDependencies: + postcss: ^8.4.6 + + postcss-color-functional-notation@7.0.12: + resolution: {integrity: sha512-TLCW9fN5kvO/u38/uesdpbx3e8AkTYhMvDZYa9JpmImWuTE99bDQ7GU7hdOADIZsiI9/zuxfAJxny/khknp1Zw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-color-hex-alpha@10.0.0: + resolution: {integrity: sha512-1kervM2cnlgPs2a8Vt/Qbe5cQ++N7rkYo/2rz2BkqJZIHQwaVuJgQH38REHrAi4uM0b1fqxMkWYmese94iMp3w==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-color-rebeccapurple@10.0.0: + resolution: {integrity: sha512-JFta737jSP+hdAIEhk1Vs0q0YF5P8fFcj+09pweS8ktuGuZ8pPlykHsk6mPxZ8awDl4TrcxUqJo9l1IhVr/OjQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-colormin@6.1.0: + resolution: {integrity: sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-convert-values@6.1.0: + resolution: {integrity: sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-custom-media@11.0.6: + resolution: {integrity: sha512-C4lD4b7mUIw+RZhtY7qUbf4eADmb7Ey8BFA2px9jUbwg7pjTZDl4KY4bvlUV+/vXQvzQRfiGEVJyAbtOsCMInw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-custom-properties@14.0.6: + resolution: {integrity: sha512-fTYSp3xuk4BUeVhxCSJdIPhDLpJfNakZKoiTDx7yRGCdlZrSJR7mWKVOBS4sBF+5poPQFMj2YdXx1VHItBGihQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-custom-selectors@8.0.5: + resolution: {integrity: sha512-9PGmckHQswiB2usSO6XMSswO2yFWVoCAuih1yl9FVcwkscLjRKjwsjM3t+NIWpSU2Jx3eOiK2+t4vVTQaoCHHg==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-dir-pseudo-class@9.0.1: + resolution: {integrity: sha512-tRBEK0MHYvcMUrAuYMEOa0zg9APqirBcgzi6P21OhxtJyJADo/SWBwY1CAwEohQ/6HDaa9jCjLRG7K3PVQYHEA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-discard-comments@6.0.2: + resolution: {integrity: sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-duplicates@6.0.3: + resolution: {integrity: sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-empty@6.0.3: + resolution: {integrity: sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-overridden@6.0.2: + resolution: {integrity: sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-unused@6.0.5: + resolution: {integrity: sha512-wHalBlRHkaNnNwfC8z+ppX57VhvS+HWgjW508esjdaEYr3Mx7Gnn2xA4R/CKf5+Z9S5qsqC+Uzh4ueENWwCVUA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-double-position-gradients@6.0.4: + resolution: {integrity: sha512-m6IKmxo7FxSP5nF2l63QbCC3r+bWpFUWmZXZf096WxG0m7Vl1Q1+ruFOhpdDRmKrRS+S3Jtk+TVk/7z0+BVK6g==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-focus-visible@10.0.1: + resolution: {integrity: sha512-U58wyjS/I1GZgjRok33aE8juW9qQgQUNwTSdxQGuShHzwuYdcklnvK/+qOWX1Q9kr7ysbraQ6ht6r+udansalA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-focus-within@9.0.1: + resolution: {integrity: sha512-fzNUyS1yOYa7mOjpci/bR+u+ESvdar6hk8XNK/TRR0fiGTp2QT5N+ducP0n3rfH/m9I7H/EQU6lsa2BrgxkEjw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-font-variant@5.0.0: + resolution: {integrity: sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==} + peerDependencies: + postcss: ^8.1.0 + + postcss-gap-properties@6.0.0: + resolution: {integrity: sha512-Om0WPjEwiM9Ru+VhfEDPZJAKWUd0mV1HmNXqp2C29z80aQ2uP9UVhLc7e3aYMIor/S5cVhoPgYQ7RtfeZpYTRw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-image-set-function@7.0.0: + resolution: {integrity: sha512-QL7W7QNlZuzOwBTeXEmbVckNt1FSmhQtbMRvGGqqU4Nf4xk6KUEQhAoWuMzwbSv5jxiRiSZ5Tv7eiDB9U87znA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-lab-function@7.0.12: + resolution: {integrity: sha512-tUcyRk1ZTPec3OuKFsqtRzW2Go5lehW29XA21lZ65XmzQkz43VY2tyWEC202F7W3mILOjw0voOiuxRGTsN+J9w==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-loader@7.3.4: + resolution: {integrity: sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A==} + engines: {node: '>= 14.15.0'} + peerDependencies: + postcss: ^7.0.0 || ^8.0.1 + webpack: ^5.0.0 + + postcss-logical@8.1.0: + resolution: {integrity: sha512-pL1hXFQ2fEXNKiNiAgtfA005T9FBxky5zkX6s4GZM2D8RkVgRqz3f4g1JUoq925zXv495qk8UNldDwh8uGEDoA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-merge-idents@6.0.3: + resolution: {integrity: sha512-1oIoAsODUs6IHQZkLQGO15uGEbK3EAl5wi9SS8hs45VgsxQfMnxvt+L+zIr7ifZFIH14cfAeVe2uCTa+SPRa3g==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-merge-longhand@6.0.5: + resolution: {integrity: sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-merge-rules@6.1.1: + resolution: {integrity: sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-font-values@6.1.0: + resolution: {integrity: sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-gradients@6.0.3: + resolution: {integrity: sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-params@6.1.0: + resolution: {integrity: sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-selectors@6.0.4: + resolution: {integrity: sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-modules-extract-imports@3.1.0: + resolution: {integrity: sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-local-by-default@4.2.0: + resolution: {integrity: sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-scope@3.2.1: + resolution: {integrity: sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-values@4.0.0: + resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-nesting@13.0.2: + resolution: {integrity: sha512-1YCI290TX+VP0U/K/aFxzHzQWHWURL+CtHMSbex1lCdpXD1SoR2sYuxDu5aNI9lPoXpKTCggFZiDJbwylU0LEQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-normalize-charset@6.0.2: + resolution: {integrity: sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-display-values@6.0.2: + resolution: {integrity: sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-positions@6.0.2: + resolution: {integrity: sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-repeat-style@6.0.2: + resolution: {integrity: sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-string@6.0.2: + resolution: {integrity: sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-timing-functions@6.0.2: + resolution: {integrity: sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-unicode@6.1.0: + resolution: {integrity: sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-url@6.0.2: + resolution: {integrity: sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-whitespace@6.0.2: + resolution: {integrity: sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-opacity-percentage@3.0.0: + resolution: {integrity: sha512-K6HGVzyxUxd/VgZdX04DCtdwWJ4NGLG212US4/LA1TLAbHgmAsTWVR86o+gGIbFtnTkfOpb9sCRBx8K7HO66qQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-ordered-values@6.0.2: + resolution: {integrity: sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-overflow-shorthand@6.0.0: + resolution: {integrity: sha512-BdDl/AbVkDjoTofzDQnwDdm/Ym6oS9KgmO7Gr+LHYjNWJ6ExORe4+3pcLQsLA9gIROMkiGVjjwZNoL/mpXHd5Q==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-page-break@3.0.4: + resolution: {integrity: sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==} + peerDependencies: + postcss: ^8 + + postcss-place@10.0.0: + resolution: {integrity: sha512-5EBrMzat2pPAxQNWYavwAfoKfYcTADJ8AXGVPcUZ2UkNloUTWzJQExgrzrDkh3EKzmAx1evfTAzF9I8NGcc+qw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-preset-env@10.4.0: + resolution: {integrity: sha512-2kqpOthQ6JhxqQq1FSAAZGe9COQv75Aw8WbsOvQVNJ2nSevc9Yx/IKZGuZ7XJ+iOTtVon7LfO7ELRzg8AZ+sdw==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-pseudo-class-any-link@10.0.1: + resolution: {integrity: sha512-3el9rXlBOqTFaMFkWDOkHUTQekFIYnaQY55Rsp8As8QQkpiSgIYEcF/6Ond93oHiDsGb4kad8zjt+NPlOC1H0Q==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-reduce-idents@6.0.3: + resolution: {integrity: sha512-G3yCqZDpsNPoQgbDUy3T0E6hqOQ5xigUtBQyrmq3tn2GxlyiL0yyl7H+T8ulQR6kOcHJ9t7/9H4/R2tv8tJbMA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-reduce-initial@6.1.0: + resolution: {integrity: sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-reduce-transforms@6.0.2: + resolution: {integrity: sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-replace-overflow-wrap@4.0.0: + resolution: {integrity: sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==} + peerDependencies: + postcss: ^8.0.3 + + postcss-selector-not@8.0.1: + resolution: {integrity: sha512-kmVy/5PYVb2UOhy0+LqUYAhKj7DUGDpSWa5LZqlkWJaaAV+dxxsOG3+St0yNLu6vsKD7Dmqx+nWQt0iil89+WA==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + postcss-selector-parser@7.1.0: + resolution: {integrity: sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==} + engines: {node: '>=4'} + + postcss-sort-media-queries@5.2.0: + resolution: {integrity: sha512-AZ5fDMLD8SldlAYlvi8NIqo0+Z8xnXU2ia0jxmuhxAU+Lqt9K+AlmLNJ/zWEnE9x+Zx3qL3+1K20ATgNOr3fAA==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.4.23 + + postcss-svgo@6.0.3: + resolution: {integrity: sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==} + engines: {node: ^14 || ^16 || >= 18} + peerDependencies: + postcss: ^8.4.31 + + postcss-unique-selectors@6.0.4: + resolution: {integrity: sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss-zindex@6.0.2: + resolution: {integrity: sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + engines: {node: ^10 || ^12 || >=14} + + pretty-error@4.0.0: + resolution: {integrity: sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==} + + pretty-time@1.1.0: + resolution: {integrity: sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==} + engines: {node: '>=4'} + + prism-react-renderer@2.4.1: + resolution: {integrity: sha512-ey8Ls/+Di31eqzUxC46h8MksNuGx/n0AAC8uKpwFau4RPDYLuE3EXTp8N8G2vX2N7UC/+IXeNUnlWBGGcAG+Ig==} + peerDependencies: + react: '>=16.0.0' + + prismjs@1.30.0: + resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} + engines: {node: '>=6'} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + + property-information@6.5.0: + resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} + + property-information@7.1.0: + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + + proto-list@1.2.4: + resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + pupa@3.3.0: + resolution: {integrity: sha512-LjgDO2zPtoXP2wJpDjZrGdojii1uqO0cnwKoIoUzkfS98HDmbeiGmYiXo3lXeFlq2xvne1QFQhwYXSUCLKtEuA==} + engines: {node: '>=12.20'} + + qs@6.13.0: + resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} + engines: {node: '>=0.6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + range-parser@1.2.0: + resolution: {integrity: sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==} + engines: {node: '>= 0.6'} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@2.5.2: + resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} + engines: {node: '>= 0.8'} + + rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + + react-dom@19.2.0: + resolution: {integrity: sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==} + peerDependencies: + react: ^19.2.0 + + react-fast-compare@3.2.2: + resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==} + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react-json-view-lite@2.5.0: + resolution: {integrity: sha512-tk7o7QG9oYyELWHL8xiMQ8x4WzjCzbWNyig3uexmkLb54r8jO0yH3WCWx8UZS0c49eSA4QUmG5caiRJ8fAn58g==} + engines: {node: '>=18'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + + react-loadable-ssr-addon-v5-slorber@1.0.1: + resolution: {integrity: sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A==} + engines: {node: '>=10.13.0'} + peerDependencies: + react-loadable: '*' + webpack: '>=4.41.1 || 5.x' + + react-router-config@5.1.1: + resolution: {integrity: sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg==} + peerDependencies: + react: '>=15' + react-router: '>=5' + + react-router-dom@5.3.4: + resolution: {integrity: sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==} + peerDependencies: + react: '>=15' + + react-router@5.3.4: + resolution: {integrity: sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==} + peerDependencies: + react: '>=15' + + react@19.2.0: + resolution: {integrity: sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==} + engines: {node: '>=0.10.0'} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + recma-build-jsx@1.0.0: + resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==} + + recma-jsx@1.0.1: + resolution: {integrity: sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + recma-parse@1.0.0: + resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==} + + recma-stringify@1.0.0: + resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==} + + regenerate-unicode-properties@10.2.2: + resolution: {integrity: sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==} + engines: {node: '>=4'} + + regenerate@1.4.2: + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + + regexpu-core@6.4.0: + resolution: {integrity: sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==} + engines: {node: '>=4'} + + registry-auth-token@5.1.0: + resolution: {integrity: sha512-GdekYuwLXLxMuFTwAPg5UKGLW/UXzQrZvH/Zj791BQif5T05T0RsaLfHc9q3ZOKi7n+BoprPD9mJ0O0k4xzUlw==} + engines: {node: '>=14'} + + registry-url@6.0.1: + resolution: {integrity: sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==} + engines: {node: '>=12'} + + regjsgen@0.8.0: + resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==} + + regjsparser@0.13.0: + resolution: {integrity: sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==} + hasBin: true + + rehype-raw@7.0.0: + resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} + + rehype-recma@1.0.0: + resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} + + relateurl@0.2.7: + resolution: {integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==} + engines: {node: '>= 0.10'} + + remark-directive@3.0.1: + resolution: {integrity: sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A==} + + remark-emoji@4.0.1: + resolution: {integrity: sha512-fHdvsTR1dHkWKev9eNyhTo4EFwbUvJ8ka9SgeWkMPYFX4WoI7ViVBms3PjlQYgw5TLvNQso3GUB/b/8t3yo+dg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + remark-frontmatter@5.0.0: + resolution: {integrity: sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==} + + remark-gfm@4.0.1: + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + + remark-mdx@3.1.1: + resolution: {integrity: sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-rehype@11.1.2: + resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + + renderkid@3.0.0: + resolution: {integrity: sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==} + + repeat-string@1.6.1: + resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} + engines: {node: '>=0.10'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + require-like@0.1.2: + resolution: {integrity: sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==} + + requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + + resolve-alpn@1.2.1: + resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-pathname@3.0.0: + resolution: {integrity: sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==} + + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + engines: {node: '>= 0.4'} + hasBin: true + + responselike@3.0.0: + resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==} + engines: {node: '>=14.16'} + + retry@0.13.1: + resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} + engines: {node: '>= 4'} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rtlcss@4.3.0: + resolution: {integrity: sha512-FI+pHEn7Wc4NqKXMXFM+VAYKEj/mRIcW4h24YVwVtyjI+EqGrLc2Hx/Ny0lrZ21cBWU2goLy36eqMcNj3AQJig==} + engines: {node: '>=12.0.0'} + hasBin: true + + run-applescript@7.1.0: + resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} + engines: {node: '>=18'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sax@1.4.3: + resolution: {integrity: sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==} + + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + + schema-dts@1.1.5: + resolution: {integrity: sha512-RJr9EaCmsLzBX2NDiO5Z3ux2BVosNZN5jo0gWgsyKvxKIUL5R3swNvoorulAeL9kLB0iTSX7V6aokhla2m7xbg==} + + schema-utils@3.3.0: + resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} + engines: {node: '>= 10.13.0'} + + schema-utils@4.3.3: + resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} + engines: {node: '>= 10.13.0'} + + search-insights@2.17.3: + resolution: {integrity: sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==} + + section-matter@1.0.0: + resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} + engines: {node: '>=4'} + + select-hose@2.0.0: + resolution: {integrity: sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==} + + selfsigned@2.4.1: + resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} + engines: {node: '>=10'} + + semver-diff@4.0.0: + resolution: {integrity: sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==} + engines: {node: '>=12'} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.3: + resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} + engines: {node: '>=10'} + hasBin: true + + send@0.19.0: + resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} + engines: {node: '>= 0.8.0'} + + serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + + serve-handler@6.1.6: + resolution: {integrity: sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==} + + serve-index@1.9.1: + resolution: {integrity: sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==} + engines: {node: '>= 0.8.0'} + + serve-static@1.16.2: + resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} + engines: {node: '>= 0.8.0'} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + setprototypeof@1.1.0: + resolution: {integrity: sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + shallow-clone@3.0.1: + resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} + engines: {node: '>=8'} + + shallowequal@1.1.0: + resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shell-quote@1.8.3: + resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} + engines: {node: '>= 0.4'} + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + sirv@2.0.4: + resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==} + engines: {node: '>= 10'} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + sitemap@7.1.2: + resolution: {integrity: sha512-ARCqzHJ0p4gWt+j7NlU5eDlIO9+Rkr/JhPFZKKQ1l5GCus7rJH4UdrlVAh0xC/gDS/Qir2UMxqYNHtsKr2rpCw==} + engines: {node: '>=12.0.0', npm: '>=5.6.0'} + hasBin: true + + skin-tone@2.0.0: + resolution: {integrity: sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==} + engines: {node: '>=8'} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slash@4.0.0: + resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} + engines: {node: '>=12'} + + snake-case@3.0.4: + resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} + + sockjs@0.3.24: + resolution: {integrity: sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==} + + sort-css-media-queries@2.2.0: + resolution: {integrity: sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA==} + engines: {node: '>= 6.3.0'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + spdy-transport@3.0.0: + resolution: {integrity: sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==} + + spdy@4.0.2: + resolution: {integrity: sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==} + engines: {node: '>=6.0.0'} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + srcset@4.0.0: + resolution: {integrity: sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==} + engines: {node: '>=12'} + + statuses@1.5.0: + resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} + engines: {node: '>= 0.6'} + + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + + std-env@3.10.0: + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + + stringify-object@3.3.0: + resolution: {integrity: sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==} + engines: {node: '>=4'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.2: + resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} + engines: {node: '>=12'} + + strip-bom-string@1.0.0: + resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} + engines: {node: '>=0.10.0'} + + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + style-to-js@1.1.19: + resolution: {integrity: sha512-Ev+SgeqiNGT1ufsXyVC5RrJRXdrkRJ1Gol9Qw7Pb72YCKJXrBvP0ckZhBeVSrw2m06DJpei2528uIpjMb4TsoQ==} + + style-to-object@1.0.12: + resolution: {integrity: sha512-ddJqYnoT4t97QvN2C95bCgt+m7AAgXjVnkk/jxAfmp7EAB8nnqqZYEbMd3em7/vEomDb2LAQKAy1RFfv41mdNw==} + + stylehacks@6.1.1: + resolution: {integrity: sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + svg-parser@2.0.4: + resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==} + + svgo@3.3.2: + resolution: {integrity: sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==} + engines: {node: '>=14.0.0'} + hasBin: true + + swr@2.3.6: + resolution: {integrity: sha512-wfHRmHWk/isGNMwlLGlZX5Gzz/uTgo0o2IRuTMcf4CPuPFJZlq0rDaKUx+ozB5nBOReNV1kiOyzMfj+MBMikLw==} + peerDependencies: + react: ^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + tagged-tag@1.0.0: + resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} + engines: {node: '>=20'} + + tapable@2.3.0: + resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} + engines: {node: '>=6'} + + terser-webpack-plugin@5.3.14: + resolution: {integrity: sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==} + engines: {node: '>= 10.13.0'} + peerDependencies: + '@swc/core': '*' + esbuild: '*' + uglify-js: '*' + webpack: ^5.1.0 + peerDependenciesMeta: + '@swc/core': + optional: true + esbuild: + optional: true + uglify-js: + optional: true + + terser@5.44.1: + resolution: {integrity: sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==} + engines: {node: '>=10'} + hasBin: true + + thingies@2.5.0: + resolution: {integrity: sha512-s+2Bwztg6PhWUD7XMfeYm5qliDdSiZm7M7n8KjTkIsm3l/2lgVRc2/Gx/v+ZX8lT4FMA+i8aQvhcWylldc+ZNw==} + engines: {node: '>=10.18'} + peerDependencies: + tslib: ^2 + + throttleit@2.1.0: + resolution: {integrity: sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==} + engines: {node: '>=18'} + + thunky@1.1.0: + resolution: {integrity: sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==} + + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + + tiny-warning@1.0.3: + resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==} + + tinypool@1.1.1: + resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} + engines: {node: ^18.0.0 || >=20.0.0} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + + tree-dump@1.1.0: + resolution: {integrity: sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + type-fest@1.4.0: + resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} + engines: {node: '>=10'} + + type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + + type-fest@5.0.0: + resolution: {integrity: sha512-GeJop7+u7BYlQ6yQCAY1nBQiRSHR+6OdCEtd8Bwp9a3NK3+fWAVjOaPKJDteB9f6cIJ0wt4IfnScjLG450EpXA==} + engines: {node: '>=20'} + + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + + typedarray-to-buffer@3.1.5: + resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} + + typescript@5.6.3: + resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + + unicode-canonical-property-names-ecmascript@2.0.1: + resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==} + engines: {node: '>=4'} + + unicode-emoji-modifier-base@1.0.0: + resolution: {integrity: sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==} + engines: {node: '>=4'} + + unicode-match-property-ecmascript@2.0.0: + resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} + engines: {node: '>=4'} + + unicode-match-property-value-ecmascript@2.2.1: + resolution: {integrity: sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==} + engines: {node: '>=4'} + + unicode-property-aliases-ecmascript@2.2.0: + resolution: {integrity: sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==} + engines: {node: '>=4'} + + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + + unique-string@3.0.0: + resolution: {integrity: sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==} + engines: {node: '>=12'} + + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-position-from-estree@2.0.0: + resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + update-browserslist-db@1.1.4: + resolution: {integrity: sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + update-notifier@6.0.2: + resolution: {integrity: sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==} + engines: {node: '>=14.16'} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + url-loader@4.1.1: + resolution: {integrity: sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==} + engines: {node: '>= 10.13.0'} + peerDependencies: + file-loader: '*' + webpack: ^4.0.0 || ^5.0.0 + peerDependenciesMeta: + file-loader: + optional: true + + use-sync-external-store@1.6.0: + resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + utila@0.4.0: + resolution: {integrity: sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==} + + utility-types@3.11.0: + resolution: {integrity: sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==} + engines: {node: '>= 4'} + + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + + value-equal@1.0.1: + resolution: {integrity: sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + vfile-location@5.0.3: + resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} + + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + watchpack@2.4.4: + resolution: {integrity: sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==} + engines: {node: '>=10.13.0'} + + wbuf@1.7.3: + resolution: {integrity: sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==} + + web-namespaces@2.0.1: + resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + + webpack-bundle-analyzer@4.10.2: + resolution: {integrity: sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==} + engines: {node: '>= 10.13.0'} + hasBin: true + + webpack-dev-middleware@7.4.5: + resolution: {integrity: sha512-uxQ6YqGdE4hgDKNf7hUiPXOdtkXvBJXrfEGYSx7P7LC8hnUYGK70X6xQXUvXeNyBDDcsiQXpG2m3G9vxowaEuA==} + engines: {node: '>= 18.12.0'} + peerDependencies: + webpack: ^5.0.0 + peerDependenciesMeta: + webpack: + optional: true + + webpack-dev-server@5.2.2: + resolution: {integrity: sha512-QcQ72gh8a+7JO63TAx/6XZf/CWhgMzu5m0QirvPfGvptOusAxG12w2+aua1Jkjr7hzaWDnJ2n6JFeexMHI+Zjg==} + engines: {node: '>= 18.12.0'} + hasBin: true + peerDependencies: + webpack: ^5.0.0 + webpack-cli: '*' + peerDependenciesMeta: + webpack: + optional: true + webpack-cli: + optional: true + + webpack-merge@5.10.0: + resolution: {integrity: sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==} + engines: {node: '>=10.0.0'} + + webpack-merge@6.0.1: + resolution: {integrity: sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==} + engines: {node: '>=18.0.0'} + + webpack-sources@3.3.3: + resolution: {integrity: sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==} + engines: {node: '>=10.13.0'} + + webpack@5.102.1: + resolution: {integrity: sha512-7h/weGm9d/ywQ6qzJ+Xy+r9n/3qgp/thalBbpOi5i223dPXKi04IBtqPN9nTd+jBc7QKfvDbaBnFipYp4sJAUQ==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + + webpackbar@6.0.1: + resolution: {integrity: sha512-TnErZpmuKdwWBdMoexjio3KKX6ZtoKHRVvLIU0A47R0VVBDtx3ZyOJDktgYixhoJokZTYTt1Z37OkO9pnGJa9Q==} + engines: {node: '>=14.21.3'} + peerDependencies: + webpack: 3 || 4 || 5 + + websocket-driver@0.7.4: + resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==} + engines: {node: '>=0.8.0'} + + websocket-extensions@0.1.4: + resolution: {integrity: sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==} + engines: {node: '>=0.8.0'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + widest-line@4.0.1: + resolution: {integrity: sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==} + engines: {node: '>=12'} + + wildcard@2.0.1: + resolution: {integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + write-file-atomic@3.0.3: + resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} + + ws@7.5.10: + resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.18.3: + resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + wsl-utils@0.1.0: + resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==} + engines: {node: '>=18'} + + xdg-basedir@5.1.0: + resolution: {integrity: sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==} + engines: {node: '>=12'} + + xml-js@1.6.11: + resolution: {integrity: sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==} + hasBin: true + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yocto-queue@1.2.2: + resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} + engines: {node: '>=12.20'} + + zod@4.1.11: + resolution: {integrity: sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg==} + + zod@4.1.12: + resolution: {integrity: sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@ai-sdk/gateway@2.0.9(zod@4.1.12)': + dependencies: + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.17(zod@4.1.12) + '@vercel/oidc': 3.0.3 + zod: 4.1.12 + + '@ai-sdk/provider-utils@3.0.17(zod@4.1.12)': + dependencies: + '@ai-sdk/provider': 2.0.0 + '@standard-schema/spec': 1.0.0 + eventsource-parser: 3.0.6 + zod: 4.1.12 + + '@ai-sdk/provider@2.0.0': + dependencies: + json-schema: 0.4.0 + + '@ai-sdk/react@2.0.93(react@19.2.0)(zod@4.1.12)': + dependencies: + '@ai-sdk/provider-utils': 3.0.17(zod@4.1.12) + ai: 5.0.93(zod@4.1.12) + react: 19.2.0 + swr: 2.3.6(react@19.2.0) + throttleit: 2.1.0 + optionalDependencies: + zod: 4.1.12 + + '@algolia/abtesting@1.9.0': + dependencies: + '@algolia/client-common': 5.43.0 + '@algolia/requester-browser-xhr': 5.43.0 + '@algolia/requester-fetch': 5.43.0 + '@algolia/requester-node-http': 5.43.0 + + '@algolia/autocomplete-core@1.19.2(@algolia/client-search@5.43.0)(algoliasearch@5.43.0)(search-insights@2.17.3)': + dependencies: + '@algolia/autocomplete-plugin-algolia-insights': 1.19.2(@algolia/client-search@5.43.0)(algoliasearch@5.43.0)(search-insights@2.17.3) + '@algolia/autocomplete-shared': 1.19.2(@algolia/client-search@5.43.0)(algoliasearch@5.43.0) + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + - search-insights + + '@algolia/autocomplete-plugin-algolia-insights@1.19.2(@algolia/client-search@5.43.0)(algoliasearch@5.43.0)(search-insights@2.17.3)': + dependencies: + '@algolia/autocomplete-shared': 1.19.2(@algolia/client-search@5.43.0)(algoliasearch@5.43.0) + search-insights: 2.17.3 + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + + '@algolia/autocomplete-shared@1.19.2(@algolia/client-search@5.43.0)(algoliasearch@5.43.0)': + dependencies: + '@algolia/client-search': 5.43.0 + algoliasearch: 5.43.0 + + '@algolia/client-abtesting@5.43.0': + dependencies: + '@algolia/client-common': 5.43.0 + '@algolia/requester-browser-xhr': 5.43.0 + '@algolia/requester-fetch': 5.43.0 + '@algolia/requester-node-http': 5.43.0 + + '@algolia/client-analytics@5.43.0': + dependencies: + '@algolia/client-common': 5.43.0 + '@algolia/requester-browser-xhr': 5.43.0 + '@algolia/requester-fetch': 5.43.0 + '@algolia/requester-node-http': 5.43.0 + + '@algolia/client-common@5.43.0': {} + + '@algolia/client-insights@5.43.0': + dependencies: + '@algolia/client-common': 5.43.0 + '@algolia/requester-browser-xhr': 5.43.0 + '@algolia/requester-fetch': 5.43.0 + '@algolia/requester-node-http': 5.43.0 + + '@algolia/client-personalization@5.43.0': + dependencies: + '@algolia/client-common': 5.43.0 + '@algolia/requester-browser-xhr': 5.43.0 + '@algolia/requester-fetch': 5.43.0 + '@algolia/requester-node-http': 5.43.0 + + '@algolia/client-query-suggestions@5.43.0': + dependencies: + '@algolia/client-common': 5.43.0 + '@algolia/requester-browser-xhr': 5.43.0 + '@algolia/requester-fetch': 5.43.0 + '@algolia/requester-node-http': 5.43.0 + + '@algolia/client-search@5.43.0': + dependencies: + '@algolia/client-common': 5.43.0 + '@algolia/requester-browser-xhr': 5.43.0 + '@algolia/requester-fetch': 5.43.0 + '@algolia/requester-node-http': 5.43.0 + + '@algolia/events@4.0.1': {} + + '@algolia/ingestion@1.43.0': + dependencies: + '@algolia/client-common': 5.43.0 + '@algolia/requester-browser-xhr': 5.43.0 + '@algolia/requester-fetch': 5.43.0 + '@algolia/requester-node-http': 5.43.0 + + '@algolia/monitoring@1.43.0': + dependencies: + '@algolia/client-common': 5.43.0 + '@algolia/requester-browser-xhr': 5.43.0 + '@algolia/requester-fetch': 5.43.0 + '@algolia/requester-node-http': 5.43.0 + + '@algolia/recommend@5.43.0': + dependencies: + '@algolia/client-common': 5.43.0 + '@algolia/requester-browser-xhr': 5.43.0 + '@algolia/requester-fetch': 5.43.0 + '@algolia/requester-node-http': 5.43.0 + + '@algolia/requester-browser-xhr@5.43.0': + dependencies: + '@algolia/client-common': 5.43.0 + + '@algolia/requester-fetch@5.43.0': + dependencies: + '@algolia/client-common': 5.43.0 + + '@algolia/requester-node-http@5.43.0': + dependencies: + '@algolia/client-common': 5.43.0 + + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.28.5': {} + + '@babel/core@7.28.5': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/helpers': 7.28.4 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.28.5': + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@7.27.3': + dependencies: + '@babel/types': 7.28.5 + + '@babel/helper-compilation-targets@7.27.2': + dependencies: + '@babel/compat-data': 7.28.5 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.0 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.28.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.5) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.28.5 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-create-regexp-features-plugin@7.28.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + regexpu-core: 6.4.0 + semver: 6.3.1 + + '@babel/helper-define-polyfill-provider@0.6.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-plugin-utils': 7.27.1 + debug: 4.4.3 + lodash.debounce: 4.0.8 + resolve: 1.22.11 + transitivePeerDependencies: + - supports-color + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-member-expression-to-functions@7.28.5': + dependencies: + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.27.1': + dependencies: + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.27.1': + dependencies: + '@babel/types': 7.28.5 + + '@babel/helper-plugin-utils@7.27.1': {} + + '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-wrap-function': 7.28.3 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-replace-supers@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + dependencies: + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helper-wrap-function@7.28.3': + dependencies: + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helpers@7.28.4': + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 + + '@babel/parser@7.28.5': + dependencies: + '@babel/types': 7.28.5 + + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-transform-optional-chaining': 7.28.5(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + + '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-import-assertions@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-async-generator-functions@7.28.0(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.5) + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-async-to-generator@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-block-scoping@7.28.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-class-properties@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-class-static-block@7.28.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-classes@7.28.4(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-globals': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.5) + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-computed-properties@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/template': 7.27.2 + + '@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-dotall-regex@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-explicit-resource-management@7.28.0(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-exponentiation-operator@7.28.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-json-strings@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-literals@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-logical-assignment-operators@7.28.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-systemjs@7.28.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-named-capturing-groups-regex@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-nullish-coalescing-operator@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-numeric-separator@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-object-rest-spread@7.28.4(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.28.5) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.5) + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-optional-catch-binding@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-optional-chaining@7.28.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-private-methods@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-private-property-in-object@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-react-constant-elements@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-react-display-name@7.28.0(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5) + '@babel/types': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-react-pure-annotations@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-regenerator@7.28.4(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-regexp-modifiers@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-runtime@7.28.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.28.5) + babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.28.5) + babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.28.5) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-spread@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-typescript@7.28.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-unicode-property-regex@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-unicode-sets-regex@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/preset-env@7.28.5(@babel/core@7.28.5)': + dependencies: + '@babel/compat-data': 7.28.5 + '@babel/core': 7.28.5 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.28.5(@babel/core@7.28.5) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.28.3(@babel/core@7.28.5) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.5) + '@babel/plugin-syntax-import-assertions': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.28.5) + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-async-generator-functions': 7.28.0(@babel/core@7.28.5) + '@babel/plugin-transform-async-to-generator': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-block-scoping': 7.28.5(@babel/core@7.28.5) + '@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-class-static-block': 7.28.3(@babel/core@7.28.5) + '@babel/plugin-transform-classes': 7.28.4(@babel/core@7.28.5) + '@babel/plugin-transform-computed-properties': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.28.5) + '@babel/plugin-transform-dotall-regex': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-explicit-resource-management': 7.28.0(@babel/core@7.28.5) + '@babel/plugin-transform-exponentiation-operator': 7.28.5(@babel/core@7.28.5) + '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-json-strings': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-logical-assignment-operators': 7.28.5(@babel/core@7.28.5) + '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-modules-systemjs': 7.28.5(@babel/core@7.28.5) + '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-nullish-coalescing-operator': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-numeric-separator': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-object-rest-spread': 7.28.4(@babel/core@7.28.5) + '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-optional-catch-binding': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-optional-chaining': 7.28.5(@babel/core@7.28.5) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.5) + '@babel/plugin-transform-private-methods': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-private-property-in-object': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-regenerator': 7.28.4(@babel/core@7.28.5) + '@babel/plugin-transform-regexp-modifiers': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-spread': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-unicode-property-regex': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-unicode-sets-regex': 7.27.1(@babel/core@7.28.5) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.28.5) + babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.28.5) + babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.28.5) + babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.28.5) + core-js-compat: 3.46.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/types': 7.28.5 + esutils: 2.0.3 + + '@babel/preset-react@7.28.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-transform-react-display-name': 7.28.0(@babel/core@7.28.5) + '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-react-pure-annotations': 7.27.1(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + + '@babel/preset-typescript@7.28.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-typescript': 7.28.5(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + + '@babel/runtime-corejs3@7.28.4': + dependencies: + core-js-pure: 3.46.0 + + '@babel/runtime@7.28.4': {} + + '@babel/template@7.27.2': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + + '@babel/traverse@7.28.5': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.28.5': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@colors/colors@1.5.0': + optional: true + + '@csstools/cascade-layer-name-parser@2.0.5(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/color-helpers@5.1.0': {} + + '@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-color-parser@3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/color-helpers': 5.1.0 + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-tokenizer@3.0.4': {} + + '@csstools/media-query-list-parser@4.0.3(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/postcss-alpha-function@1.0.1(postcss@8.5.6)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + + '@csstools/postcss-cascade-layers@5.0.2(postcss@8.5.6)': + dependencies: + '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.0) + postcss: 8.5.6 + postcss-selector-parser: 7.1.0 + + '@csstools/postcss-color-function-display-p3-linear@1.0.1(postcss@8.5.6)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + + '@csstools/postcss-color-function@4.0.12(postcss@8.5.6)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + + '@csstools/postcss-color-mix-function@3.0.12(postcss@8.5.6)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + + '@csstools/postcss-color-mix-variadic-function-arguments@1.0.2(postcss@8.5.6)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + + '@csstools/postcss-content-alt-text@2.0.8(postcss@8.5.6)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + + '@csstools/postcss-contrast-color-function@2.0.12(postcss@8.5.6)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + + '@csstools/postcss-exponential-functions@2.0.9(postcss@8.5.6)': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.6 + + '@csstools/postcss-font-format-keywords@4.0.0(postcss@8.5.6)': + dependencies: + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + '@csstools/postcss-gamut-mapping@2.0.11(postcss@8.5.6)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.6 + + '@csstools/postcss-gradients-interpolation-method@5.0.12(postcss@8.5.6)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + + '@csstools/postcss-hwb-function@4.0.12(postcss@8.5.6)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + + '@csstools/postcss-ic-unit@4.0.4(postcss@8.5.6)': + dependencies: + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + '@csstools/postcss-initial@2.0.1(postcss@8.5.6)': + dependencies: + postcss: 8.5.6 + + '@csstools/postcss-is-pseudo-class@5.0.3(postcss@8.5.6)': + dependencies: + '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.0) + postcss: 8.5.6 + postcss-selector-parser: 7.1.0 + + '@csstools/postcss-light-dark-function@2.0.11(postcss@8.5.6)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + + '@csstools/postcss-logical-float-and-clear@3.0.0(postcss@8.5.6)': + dependencies: + postcss: 8.5.6 + + '@csstools/postcss-logical-overflow@2.0.0(postcss@8.5.6)': + dependencies: + postcss: 8.5.6 + + '@csstools/postcss-logical-overscroll-behavior@2.0.0(postcss@8.5.6)': + dependencies: + postcss: 8.5.6 + + '@csstools/postcss-logical-resize@3.0.0(postcss@8.5.6)': + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + '@csstools/postcss-logical-viewport-units@3.0.4(postcss@8.5.6)': + dependencies: + '@csstools/css-tokenizer': 3.0.4 + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + + '@csstools/postcss-media-minmax@2.0.9(postcss@8.5.6)': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/media-query-list-parser': 4.0.3(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + postcss: 8.5.6 + + '@csstools/postcss-media-queries-aspect-ratio-number-values@3.0.5(postcss@8.5.6)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/media-query-list-parser': 4.0.3(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + postcss: 8.5.6 + + '@csstools/postcss-nested-calc@4.0.0(postcss@8.5.6)': + dependencies: + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + '@csstools/postcss-normalize-display-values@4.0.0(postcss@8.5.6)': + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + '@csstools/postcss-oklab-function@4.0.12(postcss@8.5.6)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + + '@csstools/postcss-progressive-custom-properties@4.2.1(postcss@8.5.6)': + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + '@csstools/postcss-random-function@2.0.1(postcss@8.5.6)': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.6 + + '@csstools/postcss-relative-color-syntax@3.0.12(postcss@8.5.6)': + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + + '@csstools/postcss-scope-pseudo-class@4.0.1(postcss@8.5.6)': + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 7.1.0 + + '@csstools/postcss-sign-functions@1.1.4(postcss@8.5.6)': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.6 + + '@csstools/postcss-stepped-value-functions@4.0.9(postcss@8.5.6)': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.6 + + '@csstools/postcss-text-decoration-shorthand@4.0.3(postcss@8.5.6)': + dependencies: + '@csstools/color-helpers': 5.1.0 + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + '@csstools/postcss-trigonometric-functions@4.0.9(postcss@8.5.6)': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.6 + + '@csstools/postcss-unset-value@4.0.0(postcss@8.5.6)': + dependencies: + postcss: 8.5.6 + + '@csstools/selector-resolve-nested@3.1.0(postcss-selector-parser@7.1.0)': + dependencies: + postcss-selector-parser: 7.1.0 + + '@csstools/selector-specificity@5.0.0(postcss-selector-parser@7.1.0)': + dependencies: + postcss-selector-parser: 7.1.0 + + '@csstools/utilities@2.0.0(postcss@8.5.6)': + dependencies: + postcss: 8.5.6 + + '@discoveryjs/json-ext@0.5.7': {} + + '@docsearch/core@4.3.1(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + optionalDependencies: + '@types/react': 19.2.4 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + + '@docsearch/css@4.3.2': {} + + '@docsearch/react@4.3.2(@algolia/client-search@5.43.0)(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(search-insights@2.17.3)': + dependencies: + '@ai-sdk/react': 2.0.93(react@19.2.0)(zod@4.1.12) + '@algolia/autocomplete-core': 1.19.2(@algolia/client-search@5.43.0)(algoliasearch@5.43.0)(search-insights@2.17.3) + '@docsearch/core': 4.3.1(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docsearch/css': 4.3.2 + ai: 5.0.93(zod@4.1.12) + algoliasearch: 5.43.0 + marked: 16.4.2 + zod: 4.1.12 + optionalDependencies: + '@types/react': 19.2.4 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + search-insights: 2.17.3 + transitivePeerDependencies: + - '@algolia/client-search' + + '@docusaurus/babel@3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@babel/core': 7.28.5 + '@babel/generator': 7.28.5 + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.28.5) + '@babel/plugin-transform-runtime': 7.28.5(@babel/core@7.28.5) + '@babel/preset-env': 7.28.5(@babel/core@7.28.5) + '@babel/preset-react': 7.28.5(@babel/core@7.28.5) + '@babel/preset-typescript': 7.28.5(@babel/core@7.28.5) + '@babel/runtime': 7.28.4 + '@babel/runtime-corejs3': 7.28.4 + '@babel/traverse': 7.28.5 + '@docusaurus/logger': 3.9.2 + '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + babel-plugin-dynamic-import-node: 2.3.3 + fs-extra: 11.3.2 + tslib: 2.8.1 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - react + - react-dom + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/bundler@3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + dependencies: + '@babel/core': 7.28.5 + '@docusaurus/babel': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/cssnano-preset': 3.9.2 + '@docusaurus/logger': 3.9.2 + '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + babel-loader: 9.2.1(@babel/core@7.28.5)(webpack@5.102.1) + clean-css: 5.3.3 + copy-webpack-plugin: 11.0.0(webpack@5.102.1) + css-loader: 6.11.0(webpack@5.102.1) + css-minimizer-webpack-plugin: 5.0.1(clean-css@5.3.3)(webpack@5.102.1) + cssnano: 6.1.2(postcss@8.5.6) + file-loader: 6.2.0(webpack@5.102.1) + html-minifier-terser: 7.2.0 + mini-css-extract-plugin: 2.9.4(webpack@5.102.1) + null-loader: 4.0.1(webpack@5.102.1) + postcss: 8.5.6 + postcss-loader: 7.3.4(postcss@8.5.6)(typescript@5.6.3)(webpack@5.102.1) + postcss-preset-env: 10.4.0(postcss@8.5.6) + terser-webpack-plugin: 5.3.14(webpack@5.102.1) + tslib: 2.8.1 + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.102.1))(webpack@5.102.1) + webpack: 5.102.1 + webpackbar: 6.0.1(webpack@5.102.1) + transitivePeerDependencies: + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - csso + - esbuild + - lightningcss + - react + - react-dom + - supports-color + - typescript + - uglify-js + - webpack-cli + + '@docusaurus/core@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + dependencies: + '@docusaurus/babel': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/bundler': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/logger': 3.9.2 + '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@mdx-js/react': 3.1.1(@types/react@19.2.4)(react@19.2.0) + boxen: 6.2.1 + chalk: 4.1.2 + chokidar: 3.6.0 + cli-table3: 0.6.5 + combine-promises: 1.2.0 + commander: 5.1.0 + core-js: 3.46.0 + detect-port: 1.6.1 + escape-html: 1.0.3 + eta: 2.2.0 + eval: 0.1.8 + execa: 5.1.1 + fs-extra: 11.3.2 + html-tags: 3.3.1 + html-webpack-plugin: 5.6.4(webpack@5.102.1) + leven: 3.1.0 + lodash: 4.17.21 + open: 8.4.2 + p-map: 4.0.0 + prompts: 2.4.2 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0)' + react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.0)' + react-loadable-ssr-addon-v5-slorber: 1.0.1(@docusaurus/react-loadable@6.0.0(react@19.2.0))(webpack@5.102.1) + react-router: 5.3.4(react@19.2.0) + react-router-config: 5.1.1(react-router@5.3.4(react@19.2.0))(react@19.2.0) + react-router-dom: 5.3.4(react@19.2.0) + semver: 7.7.3 + serve-handler: 6.1.6 + tinypool: 1.1.1 + tslib: 2.8.1 + update-notifier: 6.0.2 + webpack: 5.102.1 + webpack-bundle-analyzer: 4.10.2 + webpack-dev-server: 5.2.2(webpack@5.102.1) + webpack-merge: 6.0.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/cssnano-preset@3.9.2': + dependencies: + cssnano-preset-advanced: 6.1.2(postcss@8.5.6) + postcss: 8.5.6 + postcss-sort-media-queries: 5.2.0(postcss@8.5.6) + tslib: 2.8.1 + + '@docusaurus/logger@3.9.2': + dependencies: + chalk: 4.1.2 + tslib: 2.8.1 + + '@docusaurus/mdx-loader@3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@docusaurus/logger': 3.9.2 + '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@mdx-js/mdx': 3.1.1 + '@slorber/remark-comment': 1.0.0 + escape-html: 1.0.3 + estree-util-value-to-estree: 3.5.0 + file-loader: 6.2.0(webpack@5.102.1) + fs-extra: 11.3.2 + image-size: 2.0.2 + mdast-util-mdx: 3.0.0 + mdast-util-to-string: 4.0.0 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + rehype-raw: 7.0.0 + remark-directive: 3.0.1 + remark-emoji: 4.0.1 + remark-frontmatter: 5.0.0 + remark-gfm: 4.0.1 + stringify-object: 3.3.0 + tslib: 2.8.1 + unified: 11.0.5 + unist-util-visit: 5.0.0 + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.102.1))(webpack@5.102.1) + vfile: 6.0.3 + webpack: 5.102.1 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/module-type-aliases@3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@types/history': 4.7.11 + '@types/react': 19.2.4 + '@types/react-router-config': 5.0.11 + '@types/react-router-dom': 5.3.3 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0)' + react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.0)' + transitivePeerDependencies: + - '@swc/core' + - esbuild + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/plugin-client-redirects@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/logger': 3.9.2 + '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + eta: 2.2.0 + fs-extra: 11.3.2 + lodash: 4.17.21 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + tslib: 2.8.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-content-blog@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/logger': 3.9.2 + '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + cheerio: 1.0.0-rc.12 + feed: 4.2.2 + fs-extra: 11.3.2 + lodash: 4.17.21 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + schema-dts: 1.1.5 + srcset: 4.0.0 + tslib: 2.8.1 + unist-util-visit: 5.0.0 + utility-types: 3.11.0 + webpack: 5.102.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/logger': 3.9.2 + '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/module-type-aliases': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@types/react-router-config': 5.0.11 + combine-promises: 1.2.0 + fs-extra: 11.3.2 + js-yaml: 4.1.1 + lodash: 4.17.21 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + schema-dts: 1.1.5 + tslib: 2.8.1 + utility-types: 3.11.0 + webpack: 5.102.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-content-pages@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + fs-extra: 11.3.2 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + tslib: 2.8.1 + webpack: 5.102.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-css-cascade-layers@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + tslib: 2.8.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - react + - react-dom + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-debug@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + fs-extra: 11.3.2 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + react-json-view-lite: 2.5.0(react@19.2.0) + tslib: 2.8.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-google-analytics@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + tslib: 2.8.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-google-gtag@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@types/gtag.js': 0.0.12 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + tslib: 2.8.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-google-tag-manager@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + tslib: 2.8.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-sitemap@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/logger': 3.9.2 + '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + fs-extra: 11.3.2 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + sitemap: 7.1.2 + tslib: 2.8.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/plugin-svgr@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@svgr/core': 8.1.0(typescript@5.6.3) + '@svgr/webpack': 8.1.0(typescript@5.6.3) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + tslib: 2.8.1 + webpack: 5.102.1 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/preset-classic@3.9.2(@algolia/client-search@5.43.0)(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(search-insights@2.17.3)(typescript@5.6.3)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/plugin-content-blog': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/plugin-content-pages': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/plugin-css-cascade-layers': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/plugin-debug': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/plugin-google-analytics': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/plugin-google-gtag': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/plugin-google-tag-manager': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/plugin-sitemap': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/plugin-svgr': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/theme-classic': 3.9.2(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/theme-search-algolia': 3.9.2(@algolia/client-search@5.43.0)(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(search-insights@2.17.3)(typescript@5.6.3) + '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + transitivePeerDependencies: + - '@algolia/client-search' + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - '@types/react' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - search-insights + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/react-loadable@6.0.0(react@19.2.0)': + dependencies: + '@types/react': 19.2.4 + react: 19.2.0 + + '@docusaurus/theme-classic@3.9.2(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/logger': 3.9.2 + '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/module-type-aliases': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/plugin-content-blog': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/plugin-content-pages': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/theme-translations': 3.9.2 + '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@mdx-js/react': 3.1.1(@types/react@19.2.4)(react@19.2.0) + clsx: 2.1.1 + infima: 0.2.0-alpha.45 + lodash: 4.17.21 + nprogress: 0.2.0 + postcss: 8.5.6 + prism-react-renderer: 2.4.1(react@19.2.0) + prismjs: 1.30.0 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + react-router-dom: 5.3.4(react@19.2.0) + rtlcss: 4.3.0 + tslib: 2.8.1 + utility-types: 3.11.0 + transitivePeerDependencies: + - '@docusaurus/faster' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - '@types/react' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/theme-common@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/module-type-aliases': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@types/history': 4.7.11 + '@types/react': 19.2.4 + '@types/react-router-config': 5.0.11 + clsx: 2.1.1 + parse-numeric-range: 1.3.0 + prism-react-renderer: 2.4.1(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + tslib: 2.8.1 + utility-types: 3.11.0 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/theme-search-algolia@3.9.2(@algolia/client-search@5.43.0)(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(search-insights@2.17.3)(typescript@5.6.3)': + dependencies: + '@docsearch/react': 4.3.2(@algolia/client-search@5.43.0)(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(search-insights@2.17.3) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/logger': 3.9.2 + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/theme-translations': 3.9.2 + '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + algoliasearch: 5.43.0 + algoliasearch-helper: 3.26.1(algoliasearch@5.43.0) + clsx: 2.1.1 + eta: 2.2.0 + fs-extra: 11.3.2 + lodash: 4.17.21 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + tslib: 2.8.1 + utility-types: 3.11.0 + transitivePeerDependencies: + - '@algolia/client-search' + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - '@types/react' + - bufferutil + - csso + - debug + - esbuild + - lightningcss + - search-insights + - supports-color + - typescript + - uglify-js + - utf-8-validate + - webpack-cli + + '@docusaurus/theme-translations@3.9.2': + dependencies: + fs-extra: 11.3.2 + tslib: 2.8.1 + + '@docusaurus/tsconfig@3.9.2': {} + + '@docusaurus/types@3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@mdx-js/mdx': 3.1.1 + '@types/history': 4.7.11 + '@types/mdast': 4.0.4 + '@types/react': 19.2.4 + commander: 5.1.0 + joi: 17.13.3 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0)' + utility-types: 3.11.0 + webpack: 5.102.1 + webpack-merge: 5.10.0 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/utils-common@3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + tslib: 2.8.1 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - react + - react-dom + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/utils-validation@3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@docusaurus/logger': 3.9.2 + '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + fs-extra: 11.3.2 + joi: 17.13.3 + js-yaml: 4.1.1 + lodash: 4.17.21 + tslib: 2.8.1 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - react + - react-dom + - supports-color + - uglify-js + - webpack-cli + + '@docusaurus/utils@3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@docusaurus/logger': 3.9.2 + '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + escape-string-regexp: 4.0.0 + execa: 5.1.1 + file-loader: 6.2.0(webpack@5.102.1) + fs-extra: 11.3.2 + github-slugger: 1.5.0 + globby: 11.1.0 + gray-matter: 4.0.3 + jiti: 1.21.7 + js-yaml: 4.1.1 + lodash: 4.17.21 + micromatch: 4.0.8 + p-queue: 6.6.2 + prompts: 2.4.2 + resolve-pathname: 3.0.0 + tslib: 2.8.1 + url-loader: 4.1.1(file-loader@6.2.0(webpack@5.102.1))(webpack@5.102.1) + utility-types: 3.11.0 + webpack: 5.102.1 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - react + - react-dom + - supports-color + - uglify-js + - webpack-cli + + '@hapi/hoek@9.3.0': {} + + '@hapi/topo@5.1.0': + dependencies: + '@hapi/hoek': 9.3.0 + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.8 + + '@jest/types@29.6.3': + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 24.10.1 + '@types/yargs': 17.0.34 + chalk: 4.1.2 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/source-map@0.3.11': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@jsonjoy.com/base64@1.1.2(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/buffers@1.2.1(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/codegen@1.0.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/json-pack@1.21.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/base64': 1.1.2(tslib@2.8.1) + '@jsonjoy.com/buffers': 1.2.1(tslib@2.8.1) + '@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1) + '@jsonjoy.com/json-pointer': 1.0.2(tslib@2.8.1) + '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) + hyperdyperid: 1.2.0 + thingies: 2.5.0(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/json-pointer@1.0.2(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1) + '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/util@1.9.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/buffers': 1.2.1(tslib@2.8.1) + '@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1) + tslib: 2.8.1 + + '@leichtgewicht/ip-codec@2.0.5': {} + + '@mdx-js/mdx@3.1.1': + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdx': 2.0.13 + acorn: 8.15.0 + collapse-white-space: 2.1.0 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-util-scope: 1.0.0 + estree-walker: 3.0.3 + hast-util-to-jsx-runtime: 2.3.6 + markdown-extensions: 2.0.0 + recma-build-jsx: 1.0.0 + recma-jsx: 1.0.1(acorn@8.15.0) + recma-stringify: 1.0.0 + rehype-recma: 1.0.0 + remark-mdx: 3.1.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + source-map: 0.7.6 + unified: 11.0.5 + unist-util-position-from-estree: 2.0.0 + unist-util-stringify-position: 4.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0)': + dependencies: + '@types/mdx': 2.0.13 + '@types/react': 19.2.4 + react: 19.2.0 + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.1 + + '@opentelemetry/api@1.9.0': {} + + '@pnpm/config.env-replace@1.1.0': {} + + '@pnpm/network.ca-file@1.0.2': + dependencies: + graceful-fs: 4.2.10 + + '@pnpm/npm-conf@2.3.1': + dependencies: + '@pnpm/config.env-replace': 1.1.0 + '@pnpm/network.ca-file': 1.0.2 + config-chain: 1.1.13 + + '@polka/url@1.0.0-next.29': {} + + '@scalar/docusaurus@0.7.21(@docusaurus/utils@3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)': + dependencies: + '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@scalar/types': 0.4.0 + react: 19.2.0 + + '@scalar/openapi-types@0.5.1': + dependencies: + zod: 4.1.11 + + '@scalar/types@0.4.0': + dependencies: + '@scalar/openapi-types': 0.5.1 + nanoid: 5.1.5 + type-fest: 5.0.0 + zod: 4.1.11 + + '@sideway/address@4.1.5': + dependencies: + '@hapi/hoek': 9.3.0 + + '@sideway/formula@3.0.1': {} + + '@sideway/pinpoint@2.0.0': {} + + '@sinclair/typebox@0.27.8': {} + + '@sindresorhus/is@4.6.0': {} + + '@sindresorhus/is@5.6.0': {} + + '@slorber/react-helmet-async@1.3.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@babel/runtime': 7.28.4 + invariant: 2.2.4 + prop-types: 15.8.1 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + react-fast-compare: 3.2.2 + shallowequal: 1.1.0 + + '@slorber/remark-comment@1.0.0': + dependencies: + micromark-factory-space: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + + '@standard-schema/spec@1.0.0': {} + + '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + + '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + + '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + + '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + + '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + + '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + + '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + + '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + + '@svgr/babel-preset@8.1.0(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.28.5) + '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.28.5) + '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.28.5) + '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.28.5) + '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.28.5) + '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.28.5) + '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.28.5) + '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.28.5) + + '@svgr/core@8.1.0(typescript@5.6.3)': + dependencies: + '@babel/core': 7.28.5 + '@svgr/babel-preset': 8.1.0(@babel/core@7.28.5) + camelcase: 6.3.0 + cosmiconfig: 8.3.6(typescript@5.6.3) + snake-case: 3.0.4 + transitivePeerDependencies: + - supports-color + - typescript + + '@svgr/hast-util-to-babel-ast@8.0.0': + dependencies: + '@babel/types': 7.28.5 + entities: 4.5.0 + + '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.6.3))': + dependencies: + '@babel/core': 7.28.5 + '@svgr/babel-preset': 8.1.0(@babel/core@7.28.5) + '@svgr/core': 8.1.0(typescript@5.6.3) + '@svgr/hast-util-to-babel-ast': 8.0.0 + svg-parser: 2.0.4 + transitivePeerDependencies: + - supports-color + + '@svgr/plugin-svgo@8.1.0(@svgr/core@8.1.0(typescript@5.6.3))(typescript@5.6.3)': + dependencies: + '@svgr/core': 8.1.0(typescript@5.6.3) + cosmiconfig: 8.3.6(typescript@5.6.3) + deepmerge: 4.3.1 + svgo: 3.3.2 + transitivePeerDependencies: + - typescript + + '@svgr/webpack@8.1.0(typescript@5.6.3)': + dependencies: + '@babel/core': 7.28.5 + '@babel/plugin-transform-react-constant-elements': 7.27.1(@babel/core@7.28.5) + '@babel/preset-env': 7.28.5(@babel/core@7.28.5) + '@babel/preset-react': 7.28.5(@babel/core@7.28.5) + '@babel/preset-typescript': 7.28.5(@babel/core@7.28.5) + '@svgr/core': 8.1.0(typescript@5.6.3) + '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.6.3)) + '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@5.6.3))(typescript@5.6.3) + transitivePeerDependencies: + - supports-color + - typescript + + '@szmarczak/http-timer@5.0.1': + dependencies: + defer-to-connect: 2.0.1 + + '@trysound/sax@0.2.0': {} + + '@types/body-parser@1.19.6': + dependencies: + '@types/connect': 3.4.38 + '@types/node': 24.10.1 + + '@types/bonjour@3.5.13': + dependencies: + '@types/node': 24.10.1 + + '@types/connect-history-api-fallback@1.5.4': + dependencies: + '@types/express-serve-static-core': 4.19.7 + '@types/node': 24.10.1 + + '@types/connect@3.4.38': + dependencies: + '@types/node': 24.10.1 + + '@types/debug@4.1.12': + dependencies: + '@types/ms': 2.1.0 + + '@types/eslint-scope@3.7.7': + dependencies: + '@types/eslint': 9.6.1 + '@types/estree': 1.0.8 + + '@types/eslint@9.6.1': + dependencies: + '@types/estree': 1.0.8 + '@types/json-schema': 7.0.15 + + '@types/estree-jsx@1.0.5': + dependencies: + '@types/estree': 1.0.8 + + '@types/estree@1.0.8': {} + + '@types/express-serve-static-core@4.19.7': + dependencies: + '@types/node': 24.10.1 + '@types/qs': 6.14.0 + '@types/range-parser': 1.2.7 + '@types/send': 1.2.1 + + '@types/express@4.17.25': + dependencies: + '@types/body-parser': 1.19.6 + '@types/express-serve-static-core': 4.19.7 + '@types/qs': 6.14.0 + '@types/serve-static': 1.15.10 + + '@types/gtag.js@0.0.12': {} + + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/history@4.7.11': {} + + '@types/html-minifier-terser@6.1.0': {} + + '@types/http-cache-semantics@4.0.4': {} + + '@types/http-errors@2.0.5': {} + + '@types/http-proxy@1.17.17': + dependencies: + '@types/node': 24.10.1 + + '@types/istanbul-lib-coverage@2.0.6': {} + + '@types/istanbul-lib-report@3.0.3': + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + + '@types/istanbul-reports@3.0.4': + dependencies: + '@types/istanbul-lib-report': 3.0.3 + + '@types/json-schema@7.0.15': {} + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/mdx@2.0.13': {} + + '@types/mime@1.3.5': {} + + '@types/ms@2.1.0': {} + + '@types/node-forge@1.3.14': + dependencies: + '@types/node': 24.10.1 + + '@types/node@17.0.45': {} + + '@types/node@24.10.1': + dependencies: + undici-types: 7.16.0 + + '@types/prismjs@1.26.5': {} + + '@types/qs@6.14.0': {} + + '@types/range-parser@1.2.7': {} + + '@types/react-router-config@5.0.11': + dependencies: + '@types/history': 4.7.11 + '@types/react': 19.2.4 + '@types/react-router': 5.1.20 + + '@types/react-router-dom@5.3.3': + dependencies: + '@types/history': 4.7.11 + '@types/react': 19.2.4 + '@types/react-router': 5.1.20 + + '@types/react-router@5.1.20': + dependencies: + '@types/history': 4.7.11 + '@types/react': 19.2.4 + + '@types/react@19.2.4': + dependencies: + csstype: 3.1.3 + + '@types/retry@0.12.2': {} + + '@types/sax@1.2.7': + dependencies: + '@types/node': 17.0.45 + + '@types/send@0.17.6': + dependencies: + '@types/mime': 1.3.5 + '@types/node': 24.10.1 + + '@types/send@1.2.1': + dependencies: + '@types/node': 24.10.1 + + '@types/serve-index@1.9.4': + dependencies: + '@types/express': 4.17.25 + + '@types/serve-static@1.15.10': + dependencies: + '@types/http-errors': 2.0.5 + '@types/node': 24.10.1 + '@types/send': 0.17.6 + + '@types/sockjs@0.3.36': + dependencies: + '@types/node': 24.10.1 + + '@types/unist@2.0.11': {} + + '@types/unist@3.0.3': {} + + '@types/ws@8.18.1': + dependencies: + '@types/node': 24.10.1 + + '@types/yargs-parser@21.0.3': {} + + '@types/yargs@17.0.34': + dependencies: + '@types/yargs-parser': 21.0.3 + + '@ungap/structured-clone@1.3.0': {} + + '@vercel/oidc@3.0.3': {} + + '@webassemblyjs/ast@1.14.1': + dependencies: + '@webassemblyjs/helper-numbers': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + + '@webassemblyjs/floating-point-hex-parser@1.13.2': {} + + '@webassemblyjs/helper-api-error@1.13.2': {} + + '@webassemblyjs/helper-buffer@1.14.1': {} + + '@webassemblyjs/helper-numbers@1.13.2': + dependencies: + '@webassemblyjs/floating-point-hex-parser': 1.13.2 + '@webassemblyjs/helper-api-error': 1.13.2 + '@xtuc/long': 4.2.2 + + '@webassemblyjs/helper-wasm-bytecode@1.13.2': {} + + '@webassemblyjs/helper-wasm-section@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/wasm-gen': 1.14.1 + + '@webassemblyjs/ieee754@1.13.2': + dependencies: + '@xtuc/ieee754': 1.2.0 + + '@webassemblyjs/leb128@1.13.2': + dependencies: + '@xtuc/long': 4.2.2 + + '@webassemblyjs/utf8@1.13.2': {} + + '@webassemblyjs/wasm-edit@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/helper-wasm-section': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-opt': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + '@webassemblyjs/wast-printer': 1.14.1 + + '@webassemblyjs/wasm-gen@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + + '@webassemblyjs/wasm-opt@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + + '@webassemblyjs/wasm-parser@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-api-error': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + + '@webassemblyjs/wast-printer@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@xtuc/long': 4.2.2 + + '@xtuc/ieee754@1.2.0': {} + + '@xtuc/long@4.2.2': {} + + accepts@1.3.8: + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + + acorn-import-phases@1.0.4(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + + acorn-jsx@5.3.2(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + + acorn-walk@8.3.4: + dependencies: + acorn: 8.15.0 + + acorn@8.15.0: {} + + address@1.2.2: {} + + aggregate-error@3.1.0: + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + + ai@5.0.93(zod@4.1.12): + dependencies: + '@ai-sdk/gateway': 2.0.9(zod@4.1.12) + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.17(zod@4.1.12) + '@opentelemetry/api': 1.9.0 + zod: 4.1.12 + + ajv-formats@2.1.1(ajv@8.17.1): + optionalDependencies: + ajv: 8.17.1 + + ajv-keywords@3.5.2(ajv@6.12.6): + dependencies: + ajv: 6.12.6 + + ajv-keywords@5.1.0(ajv@8.17.1): + dependencies: + ajv: 8.17.1 + fast-deep-equal: 3.1.3 + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ajv@8.17.1: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.0 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + algoliasearch-helper@3.26.1(algoliasearch@5.43.0): + dependencies: + '@algolia/events': 4.0.1 + algoliasearch: 5.43.0 + + algoliasearch@5.43.0: + dependencies: + '@algolia/abtesting': 1.9.0 + '@algolia/client-abtesting': 5.43.0 + '@algolia/client-analytics': 5.43.0 + '@algolia/client-common': 5.43.0 + '@algolia/client-insights': 5.43.0 + '@algolia/client-personalization': 5.43.0 + '@algolia/client-query-suggestions': 5.43.0 + '@algolia/client-search': 5.43.0 + '@algolia/ingestion': 1.43.0 + '@algolia/monitoring': 1.43.0 + '@algolia/recommend': 5.43.0 + '@algolia/requester-browser-xhr': 5.43.0 + '@algolia/requester-fetch': 5.43.0 + '@algolia/requester-node-http': 5.43.0 + + ansi-align@3.0.1: + dependencies: + string-width: 4.2.3 + + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + + ansi-html-community@0.0.8: {} + + ansi-regex@5.0.1: {} + + ansi-regex@6.2.2: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.3: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + arg@5.0.2: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + array-flatten@1.1.1: {} + + array-union@2.1.0: {} + + astring@1.9.0: {} + + autoprefixer@10.4.22(postcss@8.5.6): + dependencies: + browserslist: 4.28.0 + caniuse-lite: 1.0.30001754 + fraction.js: 5.3.4 + normalize-range: 0.1.2 + picocolors: 1.1.1 + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + babel-loader@9.2.1(@babel/core@7.28.5)(webpack@5.102.1): + dependencies: + '@babel/core': 7.28.5 + find-cache-dir: 4.0.0 + schema-utils: 4.3.3 + webpack: 5.102.1 + + babel-plugin-dynamic-import-node@2.3.3: + dependencies: + object.assign: 4.1.7 + + babel-plugin-polyfill-corejs2@0.4.14(@babel/core@7.28.5): + dependencies: + '@babel/compat-data': 7.28.5 + '@babel/core': 7.28.5 + '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.5) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.28.5): + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.5) + core-js-compat: 3.46.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-regenerator@0.6.5(@babel/core@7.28.5): + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + + bail@2.0.2: {} + + balanced-match@1.0.2: {} + + baseline-browser-mapping@2.8.28: {} + + batch@0.6.1: {} + + big.js@5.2.2: {} + + binary-extensions@2.3.0: {} + + body-parser@1.20.3: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.13.0 + raw-body: 2.5.2 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + bonjour-service@1.3.0: + dependencies: + fast-deep-equal: 3.1.3 + multicast-dns: 7.2.5 + + boolbase@1.0.0: {} + + boxen@6.2.1: + dependencies: + ansi-align: 3.0.1 + camelcase: 6.3.0 + chalk: 4.1.2 + cli-boxes: 3.0.0 + string-width: 5.1.2 + type-fest: 2.19.0 + widest-line: 4.0.1 + wrap-ansi: 8.1.0 + + boxen@7.1.1: + dependencies: + ansi-align: 3.0.1 + camelcase: 7.0.1 + chalk: 5.6.2 + cli-boxes: 3.0.0 + string-width: 5.1.2 + type-fest: 2.19.0 + widest-line: 4.0.1 + wrap-ansi: 8.1.0 + + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.28.0: + dependencies: + baseline-browser-mapping: 2.8.28 + caniuse-lite: 1.0.30001754 + electron-to-chromium: 1.5.250 + node-releases: 2.0.27 + update-browserslist-db: 1.1.4(browserslist@4.28.0) + + buffer-from@1.1.2: {} + + bundle-name@4.1.0: + dependencies: + run-applescript: 7.1.0 + + bytes@3.0.0: {} + + bytes@3.1.2: {} + + cacheable-lookup@7.0.0: {} + + cacheable-request@10.2.14: + dependencies: + '@types/http-cache-semantics': 4.0.4 + get-stream: 6.0.1 + http-cache-semantics: 4.2.0 + keyv: 4.5.4 + mimic-response: 4.0.0 + normalize-url: 8.1.0 + responselike: 3.0.0 + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.8: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + callsites@3.1.0: {} + + camel-case@4.1.2: + dependencies: + pascal-case: 3.1.2 + tslib: 2.8.1 + + camelcase@6.3.0: {} + + camelcase@7.0.1: {} + + caniuse-api@3.0.0: + dependencies: + browserslist: 4.28.0 + caniuse-lite: 1.0.30001754 + lodash.memoize: 4.1.2 + lodash.uniq: 4.5.0 + + caniuse-lite@1.0.30001754: {} + + ccount@2.0.1: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@5.6.2: {} + + char-regex@1.0.2: {} + + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + + character-entities@2.0.2: {} + + character-reference-invalid@2.0.1: {} + + cheerio-select@2.1.0: + dependencies: + boolbase: 1.0.0 + css-select: 5.2.2 + css-what: 6.2.2 + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + + cheerio@1.0.0-rc.12: + dependencies: + cheerio-select: 2.1.0 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + domutils: 3.2.2 + htmlparser2: 8.0.2 + parse5: 7.3.0 + parse5-htmlparser2-tree-adapter: 7.1.0 + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chrome-trace-event@1.0.4: {} + + ci-info@3.9.0: {} + + clean-css@5.3.3: + dependencies: + source-map: 0.6.1 + + clean-stack@2.2.0: {} + + cli-boxes@3.0.0: {} + + cli-table3@0.6.5: + dependencies: + string-width: 4.2.3 + optionalDependencies: + '@colors/colors': 1.5.0 + + clone-deep@4.0.1: + dependencies: + is-plain-object: 2.0.4 + kind-of: 6.0.3 + shallow-clone: 3.0.1 + + clsx@2.1.1: {} + + collapse-white-space@2.1.0: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + colord@2.9.3: {} + + colorette@2.0.20: {} + + combine-promises@1.2.0: {} + + comma-separated-tokens@2.0.3: {} + + commander@10.0.1: {} + + commander@2.20.3: {} + + commander@5.1.0: {} + + commander@7.2.0: {} + + commander@8.3.0: {} + + common-path-prefix@3.0.0: {} + + compressible@2.0.18: + dependencies: + mime-db: 1.54.0 + + compression@1.8.1: + dependencies: + bytes: 3.1.2 + compressible: 2.0.18 + debug: 2.6.9 + negotiator: 0.6.4 + on-headers: 1.1.0 + safe-buffer: 5.2.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + concat-map@0.0.1: {} + + config-chain@1.1.13: + dependencies: + ini: 1.3.8 + proto-list: 1.2.4 + + configstore@6.0.0: + dependencies: + dot-prop: 6.0.1 + graceful-fs: 4.2.11 + unique-string: 3.0.0 + write-file-atomic: 3.0.3 + xdg-basedir: 5.1.0 + + connect-history-api-fallback@2.0.0: {} + + consola@3.4.2: {} + + content-disposition@0.5.2: {} + + content-disposition@0.5.4: + dependencies: + safe-buffer: 5.2.1 + + content-type@1.0.5: {} + + convert-source-map@2.0.0: {} + + cookie-signature@1.0.6: {} + + cookie@0.7.1: {} + + copy-webpack-plugin@11.0.0(webpack@5.102.1): + dependencies: + fast-glob: 3.3.3 + glob-parent: 6.0.2 + globby: 13.2.2 + normalize-path: 3.0.0 + schema-utils: 4.3.3 + serialize-javascript: 6.0.2 + webpack: 5.102.1 + + core-js-compat@3.46.0: + dependencies: + browserslist: 4.28.0 + + core-js-pure@3.46.0: {} + + core-js@3.46.0: {} + + core-util-is@1.0.3: {} + + cosmiconfig@8.3.6(typescript@5.6.3): + dependencies: + import-fresh: 3.3.1 + js-yaml: 4.1.1 + parse-json: 5.2.0 + path-type: 4.0.0 + optionalDependencies: + typescript: 5.6.3 + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + crypto-random-string@4.0.0: + dependencies: + type-fest: 1.4.0 + + css-blank-pseudo@7.0.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 7.1.0 + + css-declaration-sorter@7.3.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + css-has-pseudo@7.0.3(postcss@8.5.6): + dependencies: + '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.0) + postcss: 8.5.6 + postcss-selector-parser: 7.1.0 + postcss-value-parser: 4.2.0 + + css-loader@6.11.0(webpack@5.102.1): + dependencies: + icss-utils: 5.1.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-modules-extract-imports: 3.1.0(postcss@8.5.6) + postcss-modules-local-by-default: 4.2.0(postcss@8.5.6) + postcss-modules-scope: 3.2.1(postcss@8.5.6) + postcss-modules-values: 4.0.0(postcss@8.5.6) + postcss-value-parser: 4.2.0 + semver: 7.7.3 + optionalDependencies: + webpack: 5.102.1 + + css-minimizer-webpack-plugin@5.0.1(clean-css@5.3.3)(webpack@5.102.1): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + cssnano: 6.1.2(postcss@8.5.6) + jest-worker: 29.7.0 + postcss: 8.5.6 + schema-utils: 4.3.3 + serialize-javascript: 6.0.2 + webpack: 5.102.1 + optionalDependencies: + clean-css: 5.3.3 + + css-prefers-color-scheme@10.0.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + css-select@4.3.0: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 4.3.1 + domutils: 2.8.0 + nth-check: 2.1.1 + + css-select@5.2.2: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + + css-tree@2.2.1: + dependencies: + mdn-data: 2.0.28 + source-map-js: 1.2.1 + + css-tree@2.3.1: + dependencies: + mdn-data: 2.0.30 + source-map-js: 1.2.1 + + css-what@6.2.2: {} + + cssdb@8.4.2: {} + + cssesc@3.0.0: {} + + cssnano-preset-advanced@6.1.2(postcss@8.5.6): + dependencies: + autoprefixer: 10.4.22(postcss@8.5.6) + browserslist: 4.28.0 + cssnano-preset-default: 6.1.2(postcss@8.5.6) + postcss: 8.5.6 + postcss-discard-unused: 6.0.5(postcss@8.5.6) + postcss-merge-idents: 6.0.3(postcss@8.5.6) + postcss-reduce-idents: 6.0.3(postcss@8.5.6) + postcss-zindex: 6.0.2(postcss@8.5.6) + + cssnano-preset-default@6.1.2(postcss@8.5.6): + dependencies: + browserslist: 4.28.0 + css-declaration-sorter: 7.3.0(postcss@8.5.6) + cssnano-utils: 4.0.2(postcss@8.5.6) + postcss: 8.5.6 + postcss-calc: 9.0.1(postcss@8.5.6) + postcss-colormin: 6.1.0(postcss@8.5.6) + postcss-convert-values: 6.1.0(postcss@8.5.6) + postcss-discard-comments: 6.0.2(postcss@8.5.6) + postcss-discard-duplicates: 6.0.3(postcss@8.5.6) + postcss-discard-empty: 6.0.3(postcss@8.5.6) + postcss-discard-overridden: 6.0.2(postcss@8.5.6) + postcss-merge-longhand: 6.0.5(postcss@8.5.6) + postcss-merge-rules: 6.1.1(postcss@8.5.6) + postcss-minify-font-values: 6.1.0(postcss@8.5.6) + postcss-minify-gradients: 6.0.3(postcss@8.5.6) + postcss-minify-params: 6.1.0(postcss@8.5.6) + postcss-minify-selectors: 6.0.4(postcss@8.5.6) + postcss-normalize-charset: 6.0.2(postcss@8.5.6) + postcss-normalize-display-values: 6.0.2(postcss@8.5.6) + postcss-normalize-positions: 6.0.2(postcss@8.5.6) + postcss-normalize-repeat-style: 6.0.2(postcss@8.5.6) + postcss-normalize-string: 6.0.2(postcss@8.5.6) + postcss-normalize-timing-functions: 6.0.2(postcss@8.5.6) + postcss-normalize-unicode: 6.1.0(postcss@8.5.6) + postcss-normalize-url: 6.0.2(postcss@8.5.6) + postcss-normalize-whitespace: 6.0.2(postcss@8.5.6) + postcss-ordered-values: 6.0.2(postcss@8.5.6) + postcss-reduce-initial: 6.1.0(postcss@8.5.6) + postcss-reduce-transforms: 6.0.2(postcss@8.5.6) + postcss-svgo: 6.0.3(postcss@8.5.6) + postcss-unique-selectors: 6.0.4(postcss@8.5.6) + + cssnano-utils@4.0.2(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + cssnano@6.1.2(postcss@8.5.6): + dependencies: + cssnano-preset-default: 6.1.2(postcss@8.5.6) + lilconfig: 3.1.3 + postcss: 8.5.6 + + csso@5.0.5: + dependencies: + css-tree: 2.2.1 + + csstype@3.1.3: {} + + debounce@1.2.1: {} + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decode-named-character-reference@1.2.0: + dependencies: + character-entities: 2.0.2 + + decompress-response@6.0.0: + dependencies: + mimic-response: 3.1.0 + + deep-extend@0.6.0: {} + + deepmerge@4.3.1: {} + + default-browser-id@5.0.0: {} + + default-browser@5.3.0: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.0 + + defer-to-connect@2.0.1: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-lazy-prop@2.0.0: {} + + define-lazy-prop@3.0.0: {} + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + depd@1.1.2: {} + + depd@2.0.0: {} + + dequal@2.0.3: {} + + destroy@1.2.0: {} + + detect-node@2.1.0: {} + + detect-port@1.6.1: + dependencies: + address: 1.2.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + dns-packet@5.6.1: + dependencies: + '@leichtgewicht/ip-codec': 2.0.5 + + dom-converter@0.2.0: + dependencies: + utila: 0.4.0 + + dom-serializer@1.4.1: + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + entities: 2.2.0 + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@4.3.1: + dependencies: + domelementtype: 2.3.0 + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@2.8.0: + dependencies: + dom-serializer: 1.4.1 + domelementtype: 2.3.0 + domhandler: 4.3.1 + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dot-case@3.0.4: + dependencies: + no-case: 3.0.4 + tslib: 2.8.1 + + dot-prop@6.0.1: + dependencies: + is-obj: 2.0.0 + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + duplexer@0.1.2: {} + + eastasianwidth@0.2.0: {} + + ee-first@1.1.1: {} + + electron-to-chromium@1.5.250: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + emojilib@2.4.0: {} + + emojis-list@3.0.0: {} + + emoticon@4.1.0: {} + + encodeurl@1.0.2: {} + + encodeurl@2.0.0: {} + + enhanced-resolve@5.18.3: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.0 + + entities@2.2.0: {} + + entities@4.5.0: {} + + entities@6.0.1: {} + + error-ex@1.3.4: + dependencies: + is-arrayish: 0.2.1 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-module-lexer@1.7.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + esast-util-from-estree@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + unist-util-position-from-estree: 2.0.0 + + esast-util-from-js@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + acorn: 8.15.0 + esast-util-from-estree: 2.0.0 + vfile-message: 4.0.3 + + escalade@3.2.0: {} + + escape-goat@4.0.0: {} + + escape-html@1.0.3: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@4.0.0: {} + + escape-string-regexp@5.0.0: {} + + eslint-scope@5.1.1: + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + + esprima@4.0.1: {} + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@4.3.0: {} + + estraverse@5.3.0: {} + + estree-util-attach-comments@3.0.0: + dependencies: + '@types/estree': 1.0.8 + + estree-util-build-jsx@3.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-walker: 3.0.3 + + estree-util-is-identifier-name@3.0.0: {} + + estree-util-scope@1.0.0: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + + estree-util-to-js@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + astring: 1.9.0 + source-map: 0.7.6 + + estree-util-value-to-estree@3.5.0: + dependencies: + '@types/estree': 1.0.8 + + estree-util-visit@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/unist': 3.0.3 + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + + esutils@2.0.3: {} + + eta@2.2.0: {} + + etag@1.8.1: {} + + eval@0.1.8: + dependencies: + '@types/node': 24.10.1 + require-like: 0.1.2 + + eventemitter3@4.0.7: {} + + events@3.3.0: {} + + eventsource-parser@3.0.6: {} + + execa@5.1.1: + dependencies: + cross-spawn: 7.0.6 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + + express@4.21.2: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.3 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.7.1 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.3.1 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.3 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.12 + proxy-addr: 2.0.7 + qs: 6.13.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.19.0 + serve-static: 1.16.2 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + + extend@3.0.2: {} + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-uri@3.1.0: {} + + fastq@1.19.1: + dependencies: + reusify: 1.1.0 + + fault@2.0.1: + dependencies: + format: 0.2.2 + + faye-websocket@0.11.4: + dependencies: + websocket-driver: 0.7.4 + + feed@4.2.2: + dependencies: + xml-js: 1.6.11 + + figures@3.2.0: + dependencies: + escape-string-regexp: 1.0.5 + + file-loader@6.2.0(webpack@5.102.1): + dependencies: + loader-utils: 2.0.4 + schema-utils: 3.3.0 + webpack: 5.102.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + finalhandler@1.3.1: + dependencies: + debug: 2.6.9 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + find-cache-dir@4.0.0: + dependencies: + common-path-prefix: 3.0.0 + pkg-dir: 7.0.0 + + find-up@6.3.0: + dependencies: + locate-path: 7.2.0 + path-exists: 5.0.0 + + flat@5.0.2: {} + + follow-redirects@1.15.11: {} + + form-data-encoder@2.1.4: {} + + format@0.2.2: {} + + forwarded@0.2.0: {} + + fraction.js@5.3.4: {} + + fresh@0.5.2: {} + + fs-extra@11.3.2: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.0 + universalify: 2.0.1 + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + gensync@1.0.0-beta.2: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-own-enumerable-property-symbols@3.0.2: {} + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-stream@6.0.1: {} + + github-slugger@1.5.0: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob-to-regex.js@1.2.0(tslib@2.8.1): + dependencies: + tslib: 2.8.1 + + glob-to-regexp@0.4.1: {} + + global-dirs@3.0.1: + dependencies: + ini: 2.0.0 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + globby@13.2.2: + dependencies: + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 4.0.0 + + gopd@1.2.0: {} + + got@12.6.1: + dependencies: + '@sindresorhus/is': 5.6.0 + '@szmarczak/http-timer': 5.0.1 + cacheable-lookup: 7.0.0 + cacheable-request: 10.2.14 + decompress-response: 6.0.0 + form-data-encoder: 2.1.4 + get-stream: 6.0.1 + http2-wrapper: 2.2.1 + lowercase-keys: 3.0.0 + p-cancelable: 3.0.0 + responselike: 3.0.0 + + graceful-fs@4.2.10: {} + + graceful-fs@4.2.11: {} + + gray-matter@4.0.3: + dependencies: + js-yaml: 3.14.1 + kind-of: 6.0.3 + section-matter: 1.0.0 + strip-bom-string: 1.0.0 + + gzip-size@6.0.0: + dependencies: + duplexer: 0.1.2 + + handle-thing@2.0.1: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-symbols@1.1.0: {} + + has-yarn@3.0.0: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + hast-util-from-parse5@8.0.3: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + devlop: 1.1.0 + hastscript: 9.0.1 + property-information: 7.1.0 + vfile: 6.0.3 + vfile-location: 5.0.3 + web-namespaces: 2.0.1 + + hast-util-parse-selector@4.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-raw@9.1.0: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + '@ungap/structured-clone': 1.3.0 + hast-util-from-parse5: 8.0.3 + hast-util-to-parse5: 8.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.0 + parse5: 7.3.0 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-to-estree@3.1.3: + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-attach-comments: 3.0.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.19 + unist-util-position: 5.0.0 + zwitch: 2.0.4 + transitivePeerDependencies: + - supports-color + + hast-util-to-jsx-runtime@2.3.6: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.19 + unist-util-position: 5.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + hast-util-to-parse5@8.0.0: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + property-information: 6.5.0 + space-separated-tokens: 2.0.2 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hastscript@9.0.1: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + hast-util-parse-selector: 4.0.0 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + + he@1.2.0: {} + + history@4.10.1: + dependencies: + '@babel/runtime': 7.28.4 + loose-envify: 1.4.0 + resolve-pathname: 3.0.0 + tiny-invariant: 1.3.3 + tiny-warning: 1.0.3 + value-equal: 1.0.1 + + hoist-non-react-statics@3.3.2: + dependencies: + react-is: 16.13.1 + + hpack.js@2.1.6: + dependencies: + inherits: 2.0.4 + obuf: 1.1.2 + readable-stream: 2.3.8 + wbuf: 1.7.3 + + html-escaper@2.0.2: {} + + html-minifier-terser@6.1.0: + dependencies: + camel-case: 4.1.2 + clean-css: 5.3.3 + commander: 8.3.0 + he: 1.2.0 + param-case: 3.0.4 + relateurl: 0.2.7 + terser: 5.44.1 + + html-minifier-terser@7.2.0: + dependencies: + camel-case: 4.1.2 + clean-css: 5.3.3 + commander: 10.0.1 + entities: 4.5.0 + param-case: 3.0.4 + relateurl: 0.2.7 + terser: 5.44.1 + + html-tags@3.3.1: {} + + html-void-elements@3.0.0: {} + + html-webpack-plugin@5.6.4(webpack@5.102.1): + dependencies: + '@types/html-minifier-terser': 6.1.0 + html-minifier-terser: 6.1.0 + lodash: 4.17.21 + pretty-error: 4.0.0 + tapable: 2.3.0 + optionalDependencies: + webpack: 5.102.1 + + htmlparser2@6.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + domutils: 2.8.0 + entities: 2.2.0 + + htmlparser2@8.0.2: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + entities: 4.5.0 + + http-cache-semantics@4.2.0: {} + + http-deceiver@1.2.7: {} + + http-errors@1.6.3: + dependencies: + depd: 1.1.2 + inherits: 2.0.3 + setprototypeof: 1.1.0 + statuses: 1.5.0 + + http-errors@2.0.0: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + + http-parser-js@0.5.10: {} + + http-proxy-middleware@2.0.9(@types/express@4.17.25): + dependencies: + '@types/http-proxy': 1.17.17 + http-proxy: 1.18.1 + is-glob: 4.0.3 + is-plain-obj: 3.0.0 + micromatch: 4.0.8 + optionalDependencies: + '@types/express': 4.17.25 + transitivePeerDependencies: + - debug + + http-proxy@1.18.1: + dependencies: + eventemitter3: 4.0.7 + follow-redirects: 1.15.11 + requires-port: 1.0.0 + transitivePeerDependencies: + - debug + + http2-wrapper@2.2.1: + dependencies: + quick-lru: 5.1.1 + resolve-alpn: 1.2.1 + + human-signals@2.1.0: {} + + hyperdyperid@1.2.0: {} + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + icss-utils@5.1.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + ignore@5.3.2: {} + + image-size@2.0.2: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + import-lazy@4.0.0: {} + + imurmurhash@0.1.4: {} + + indent-string@4.0.0: {} + + infima@0.2.0-alpha.45: {} + + inherits@2.0.3: {} + + inherits@2.0.4: {} + + ini@1.3.8: {} + + ini@2.0.0: {} + + inline-style-parser@0.2.6: {} + + invariant@2.2.4: + dependencies: + loose-envify: 1.4.0 + + ipaddr.js@1.9.1: {} + + ipaddr.js@2.2.0: {} + + is-alphabetical@2.0.1: {} + + is-alphanumerical@2.0.1: + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + + is-arrayish@0.2.1: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-ci@3.0.1: + dependencies: + ci-info: 3.9.0 + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-decimal@2.0.1: {} + + is-docker@2.2.1: {} + + is-docker@3.0.0: {} + + is-extendable@0.1.1: {} + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-hexadecimal@2.0.1: {} + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + + is-installed-globally@0.4.0: + dependencies: + global-dirs: 3.0.1 + is-path-inside: 3.0.3 + + is-network-error@1.3.0: {} + + is-npm@6.1.0: {} + + is-number@7.0.0: {} + + is-obj@1.0.1: {} + + is-obj@2.0.0: {} + + is-path-inside@3.0.3: {} + + is-plain-obj@3.0.0: {} + + is-plain-obj@4.1.0: {} + + is-plain-object@2.0.4: + dependencies: + isobject: 3.0.1 + + is-regexp@1.0.0: {} + + is-stream@2.0.1: {} + + is-typedarray@1.0.0: {} + + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 + + is-wsl@3.1.0: + dependencies: + is-inside-container: 1.0.0 + + is-yarn-global@0.4.1: {} + + isarray@0.0.1: {} + + isarray@1.0.0: {} + + isexe@2.0.0: {} + + isobject@3.0.1: {} + + jest-util@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/node': 24.10.1 + chalk: 4.1.2 + ci-info: 3.9.0 + graceful-fs: 4.2.11 + picomatch: 2.3.1 + + jest-worker@27.5.1: + dependencies: + '@types/node': 24.10.1 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + jest-worker@29.7.0: + dependencies: + '@types/node': 24.10.1 + jest-util: 29.7.0 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + jiti@1.21.7: {} + + joi@17.13.3: + dependencies: + '@hapi/hoek': 9.3.0 + '@hapi/topo': 5.1.0 + '@sideway/address': 4.1.5 + '@sideway/formula': 3.0.1 + '@sideway/pinpoint': 2.0.0 + + js-tokens@4.0.0: {} + + js-yaml@3.14.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-parse-even-better-errors@2.3.1: {} + + json-schema-traverse@0.4.1: {} + + json-schema-traverse@1.0.0: {} + + json-schema@0.4.0: {} + + json5@2.2.3: {} + + jsonfile@6.2.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + kind-of@6.0.3: {} + + kleur@3.0.3: {} + + latest-version@7.0.0: + dependencies: + package-json: 8.1.1 + + launch-editor@2.12.0: + dependencies: + picocolors: 1.1.1 + shell-quote: 1.8.3 + + leven@3.1.0: {} + + lilconfig@3.1.3: {} + + lines-and-columns@1.2.4: {} + + loader-runner@4.3.1: {} + + loader-utils@2.0.4: + dependencies: + big.js: 5.2.2 + emojis-list: 3.0.0 + json5: 2.2.3 + + locate-path@7.2.0: + dependencies: + p-locate: 6.0.0 + + lodash.debounce@4.0.8: {} + + lodash.memoize@4.1.2: {} + + lodash.uniq@4.5.0: {} + + lodash@4.17.21: {} + + longest-streak@3.1.0: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + lower-case@2.0.2: + dependencies: + tslib: 2.8.1 + + lowercase-keys@3.0.0: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + markdown-extensions@2.0.0: {} + + markdown-table@2.0.0: + dependencies: + repeat-string: 1.6.1 + + markdown-table@3.0.4: {} + + marked@16.4.2: {} + + math-intrinsics@1.1.0: {} + + mdast-util-directive@3.1.0: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-visit-parents: 6.0.2 + transitivePeerDependencies: + - supports-color + + mdast-util-find-and-replace@3.0.2: + dependencies: + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + mdast-util-from-markdown@2.0.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.2.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-frontmatter@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + escape-string-regexp: 5.0.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + micromark-extension-frontmatter: 2.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.2 + micromark-util-character: 2.1.1 + + mdast-util-gfm-footnote@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + micromark-util-normalize-identifier: 2.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm@3.1.0: + dependencies: + mdast-util-from-markdown: 2.0.2 + mdast-util-gfm-autolink-literal: 2.0.1 + mdast-util-gfm-footnote: 2.1.0 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-expression@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-jsx@3.2.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx@3.0.0: + dependencies: + mdast-util-from-markdown: 2.0.2 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdxjs-esm@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.1 + + mdast-util-to-hast@13.2.0: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + + mdast-util-to-markdown@2.1.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.0.0 + zwitch: 2.0.4 + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + + mdn-data@2.0.28: {} + + mdn-data@2.0.30: {} + + media-typer@0.3.0: {} + + memfs@4.51.0: + dependencies: + '@jsonjoy.com/json-pack': 1.21.0(tslib@2.8.1) + '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) + glob-to-regex.js: 1.2.0(tslib@2.8.1) + thingies: 2.5.0(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) + tslib: 2.8.1 + + merge-descriptors@1.0.3: {} + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + methods@1.1.2: {} + + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.2.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-directive@3.0.2: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + parse-entities: 4.0.2 + + micromark-extension-frontmatter@2.0.0: + dependencies: + fault: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-table@2.1.1: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.1 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-expression@3.0.1: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-jsx@3.0.2: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 + + micromark-extension-mdx-md@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-mdxjs-esm@3.0.0: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 + + micromark-extension-mdxjs@3.0.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + micromark-extension-mdx-expression: 3.0.1 + micromark-extension-mdx-jsx: 3.0.2 + micromark-extension-mdx-md: 2.0.0 + micromark-extension-mdxjs-esm: 3.0.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-mdx-expression@2.0.3: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 + + micromark-factory-space@1.1.0: + dependencies: + micromark-util-character: 1.2.0 + micromark-util-types: 1.1.0 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-character@1.2.0: + dependencies: + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.2.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + + micromark-util-encode@2.0.1: {} + + micromark-util-events-to-acorn@2.0.3: + dependencies: + '@types/estree': 1.0.8 + '@types/unist': 3.0.3 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-symbol@1.1.0: {} + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@1.1.0: {} + + micromark-util-types@2.0.2: {} + + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.12 + debug: 4.4.3 + decode-named-character-reference: 1.2.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.33.0: {} + + mime-db@1.52.0: {} + + mime-db@1.54.0: {} + + mime-types@2.1.18: + dependencies: + mime-db: 1.33.0 + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime-types@3.0.1: + dependencies: + mime-db: 1.54.0 + + mime@1.6.0: {} + + mimic-fn@2.1.0: {} + + mimic-response@3.1.0: {} + + mimic-response@4.0.0: {} + + mini-css-extract-plugin@2.9.4(webpack@5.102.1): + dependencies: + schema-utils: 4.3.3 + tapable: 2.3.0 + webpack: 5.102.1 + + minimalistic-assert@1.0.1: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.12 + + minimist@1.2.8: {} + + mrmime@2.0.1: {} + + ms@2.0.0: {} + + ms@2.1.3: {} + + multicast-dns@7.2.5: + dependencies: + dns-packet: 5.6.1 + thunky: 1.1.0 + + nanoid@3.3.11: {} + + nanoid@5.1.5: {} + + negotiator@0.6.3: {} + + negotiator@0.6.4: {} + + neo-async@2.6.2: {} + + no-case@3.0.4: + dependencies: + lower-case: 2.0.2 + tslib: 2.8.1 + + node-emoji@2.2.0: + dependencies: + '@sindresorhus/is': 4.6.0 + char-regex: 1.0.2 + emojilib: 2.4.0 + skin-tone: 2.0.0 + + node-forge@1.3.1: {} + + node-releases@2.0.27: {} + + normalize-path@3.0.0: {} + + normalize-range@0.1.2: {} + + normalize-url@8.1.0: {} + + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + + nprogress@0.2.0: {} + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + null-loader@4.0.1(webpack@5.102.1): + dependencies: + loader-utils: 2.0.4 + schema-utils: 3.3.0 + webpack: 5.102.1 + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + object-keys@1.1.1: {} + + object.assign@4.1.7: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + has-symbols: 1.1.0 + object-keys: 1.1.1 + + obuf@1.1.2: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + on-headers@1.1.0: {} + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + open@10.2.0: + dependencies: + default-browser: 5.3.0 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + wsl-utils: 0.1.0 + + open@8.4.2: + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + + opener@1.5.2: {} + + p-cancelable@3.0.0: {} + + p-finally@1.0.0: {} + + p-limit@4.0.0: + dependencies: + yocto-queue: 1.2.2 + + p-locate@6.0.0: + dependencies: + p-limit: 4.0.0 + + p-map@4.0.0: + dependencies: + aggregate-error: 3.1.0 + + p-queue@6.6.2: + dependencies: + eventemitter3: 4.0.7 + p-timeout: 3.2.0 + + p-retry@6.2.1: + dependencies: + '@types/retry': 0.12.2 + is-network-error: 1.3.0 + retry: 0.13.1 + + p-timeout@3.2.0: + dependencies: + p-finally: 1.0.0 + + package-json@8.1.1: + dependencies: + got: 12.6.1 + registry-auth-token: 5.1.0 + registry-url: 6.0.1 + semver: 7.7.3 + + param-case@3.0.4: + dependencies: + dot-case: 3.0.4 + tslib: 2.8.1 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-entities@4.0.2: + dependencies: + '@types/unist': 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.2.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.27.1 + error-ex: 1.3.4 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + parse-numeric-range@1.3.0: {} + + parse5-htmlparser2-tree-adapter@7.1.0: + dependencies: + domhandler: 5.0.3 + parse5: 7.3.0 + + parse5@7.3.0: + dependencies: + entities: 6.0.1 + + parseurl@1.3.3: {} + + pascal-case@3.1.2: + dependencies: + no-case: 3.0.4 + tslib: 2.8.1 + + path-exists@5.0.0: {} + + path-is-inside@1.0.2: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + path-to-regexp@0.1.12: {} + + path-to-regexp@1.9.0: + dependencies: + isarray: 0.0.1 + + path-to-regexp@3.3.0: {} + + path-type@4.0.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + pkg-dir@7.0.0: + dependencies: + find-up: 6.3.0 + + postcss-attribute-case-insensitive@7.0.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 7.1.0 + + postcss-calc@9.0.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 6.1.2 + postcss-value-parser: 4.2.0 + + postcss-clamp@4.1.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-color-functional-notation@7.0.12(postcss@8.5.6): + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + + postcss-color-hex-alpha@10.0.0(postcss@8.5.6): + dependencies: + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-color-rebeccapurple@10.0.0(postcss@8.5.6): + dependencies: + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-colormin@6.1.0(postcss@8.5.6): + dependencies: + browserslist: 4.28.0 + caniuse-api: 3.0.0 + colord: 2.9.3 + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-convert-values@6.1.0(postcss@8.5.6): + dependencies: + browserslist: 4.28.0 + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-custom-media@11.0.6(postcss@8.5.6): + dependencies: + '@csstools/cascade-layer-name-parser': 2.0.5(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/media-query-list-parser': 4.0.3(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + postcss: 8.5.6 + + postcss-custom-properties@14.0.6(postcss@8.5.6): + dependencies: + '@csstools/cascade-layer-name-parser': 2.0.5(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-custom-selectors@8.0.5(postcss@8.5.6): + dependencies: + '@csstools/cascade-layer-name-parser': 2.0.5(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.6 + postcss-selector-parser: 7.1.0 + + postcss-dir-pseudo-class@9.0.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 7.1.0 + + postcss-discard-comments@6.0.2(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + postcss-discard-duplicates@6.0.3(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + postcss-discard-empty@6.0.3(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + postcss-discard-overridden@6.0.2(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + postcss-discard-unused@6.0.5(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 6.1.2 + + postcss-double-position-gradients@6.0.4(postcss@8.5.6): + dependencies: + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-focus-visible@10.0.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 7.1.0 + + postcss-focus-within@9.0.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 7.1.0 + + postcss-font-variant@5.0.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + postcss-gap-properties@6.0.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + postcss-image-set-function@7.0.0(postcss@8.5.6): + dependencies: + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-lab-function@7.0.12(postcss@8.5.6): + dependencies: + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/utilities': 2.0.0(postcss@8.5.6) + postcss: 8.5.6 + + postcss-loader@7.3.4(postcss@8.5.6)(typescript@5.6.3)(webpack@5.102.1): + dependencies: + cosmiconfig: 8.3.6(typescript@5.6.3) + jiti: 1.21.7 + postcss: 8.5.6 + semver: 7.7.3 + webpack: 5.102.1 + transitivePeerDependencies: + - typescript + + postcss-logical@8.1.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-merge-idents@6.0.3(postcss@8.5.6): + dependencies: + cssnano-utils: 4.0.2(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-merge-longhand@6.0.5(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + stylehacks: 6.1.1(postcss@8.5.6) + + postcss-merge-rules@6.1.1(postcss@8.5.6): + dependencies: + browserslist: 4.28.0 + caniuse-api: 3.0.0 + cssnano-utils: 4.0.2(postcss@8.5.6) + postcss: 8.5.6 + postcss-selector-parser: 6.1.2 + + postcss-minify-font-values@6.1.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-minify-gradients@6.0.3(postcss@8.5.6): + dependencies: + colord: 2.9.3 + cssnano-utils: 4.0.2(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-minify-params@6.1.0(postcss@8.5.6): + dependencies: + browserslist: 4.28.0 + cssnano-utils: 4.0.2(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-minify-selectors@6.0.4(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 6.1.2 + + postcss-modules-extract-imports@3.1.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + postcss-modules-local-by-default@4.2.0(postcss@8.5.6): + dependencies: + icss-utils: 5.1.0(postcss@8.5.6) + postcss: 8.5.6 + postcss-selector-parser: 7.1.0 + postcss-value-parser: 4.2.0 + + postcss-modules-scope@3.2.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 7.1.0 + + postcss-modules-values@4.0.0(postcss@8.5.6): + dependencies: + icss-utils: 5.1.0(postcss@8.5.6) + postcss: 8.5.6 + + postcss-nesting@13.0.2(postcss@8.5.6): + dependencies: + '@csstools/selector-resolve-nested': 3.1.0(postcss-selector-parser@7.1.0) + '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.0) + postcss: 8.5.6 + postcss-selector-parser: 7.1.0 + + postcss-normalize-charset@6.0.2(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + postcss-normalize-display-values@6.0.2(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-normalize-positions@6.0.2(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-normalize-repeat-style@6.0.2(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-normalize-string@6.0.2(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-normalize-timing-functions@6.0.2(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-normalize-unicode@6.1.0(postcss@8.5.6): + dependencies: + browserslist: 4.28.0 + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-normalize-url@6.0.2(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-normalize-whitespace@6.0.2(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-opacity-percentage@3.0.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + postcss-ordered-values@6.0.2(postcss@8.5.6): + dependencies: + cssnano-utils: 4.0.2(postcss@8.5.6) + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-overflow-shorthand@6.0.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-page-break@3.0.4(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + postcss-place@10.0.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-preset-env@10.4.0(postcss@8.5.6): + dependencies: + '@csstools/postcss-alpha-function': 1.0.1(postcss@8.5.6) + '@csstools/postcss-cascade-layers': 5.0.2(postcss@8.5.6) + '@csstools/postcss-color-function': 4.0.12(postcss@8.5.6) + '@csstools/postcss-color-function-display-p3-linear': 1.0.1(postcss@8.5.6) + '@csstools/postcss-color-mix-function': 3.0.12(postcss@8.5.6) + '@csstools/postcss-color-mix-variadic-function-arguments': 1.0.2(postcss@8.5.6) + '@csstools/postcss-content-alt-text': 2.0.8(postcss@8.5.6) + '@csstools/postcss-contrast-color-function': 2.0.12(postcss@8.5.6) + '@csstools/postcss-exponential-functions': 2.0.9(postcss@8.5.6) + '@csstools/postcss-font-format-keywords': 4.0.0(postcss@8.5.6) + '@csstools/postcss-gamut-mapping': 2.0.11(postcss@8.5.6) + '@csstools/postcss-gradients-interpolation-method': 5.0.12(postcss@8.5.6) + '@csstools/postcss-hwb-function': 4.0.12(postcss@8.5.6) + '@csstools/postcss-ic-unit': 4.0.4(postcss@8.5.6) + '@csstools/postcss-initial': 2.0.1(postcss@8.5.6) + '@csstools/postcss-is-pseudo-class': 5.0.3(postcss@8.5.6) + '@csstools/postcss-light-dark-function': 2.0.11(postcss@8.5.6) + '@csstools/postcss-logical-float-and-clear': 3.0.0(postcss@8.5.6) + '@csstools/postcss-logical-overflow': 2.0.0(postcss@8.5.6) + '@csstools/postcss-logical-overscroll-behavior': 2.0.0(postcss@8.5.6) + '@csstools/postcss-logical-resize': 3.0.0(postcss@8.5.6) + '@csstools/postcss-logical-viewport-units': 3.0.4(postcss@8.5.6) + '@csstools/postcss-media-minmax': 2.0.9(postcss@8.5.6) + '@csstools/postcss-media-queries-aspect-ratio-number-values': 3.0.5(postcss@8.5.6) + '@csstools/postcss-nested-calc': 4.0.0(postcss@8.5.6) + '@csstools/postcss-normalize-display-values': 4.0.0(postcss@8.5.6) + '@csstools/postcss-oklab-function': 4.0.12(postcss@8.5.6) + '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) + '@csstools/postcss-random-function': 2.0.1(postcss@8.5.6) + '@csstools/postcss-relative-color-syntax': 3.0.12(postcss@8.5.6) + '@csstools/postcss-scope-pseudo-class': 4.0.1(postcss@8.5.6) + '@csstools/postcss-sign-functions': 1.1.4(postcss@8.5.6) + '@csstools/postcss-stepped-value-functions': 4.0.9(postcss@8.5.6) + '@csstools/postcss-text-decoration-shorthand': 4.0.3(postcss@8.5.6) + '@csstools/postcss-trigonometric-functions': 4.0.9(postcss@8.5.6) + '@csstools/postcss-unset-value': 4.0.0(postcss@8.5.6) + autoprefixer: 10.4.22(postcss@8.5.6) + browserslist: 4.28.0 + css-blank-pseudo: 7.0.1(postcss@8.5.6) + css-has-pseudo: 7.0.3(postcss@8.5.6) + css-prefers-color-scheme: 10.0.0(postcss@8.5.6) + cssdb: 8.4.2 + postcss: 8.5.6 + postcss-attribute-case-insensitive: 7.0.1(postcss@8.5.6) + postcss-clamp: 4.1.0(postcss@8.5.6) + postcss-color-functional-notation: 7.0.12(postcss@8.5.6) + postcss-color-hex-alpha: 10.0.0(postcss@8.5.6) + postcss-color-rebeccapurple: 10.0.0(postcss@8.5.6) + postcss-custom-media: 11.0.6(postcss@8.5.6) + postcss-custom-properties: 14.0.6(postcss@8.5.6) + postcss-custom-selectors: 8.0.5(postcss@8.5.6) + postcss-dir-pseudo-class: 9.0.1(postcss@8.5.6) + postcss-double-position-gradients: 6.0.4(postcss@8.5.6) + postcss-focus-visible: 10.0.1(postcss@8.5.6) + postcss-focus-within: 9.0.1(postcss@8.5.6) + postcss-font-variant: 5.0.0(postcss@8.5.6) + postcss-gap-properties: 6.0.0(postcss@8.5.6) + postcss-image-set-function: 7.0.0(postcss@8.5.6) + postcss-lab-function: 7.0.12(postcss@8.5.6) + postcss-logical: 8.1.0(postcss@8.5.6) + postcss-nesting: 13.0.2(postcss@8.5.6) + postcss-opacity-percentage: 3.0.0(postcss@8.5.6) + postcss-overflow-shorthand: 6.0.0(postcss@8.5.6) + postcss-page-break: 3.0.4(postcss@8.5.6) + postcss-place: 10.0.0(postcss@8.5.6) + postcss-pseudo-class-any-link: 10.0.1(postcss@8.5.6) + postcss-replace-overflow-wrap: 4.0.0(postcss@8.5.6) + postcss-selector-not: 8.0.1(postcss@8.5.6) + + postcss-pseudo-class-any-link@10.0.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 7.1.0 + + postcss-reduce-idents@6.0.3(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-reduce-initial@6.1.0(postcss@8.5.6): + dependencies: + browserslist: 4.28.0 + caniuse-api: 3.0.0 + postcss: 8.5.6 + + postcss-reduce-transforms@6.0.2(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + postcss-replace-overflow-wrap@4.0.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + postcss-selector-not@8.0.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 7.1.0 + + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-selector-parser@7.1.0: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-sort-media-queries@5.2.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + sort-css-media-queries: 2.2.0 + + postcss-svgo@6.0.3(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + svgo: 3.3.2 + + postcss-unique-selectors@6.0.4(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 6.1.2 + + postcss-value-parser@4.2.0: {} + + postcss-zindex@6.0.2(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + postcss@8.5.6: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + pretty-error@4.0.0: + dependencies: + lodash: 4.17.21 + renderkid: 3.0.0 + + pretty-time@1.1.0: {} + + prism-react-renderer@2.4.1(react@19.2.0): + dependencies: + '@types/prismjs': 1.26.5 + clsx: 2.1.1 + react: 19.2.0 + + prismjs@1.30.0: {} + + process-nextick-args@2.0.1: {} + + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + property-information@6.5.0: {} + + property-information@7.1.0: {} + + proto-list@1.2.4: {} + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + punycode@2.3.1: {} + + pupa@3.3.0: + dependencies: + escape-goat: 4.0.0 + + qs@6.13.0: + dependencies: + side-channel: 1.1.0 + + queue-microtask@1.2.3: {} + + quick-lru@5.1.1: {} + + randombytes@2.1.0: + dependencies: + safe-buffer: 5.2.1 + + range-parser@1.2.0: {} + + range-parser@1.2.1: {} + + raw-body@2.5.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + rc@1.2.8: + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + + react-dom@19.2.0(react@19.2.0): + dependencies: + react: 19.2.0 + scheduler: 0.27.0 + + react-fast-compare@3.2.2: {} + + react-is@16.13.1: {} + + react-json-view-lite@2.5.0(react@19.2.0): + dependencies: + react: 19.2.0 + + react-loadable-ssr-addon-v5-slorber@1.0.1(@docusaurus/react-loadable@6.0.0(react@19.2.0))(webpack@5.102.1): + dependencies: + '@babel/runtime': 7.28.4 + react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.0)' + webpack: 5.102.1 + + react-router-config@5.1.1(react-router@5.3.4(react@19.2.0))(react@19.2.0): + dependencies: + '@babel/runtime': 7.28.4 + react: 19.2.0 + react-router: 5.3.4(react@19.2.0) + + react-router-dom@5.3.4(react@19.2.0): + dependencies: + '@babel/runtime': 7.28.4 + history: 4.10.1 + loose-envify: 1.4.0 + prop-types: 15.8.1 + react: 19.2.0 + react-router: 5.3.4(react@19.2.0) + tiny-invariant: 1.3.3 + tiny-warning: 1.0.3 + + react-router@5.3.4(react@19.2.0): + dependencies: + '@babel/runtime': 7.28.4 + history: 4.10.1 + hoist-non-react-statics: 3.3.2 + loose-envify: 1.4.0 + path-to-regexp: 1.9.0 + prop-types: 15.8.1 + react: 19.2.0 + react-is: 16.13.1 + tiny-invariant: 1.3.3 + tiny-warning: 1.0.3 + + react@19.2.0: {} + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + recma-build-jsx@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-build-jsx: 3.0.1 + vfile: 6.0.3 + + recma-jsx@1.0.1(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + estree-util-to-js: 2.0.0 + recma-parse: 1.0.0 + recma-stringify: 1.0.0 + unified: 11.0.5 + + recma-parse@1.0.0: + dependencies: + '@types/estree': 1.0.8 + esast-util-from-js: 2.0.1 + unified: 11.0.5 + vfile: 6.0.3 + + recma-stringify@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-to-js: 2.0.0 + unified: 11.0.5 + vfile: 6.0.3 + + regenerate-unicode-properties@10.2.2: + dependencies: + regenerate: 1.4.2 + + regenerate@1.4.2: {} + + regexpu-core@6.4.0: + dependencies: + regenerate: 1.4.2 + regenerate-unicode-properties: 10.2.2 + regjsgen: 0.8.0 + regjsparser: 0.13.0 + unicode-match-property-ecmascript: 2.0.0 + unicode-match-property-value-ecmascript: 2.2.1 + + registry-auth-token@5.1.0: + dependencies: + '@pnpm/npm-conf': 2.3.1 + + registry-url@6.0.1: + dependencies: + rc: 1.2.8 + + regjsgen@0.8.0: {} + + regjsparser@0.13.0: + dependencies: + jsesc: 3.1.0 + + rehype-raw@7.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-raw: 9.1.0 + vfile: 6.0.3 + + rehype-recma@1.0.0: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + hast-util-to-estree: 3.1.3 + transitivePeerDependencies: + - supports-color + + relateurl@0.2.7: {} + + remark-directive@3.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-directive: 3.1.0 + micromark-extension-directive: 3.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-emoji@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + emoticon: 4.1.0 + mdast-util-find-and-replace: 3.0.2 + node-emoji: 2.2.0 + unified: 11.0.5 + + remark-frontmatter@5.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-frontmatter: 2.0.1 + micromark-extension-frontmatter: 2.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-gfm@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-gfm: 3.1.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-mdx@3.1.1: + dependencies: + mdast-util-mdx: 3.0.0 + micromark-extension-mdxjs: 3.0.0 + transitivePeerDependencies: + - supports-color + + remark-parse@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + micromark-util-types: 2.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-rehype@11.1.2: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + mdast-util-to-hast: 13.2.0 + unified: 11.0.5 + vfile: 6.0.3 + + remark-stringify@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.1.2 + unified: 11.0.5 + + renderkid@3.0.0: + dependencies: + css-select: 4.3.0 + dom-converter: 0.2.0 + htmlparser2: 6.1.0 + lodash: 4.17.21 + strip-ansi: 6.0.1 + + repeat-string@1.6.1: {} + + require-from-string@2.0.2: {} + + require-like@0.1.2: {} + + requires-port@1.0.0: {} + + resolve-alpn@1.2.1: {} + + resolve-from@4.0.0: {} + + resolve-pathname@3.0.0: {} + + resolve@1.22.11: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + responselike@3.0.0: + dependencies: + lowercase-keys: 3.0.0 + + retry@0.13.1: {} + + reusify@1.1.0: {} + + rtlcss@4.3.0: + dependencies: + escalade: 3.2.0 + picocolors: 1.1.1 + postcss: 8.5.6 + strip-json-comments: 3.1.1 + + run-applescript@7.1.0: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safer-buffer@2.1.2: {} + + sax@1.4.3: {} + + scheduler@0.27.0: {} + + schema-dts@1.1.5: {} + + schema-utils@3.3.0: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + ajv-keywords: 3.5.2(ajv@6.12.6) + + schema-utils@4.3.3: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 8.17.1 + ajv-formats: 2.1.1(ajv@8.17.1) + ajv-keywords: 5.1.0(ajv@8.17.1) + + search-insights@2.17.3: {} + + section-matter@1.0.0: + dependencies: + extend-shallow: 2.0.1 + kind-of: 6.0.3 + + select-hose@2.0.0: {} + + selfsigned@2.4.1: + dependencies: + '@types/node-forge': 1.3.14 + node-forge: 1.3.1 + + semver-diff@4.0.0: + dependencies: + semver: 7.7.3 + + semver@6.3.1: {} + + semver@7.7.3: {} + + send@0.19.0: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + + serialize-javascript@6.0.2: + dependencies: + randombytes: 2.1.0 + + serve-handler@6.1.6: + dependencies: + bytes: 3.0.0 + content-disposition: 0.5.2 + mime-types: 2.1.18 + minimatch: 3.1.2 + path-is-inside: 1.0.2 + path-to-regexp: 3.3.0 + range-parser: 1.2.0 + + serve-index@1.9.1: + dependencies: + accepts: 1.3.8 + batch: 0.6.1 + debug: 2.6.9 + escape-html: 1.0.3 + http-errors: 1.6.3 + mime-types: 2.1.35 + parseurl: 1.3.3 + transitivePeerDependencies: + - supports-color + + serve-static@1.16.2: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.19.0 + transitivePeerDependencies: + - supports-color + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + setprototypeof@1.1.0: {} + + setprototypeof@1.2.0: {} + + shallow-clone@3.0.1: + dependencies: + kind-of: 6.0.3 + + shallowequal@1.1.0: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + shell-quote@1.8.3: {} + + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + signal-exit@3.0.7: {} + + sirv@2.0.4: + dependencies: + '@polka/url': 1.0.0-next.29 + mrmime: 2.0.1 + totalist: 3.0.1 + + sisteransi@1.0.5: {} + + sitemap@7.1.2: + dependencies: + '@types/node': 17.0.45 + '@types/sax': 1.2.7 + arg: 5.0.2 + sax: 1.4.3 + + skin-tone@2.0.0: + dependencies: + unicode-emoji-modifier-base: 1.0.0 + + slash@3.0.0: {} + + slash@4.0.0: {} + + snake-case@3.0.4: + dependencies: + dot-case: 3.0.4 + tslib: 2.8.1 + + sockjs@0.3.24: + dependencies: + faye-websocket: 0.11.4 + uuid: 8.3.2 + websocket-driver: 0.7.4 + + sort-css-media-queries@2.2.0: {} + + source-map-js@1.2.1: {} + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + source-map@0.7.6: {} + + space-separated-tokens@2.0.2: {} + + spdy-transport@3.0.0: + dependencies: + debug: 4.4.3 + detect-node: 2.1.0 + hpack.js: 2.1.6 + obuf: 1.1.2 + readable-stream: 3.6.2 + wbuf: 1.7.3 + transitivePeerDependencies: + - supports-color + + spdy@4.0.2: + dependencies: + debug: 4.4.3 + handle-thing: 2.0.1 + http-deceiver: 1.2.7 + select-hose: 2.0.0 + spdy-transport: 3.0.0 + transitivePeerDependencies: + - supports-color + + sprintf-js@1.0.3: {} + + srcset@4.0.0: {} + + statuses@1.5.0: {} + + statuses@2.0.1: {} + + std-env@3.10.0: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.2 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + + stringify-object@3.3.0: + dependencies: + get-own-enumerable-property-symbols: 3.0.2 + is-obj: 1.0.1 + is-regexp: 1.0.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.2: + dependencies: + ansi-regex: 6.2.2 + + strip-bom-string@1.0.0: {} + + strip-final-newline@2.0.0: {} + + strip-json-comments@2.0.1: {} + + strip-json-comments@3.1.1: {} + + style-to-js@1.1.19: + dependencies: + style-to-object: 1.0.12 + + style-to-object@1.0.12: + dependencies: + inline-style-parser: 0.2.6 + + stylehacks@6.1.1(postcss@8.5.6): + dependencies: + browserslist: 4.28.0 + postcss: 8.5.6 + postcss-selector-parser: 6.1.2 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + svg-parser@2.0.4: {} + + svgo@3.3.2: + dependencies: + '@trysound/sax': 0.2.0 + commander: 7.2.0 + css-select: 5.2.2 + css-tree: 2.3.1 + css-what: 6.2.2 + csso: 5.0.5 + picocolors: 1.1.1 + + swr@2.3.6(react@19.2.0): + dependencies: + dequal: 2.0.3 + react: 19.2.0 + use-sync-external-store: 1.6.0(react@19.2.0) + + tagged-tag@1.0.0: {} + + tapable@2.3.0: {} + + terser-webpack-plugin@5.3.14(webpack@5.102.1): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + jest-worker: 27.5.1 + schema-utils: 4.3.3 + serialize-javascript: 6.0.2 + terser: 5.44.1 + webpack: 5.102.1 + + terser@5.44.1: + dependencies: + '@jridgewell/source-map': 0.3.11 + acorn: 8.15.0 + commander: 2.20.3 + source-map-support: 0.5.21 + + thingies@2.5.0(tslib@2.8.1): + dependencies: + tslib: 2.8.1 + + throttleit@2.1.0: {} + + thunky@1.1.0: {} + + tiny-invariant@1.3.3: {} + + tiny-warning@1.0.3: {} + + tinypool@1.1.1: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toidentifier@1.0.1: {} + + totalist@3.0.1: {} + + tree-dump@1.1.0(tslib@2.8.1): + dependencies: + tslib: 2.8.1 + + trim-lines@3.0.1: {} + + trough@2.2.0: {} + + tslib@2.8.1: {} + + type-fest@0.21.3: {} + + type-fest@1.4.0: {} + + type-fest@2.19.0: {} + + type-fest@5.0.0: + dependencies: + tagged-tag: 1.0.0 + + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + typedarray-to-buffer@3.1.5: + dependencies: + is-typedarray: 1.0.0 + + typescript@5.6.3: {} + + undici-types@7.16.0: {} + + unicode-canonical-property-names-ecmascript@2.0.1: {} + + unicode-emoji-modifier-base@1.0.0: {} + + unicode-match-property-ecmascript@2.0.0: + dependencies: + unicode-canonical-property-names-ecmascript: 2.0.1 + unicode-property-aliases-ecmascript: 2.2.0 + + unicode-match-property-value-ecmascript@2.2.1: {} + + unicode-property-aliases-ecmascript@2.2.0: {} + + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + + unique-string@3.0.0: + dependencies: + crypto-random-string: 4.0.0 + + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position-from-estree@2.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + universalify@2.0.1: {} + + unpipe@1.0.0: {} + + update-browserslist-db@1.1.4(browserslist@4.28.0): + dependencies: + browserslist: 4.28.0 + escalade: 3.2.0 + picocolors: 1.1.1 + + update-notifier@6.0.2: + dependencies: + boxen: 7.1.1 + chalk: 5.6.2 + configstore: 6.0.0 + has-yarn: 3.0.0 + import-lazy: 4.0.0 + is-ci: 3.0.1 + is-installed-globally: 0.4.0 + is-npm: 6.1.0 + is-yarn-global: 0.4.1 + latest-version: 7.0.0 + pupa: 3.3.0 + semver: 7.7.3 + semver-diff: 4.0.0 + xdg-basedir: 5.1.0 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + url-loader@4.1.1(file-loader@6.2.0(webpack@5.102.1))(webpack@5.102.1): + dependencies: + loader-utils: 2.0.4 + mime-types: 2.1.35 + schema-utils: 3.3.0 + webpack: 5.102.1 + optionalDependencies: + file-loader: 6.2.0(webpack@5.102.1) + + use-sync-external-store@1.6.0(react@19.2.0): + dependencies: + react: 19.2.0 + + util-deprecate@1.0.2: {} + + utila@0.4.0: {} + + utility-types@3.11.0: {} + + utils-merge@1.0.1: {} + + uuid@8.3.2: {} + + value-equal@1.0.1: {} + + vary@1.1.2: {} + + vfile-location@5.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile: 6.0.3 + + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + + watchpack@2.4.4: + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + + wbuf@1.7.3: + dependencies: + minimalistic-assert: 1.0.1 + + web-namespaces@2.0.1: {} + + webpack-bundle-analyzer@4.10.2: + dependencies: + '@discoveryjs/json-ext': 0.5.7 + acorn: 8.15.0 + acorn-walk: 8.3.4 + commander: 7.2.0 + debounce: 1.2.1 + escape-string-regexp: 4.0.0 + gzip-size: 6.0.0 + html-escaper: 2.0.2 + opener: 1.5.2 + picocolors: 1.1.1 + sirv: 2.0.4 + ws: 7.5.10 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + webpack-dev-middleware@7.4.5(webpack@5.102.1): + dependencies: + colorette: 2.0.20 + memfs: 4.51.0 + mime-types: 3.0.1 + on-finished: 2.4.1 + range-parser: 1.2.1 + schema-utils: 4.3.3 + optionalDependencies: + webpack: 5.102.1 + + webpack-dev-server@5.2.2(webpack@5.102.1): + dependencies: + '@types/bonjour': 3.5.13 + '@types/connect-history-api-fallback': 1.5.4 + '@types/express': 4.17.25 + '@types/express-serve-static-core': 4.19.7 + '@types/serve-index': 1.9.4 + '@types/serve-static': 1.15.10 + '@types/sockjs': 0.3.36 + '@types/ws': 8.18.1 + ansi-html-community: 0.0.8 + bonjour-service: 1.3.0 + chokidar: 3.6.0 + colorette: 2.0.20 + compression: 1.8.1 + connect-history-api-fallback: 2.0.0 + express: 4.21.2 + graceful-fs: 4.2.11 + http-proxy-middleware: 2.0.9(@types/express@4.17.25) + ipaddr.js: 2.2.0 + launch-editor: 2.12.0 + open: 10.2.0 + p-retry: 6.2.1 + schema-utils: 4.3.3 + selfsigned: 2.4.1 + serve-index: 1.9.1 + sockjs: 0.3.24 + spdy: 4.0.2 + webpack-dev-middleware: 7.4.5(webpack@5.102.1) + ws: 8.18.3 + optionalDependencies: + webpack: 5.102.1 + transitivePeerDependencies: + - bufferutil + - debug + - supports-color + - utf-8-validate + + webpack-merge@5.10.0: + dependencies: + clone-deep: 4.0.1 + flat: 5.0.2 + wildcard: 2.0.1 + + webpack-merge@6.0.1: + dependencies: + clone-deep: 4.0.1 + flat: 5.0.2 + wildcard: 2.0.1 + + webpack-sources@3.3.3: {} + + webpack@5.102.1: + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.8 + '@types/json-schema': 7.0.15 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + acorn: 8.15.0 + acorn-import-phases: 1.0.4(acorn@8.15.0) + browserslist: 4.28.0 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.18.3 + es-module-lexer: 1.7.0 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.1 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 4.3.3 + tapable: 2.3.0 + terser-webpack-plugin: 5.3.14(webpack@5.102.1) + watchpack: 2.4.4 + webpack-sources: 3.3.3 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + + webpackbar@6.0.1(webpack@5.102.1): + dependencies: + ansi-escapes: 4.3.2 + chalk: 4.1.2 + consola: 3.4.2 + figures: 3.2.0 + markdown-table: 2.0.0 + pretty-time: 1.1.0 + std-env: 3.10.0 + webpack: 5.102.1 + wrap-ansi: 7.0.0 + + websocket-driver@0.7.4: + dependencies: + http-parser-js: 0.5.10 + safe-buffer: 5.2.1 + websocket-extensions: 0.1.4 + + websocket-extensions@0.1.4: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + widest-line@4.0.1: + dependencies: + string-width: 5.1.2 + + wildcard@2.0.1: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.3 + string-width: 5.1.2 + strip-ansi: 7.1.2 + + write-file-atomic@3.0.3: + dependencies: + imurmurhash: 0.1.4 + is-typedarray: 1.0.0 + signal-exit: 3.0.7 + typedarray-to-buffer: 3.1.5 + + ws@7.5.10: {} + + ws@8.18.3: {} + + wsl-utils@0.1.0: + dependencies: + is-wsl: 3.1.0 + + xdg-basedir@5.1.0: {} + + xml-js@1.6.11: + dependencies: + sax: 1.4.3 + + yallist@3.1.1: {} + + yocto-queue@1.2.2: {} + + zod@4.1.11: {} + + zod@4.1.12: {} + + zwitch@2.0.4: {} diff --git a/docs/pnpm-workspace.yaml b/docs/pnpm-workspace.yaml new file mode 100644 index 000000000..1f4781336 --- /dev/null +++ b/docs/pnpm-workspace.yaml @@ -0,0 +1,5 @@ +ignoredBuiltDependencies: + - core-js-pure + +onlyBuiltDependencies: + - core-js diff --git a/docs/sidebars.ts b/docs/sidebars.ts new file mode 100644 index 000000000..95bfc472e --- /dev/null +++ b/docs/sidebars.ts @@ -0,0 +1,49 @@ +import type { SidebarsConfig } from '@docusaurus/plugin-content-docs'; + +const sidebars: SidebarsConfig = { + docsSidebar: [ + 'index', + 'help', + 'faq', + { + type: 'category', + label: "Developers", + link: { + type: "generated-index", + description: "Building with Stoat" + }, + items: [ + { + type: 'autogenerated', + dirName: 'developers', + } + ] + }, + { + type: 'category', + label: "Developing Stoat", + link: { + type: "generated-index", + description: "Building Stoat" + }, + items: [ + { + type: 'autogenerated', + dirName: 'developing', + }, + { + type: 'link', + label: "for Web", + href: "https://stoatchat.github.io/for-web" + }, + { + type: 'link', + label: "for Android", + href: "https://stoatchat.github.io/for-android" + } + ] + } + ], +}; + +export default sidebars; diff --git a/docs/static/.nojekyll b/docs/static/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/docs/static/img/.gitkeep b/docs/static/img/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/docs/tsconfig.json b/docs/tsconfig.json new file mode 100644 index 000000000..920d7a652 --- /dev/null +++ b/docs/tsconfig.json @@ -0,0 +1,8 @@ +{ + // This file is not used in compilation. It is here just for a nice editor experience. + "extends": "@docusaurus/tsconfig", + "compilerOptions": { + "baseUrl": "." + }, + "exclude": [".docusaurus", "build"] +} From dda20f44aecd0fc4622ad972fbea875bce1ead14 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Fri, 14 Nov 2025 22:11:21 +0000 Subject: [PATCH 030/211] ci: correct build to ./docs/build (#463) --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 8cf399a42..74faefc0c 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -33,7 +33,7 @@ jobs: - name: Upload Build Artifact uses: actions/upload-pages-artifact@v3 with: - path: build + path: ./docs/build deploy: name: Deploy to GitHub Pages From 24fedf8c4d9cd3160bdec97aa451520f8beaa739 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Sun, 16 Nov 2025 15:24:39 +0000 Subject: [PATCH 031/211] fix: respond with 201 if no body in requests (#465) Signed-off-by: izzy --- .../delta/src/routes/policy/acknowledge_policy_changes.rs | 6 ++++-- crates/delta/src/routes/safety/report_content.rs | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/crates/delta/src/routes/policy/acknowledge_policy_changes.rs b/crates/delta/src/routes/policy/acknowledge_policy_changes.rs index 8b69efda1..9002d8900 100644 --- a/crates/delta/src/routes/policy/acknowledge_policy_changes.rs +++ b/crates/delta/src/routes/policy/acknowledge_policy_changes.rs @@ -2,12 +2,14 @@ use revolt_database::{Database, User}; use revolt_result::Result; use rocket::State; +use rocket_empty::EmptyResponse; /// # Acknowledge Policy Changes /// /// Accept/acknowledge changes to platform policy. #[openapi(tag = "Policy")] #[post("/acknowledge")] -pub async fn acknowledge_policy_changes(db: &State, user: User) -> Result<()> { - db.acknowledge_policy_changes(&user.id).await +pub async fn acknowledge_policy_changes(db: &State, user: User) -> Result { + db.acknowledge_policy_changes(&user.id).await?; + Ok(EmptyResponse) } diff --git a/crates/delta/src/routes/safety/report_content.rs b/crates/delta/src/routes/safety/report_content.rs index 1d5c23560..8d52ceefc 100644 --- a/crates/delta/src/routes/safety/report_content.rs +++ b/crates/delta/src/routes/safety/report_content.rs @@ -1,6 +1,7 @@ use revolt_database::{events::client::EventV1, Database, Report, Snapshot, SnapshotContent, User}; use revolt_models::v0::{ReportStatus, ReportedContent}; use revolt_result::{create_error, Result}; +use rocket_empty::EmptyResponse; use serde::Deserialize; use ulid::Ulid; use validator::Validate; @@ -27,7 +28,7 @@ pub async fn report_content( db: &State, user: User, data: Json, -) -> Result<()> { +) -> Result { let data = data.into_inner(); data.validate().map_err(|error| { create_error!(FailedValidation { @@ -129,5 +130,5 @@ pub async fn report_content( EventV1::ReportCreate(report.into()).global().await; - Ok(()) + Ok(EmptyResponse) } From dc9c82aa4e9667ea6639256c65ac8de37a24d1f7 Mon Sep 17 00:00:00 2001 From: Angelo Kontaxis Date: Wed, 7 Jan 2026 21:11:42 +0000 Subject: [PATCH 032/211] fix: github webhook incorrect payload and formatting (#468) --- .../routes/webhooks/webhook_execute_github.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/crates/delta/src/routes/webhooks/webhook_execute_github.rs b/crates/delta/src/routes/webhooks/webhook_execute_github.rs index f84ecc634..124b2e97c 100644 --- a/crates/delta/src/routes/webhooks/webhook_execute_github.rs +++ b/crates/delta/src/routes/webhooks/webhook_execute_github.rs @@ -217,7 +217,6 @@ pub struct GithubComment { position: Option, reactions: Option, updated_at: Value, - url: String, user: GithubUser, } @@ -701,7 +700,7 @@ fn safe_from_str Deserialize<'de>>(data: &str) -> Result { match serde_json::from_str(data) { Ok(output) => Ok(output), Err(err) => { - log::error!("{err:?}"); + revolt_config::capture_internal_error!(err); Err(create_error!(InvalidOperation)) } } @@ -753,12 +752,12 @@ pub async fn webhook_execute_github( db: &State, amqp: &State, webhook_id: Reference<'_>, - token: String, + token: &str, event: EventHeader<'_>, data: String, ) -> Result<()> { let webhook = webhook_id.as_webhook(db).await?; - webhook.assert_token(&token)?; + webhook.assert_token(token)?; let channel = db.fetch_channel(&webhook.channel_id).await?; let event = convert_event(&data, &event)?; @@ -897,10 +896,11 @@ pub async fn webhook_execute_github( url: Some(event.sender.html_url), title: Some(event.sender.login), description: Some(format!( - "#### [{}] New discussion #{}: {}\n{}", + "#### [[{}] New discussion #{}: {}]({})\n{}", event.repository.full_name, discussion.number, discussion.title, + discussion.html_url, shorten_text(&discussion.body, 450) )), colour: Some(LIGHT_ORANGE.to_string()), @@ -911,10 +911,11 @@ pub async fn webhook_execute_github( url: Some(answer.comment.user.html_url), title: Some(answer.comment.user.login), description: Some(format!( - "#### [{}] discussion #{} marked answered: {}\n{}", + "#### [[{}] Discussion #{} marked answered: {}]({})\n{}", event.repository.full_name, discussion.number, discussion.title, + answer.comment.html_url, shorten_text(&answer.comment.body, 450) )), colour: Some(LIGHT_ORANGE.to_string()), @@ -930,10 +931,11 @@ pub async fn webhook_execute_github( url: Some(comment.comment.user.html_url), title: Some(comment.comment.user.login), description: Some(format!( - "[{}] New comment on discussion #{}: {}\n{}", + "#### [[{}] New comment on discussion #{}: {}]({})\n{}", event.repository.full_name, discussion.number, discussion.title, + comment.comment.html_url, shorten_text(&comment.comment.body, 450) )), colour: Some(LIGHT_ORANGE.to_string()), @@ -1002,7 +1004,7 @@ pub async fn webhook_execute_github( event.repository.full_name, issue.number, issue.title, - issue.html_url, + comment.html_url, shorten_text(&comment.body, 450) )), colour: Some(LIGHT_ORANGE.to_string()), From b48eb28fc2cc19fc68d245bfd8d682010aa90e49 Mon Sep 17 00:00:00 2001 From: Simon Marty Date: Wed, 7 Jan 2026 13:12:24 -0800 Subject: [PATCH 033/211] docs: remove outdated notice about perf. regression (#467) --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index 1f1ccbb03..f5f452705 100644 --- a/README.md +++ b/README.md @@ -37,9 +37,6 @@ The services and libraries that power the Revolt service.
Rust 1.86.0 or higher. -> [!CAUTION] -> The events server has a significant performance regression between Rust 1.77.2 and 1.78.0 onwards, see [issue #341](https://github.com/revoltchat/backend/issues/341). This is currently solved by build time options but we are looking for a proper fix. - ## Development Guide Before contributing, make yourself familiar with [our contribution guidelines](https://developers.revolt.chat/contrib.html) and the [technical documentation for this project](https://revoltchat.github.io/backend/). From a7b870c397ac86367b0223a2935ef3f32e7ff5e4 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Thu, 8 Jan 2026 22:16:50 +0000 Subject: [PATCH 034/211] chore: configure release please (#472) --- .github/workflows/release-please.yml | 49 ++++++++++++++++++++++++++++ .release-please-manifest.json | 3 ++ Cargo.lock | 38 ++++++++++----------- crates/bonfire/Cargo.toml | 4 +-- crates/core/coalesced/Cargo.toml | 2 +- crates/core/config/Cargo.toml | 4 +-- crates/core/database/Cargo.toml | 14 ++++---- crates/core/files/Cargo.toml | 6 ++-- crates/core/models/Cargo.toml | 6 ++-- crates/core/parser/Cargo.toml | 2 +- crates/core/permissions/Cargo.toml | 4 +-- crates/core/presence/Cargo.toml | 4 +-- crates/core/ratelimits/Cargo.toml | 8 ++--- crates/core/result/Cargo.toml | 2 +- crates/daemons/crond/Cargo.toml | 10 +++--- crates/daemons/pushd/Cargo.toml | 12 +++---- crates/delta/Cargo.toml | 2 +- crates/services/autumn/Cargo.toml | 12 +++---- crates/services/gifbox/Cargo.toml | 14 ++++---- crates/services/january/Cargo.toml | 10 +++--- release-please-config.json | 33 +++++++++++++++++++ 21 files changed, 162 insertions(+), 77 deletions(-) create mode 100644 .github/workflows/release-please.yml create mode 100644 .release-please-manifest.json create mode 100644 release-please-config.json diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml new file mode 100644 index 000000000..8b5215639 --- /dev/null +++ b/.github/workflows/release-please.yml @@ -0,0 +1,49 @@ +name: Release Please + +on: + push: + branches: [main] # updates/opens the release PR when commits land on main + workflow_dispatch: + +permissions: + contents: write + pull-requests: write + id-token: write + +concurrency: + group: release-please + cancel-in-progress: true + +jobs: + release-please: + name: Release Please + runs-on: ubuntu-latest + outputs: + release_created: ${{ steps.rp.outputs.release_created }} + steps: + - id: app-token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.GH_STOAT_RELEASE_APP_ID }} + private-key: ${{ secrets.GH_STOAT_RELEASE_APP_PRIVATE_KEY }} + - id: rp + uses: googleapis/release-please-action@v4 + with: + token: ${{ steps.app-token.outputs.token }} + config-file: release-please-config.json + + publish-stable: + name: Publish release to stable branch + needs: release-please + if: needs.release-please.outputs.release_created == 'true' + runs-on: ubuntu-latest + + steps: + - id: app-token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.GH_STOAT_RELEASE_APP_ID }} + private-key: ${{ secrets.GH_STOAT_RELEASE_APP_PRIVATE_KEY }} + - uses: katyo/publish-crates@v2 + with: + registry-token: ${{ secrets.CRATES_IO_PUBLISH_TOKEN }} diff --git a/.release-please-manifest.json b/.release-please-manifest.json new file mode 100644 index 000000000..c96cf72b3 --- /dev/null +++ b/.release-please-manifest.json @@ -0,0 +1,3 @@ +{ + ".": "0.8.8" +} \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index ee03bf557..5772e212a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4742,7 +4742,7 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.8.9" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ @@ -6519,7 +6519,7 @@ dependencies = [ [[package]] name = "revolt-autumn" -version = "0.8.9" +version = "0.8.8" dependencies = [ "axum", "axum-macros", @@ -6557,7 +6557,7 @@ dependencies = [ [[package]] name = "revolt-bonfire" -version = "0.8.9" +version = "0.8.8" dependencies = [ "async-channel 2.5.0", "async-std", @@ -6588,7 +6588,7 @@ dependencies = [ [[package]] name = "revolt-coalesced" -version = "0.8.9" +version = "0.8.8" dependencies = [ "indexmap 2.11.4", "lru 0.7.8", @@ -6597,7 +6597,7 @@ dependencies = [ [[package]] name = "revolt-config" -version = "0.8.9" +version = "0.8.8" dependencies = [ "async-std", "cached", @@ -6614,7 +6614,7 @@ dependencies = [ [[package]] name = "revolt-crond" -version = "0.8.9" +version = "0.8.8" dependencies = [ "log", "revolt-config", @@ -6626,7 +6626,7 @@ dependencies = [ [[package]] name = "revolt-database" -version = "0.8.9" +version = "0.8.8" dependencies = [ "amqprs", "async-lock 2.8.0", @@ -6676,7 +6676,7 @@ dependencies = [ [[package]] name = "revolt-delta" -version = "0.8.9" +version = "0.8.8" dependencies = [ "amqprs", "async-channel 1.9.0", @@ -6726,7 +6726,7 @@ dependencies = [ [[package]] name = "revolt-files" -version = "0.8.9" +version = "0.8.8" dependencies = [ "aes-gcm", "aws-config", @@ -6749,7 +6749,7 @@ dependencies = [ [[package]] name = "revolt-gifbox" -version = "0.8.9" +version = "0.8.8" dependencies = [ "axum", "axum-extra", @@ -6771,7 +6771,7 @@ dependencies = [ [[package]] name = "revolt-january" -version = "0.8.9" +version = "0.8.8" dependencies = [ "async-recursion", "axum", @@ -6799,7 +6799,7 @@ dependencies = [ [[package]] name = "revolt-models" -version = "0.8.9" +version = "0.8.8" dependencies = [ "indexmap 1.9.3", "iso8601-timestamp", @@ -6818,14 +6818,14 @@ dependencies = [ [[package]] name = "revolt-parser" -version = "0.8.9" +version = "0.8.8" dependencies = [ "logos", ] [[package]] name = "revolt-permissions" -version = "0.8.9" +version = "0.8.8" dependencies = [ "async-std", "async-trait", @@ -6840,7 +6840,7 @@ dependencies = [ [[package]] name = "revolt-presence" -version = "0.8.9" +version = "0.8.8" dependencies = [ "async-std", "log", @@ -6852,7 +6852,7 @@ dependencies = [ [[package]] name = "revolt-pushd" -version = "0.8.9" +version = "0.8.8" dependencies = [ "amqprs", "anyhow", @@ -6880,7 +6880,7 @@ dependencies = [ [[package]] name = "revolt-ratelimits" -version = "0.8.9" +version = "0.8.8" dependencies = [ "async-trait", "authifier", @@ -6897,7 +6897,7 @@ dependencies = [ [[package]] name = "revolt-result" -version = "0.8.9" +version = "0.8.8" dependencies = [ "axum", "log", @@ -8236,7 +8236,7 @@ dependencies = [ [[package]] name = "string_cache" -version = "0.8.9" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" dependencies = [ diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index 093c04408..63badcce8 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-bonfire" -version = "0.8.9" +version = "0.8.8" license = "AGPL-3.0-or-later" edition = "2021" @@ -42,7 +42,7 @@ revolt-result = { path = "../core/result" } revolt-models = { path = "../core/models" } revolt-config = { path = "../core/config" } revolt-database = { path = "../core/database", features = ["voice"] } -revolt-permissions = { version = "0.8.9", path = "../core/permissions" } +revolt-permissions = { version = "0.8.8", path = "../core/permissions" } revolt-presence = { path = "../core/presence", features = ["redis-is-patched"] } # redis diff --git a/crates/core/coalesced/Cargo.toml b/crates/core/coalesced/Cargo.toml index 32dad1325..cb23a8adb 100644 --- a/crates/core/coalesced/Cargo.toml +++ b/crates/core/coalesced/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-coalesced" -version = "0.8.9" +version = "0.8.8" edition = "2021" license = "MIT" authors = ["Paul Makles ", "Zomatree "] diff --git a/crates/core/config/Cargo.toml b/crates/core/config/Cargo.toml index 2a6dbb9ee..26cc1c25f 100644 --- a/crates/core/config/Cargo.toml +++ b/crates/core/config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-config" -version = "0.8.9" +version = "0.8.8" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -37,4 +37,4 @@ sentry = { version = "0.31.5", optional = true } sentry-anyhow = { version = "0.38.1", optional = true } # Core -revolt-result = { version = "0.8.9", path = "../result", optional = true } +revolt-result = { version = "0.8.8", path = "../result", optional = true } diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index a1bf5189d..9abdcbf19 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-database" -version = "0.8.9" +version = "0.8.8" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -25,19 +25,19 @@ default = ["mongodb", "async-std-runtime", "tasks"] [dependencies] # Core -revolt-config = { version = "0.8.9", path = "../config", features = [ +revolt-config = { version = "0.8.8", path = "../config", features = [ "report-macros", ] } -revolt-result = { version = "0.8.9", path = "../result" } -revolt-models = { version = "0.8.9", path = "../models", features = [ +revolt-result = { version = "0.8.8", path = "../result" } +revolt-models = { version = "0.8.8", path = "../models", features = [ "validator", ] } -revolt-presence = { version = "0.8.9", path = "../presence" } -revolt-permissions = { version = "0.8.9", path = "../permissions", features = [ +revolt-presence = { version = "0.8.8", path = "../presence" } +revolt-permissions = { version = "0.8.8", path = "../permissions", features = [ "serde", "bson", ] } -revolt-parser = { version = "0.8.9", path = "../parser" } +revolt-parser = { version = "0.8.8", path = "../parser" } # Utility log = "0.4" diff --git a/crates/core/files/Cargo.toml b/crates/core/files/Cargo.toml index e65451922..7cc219f1c 100644 --- a/crates/core/files/Cargo.toml +++ b/crates/core/files/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-files" -version = "0.8.9" +version = "0.8.8" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -20,10 +20,10 @@ typenum = "1.17.0" aws-config = "1.5.5" aws-sdk-s3 = { version = "1.46.0", features = ["behavior-version-latest"] } -revolt-config = { version = "0.8.9", path = "../config", features = [ +revolt-config = { version = "0.8.8", path = "../config", features = [ "report-macros", ] } -revolt-result = { version = "0.8.9", path = "../result" } +revolt-result = { version = "0.8.8", path = "../result" } # image processing jxl-oxide = "0.8.1" diff --git a/crates/core/models/Cargo.toml b/crates/core/models/Cargo.toml index 4821ec75b..e232fd6cc 100644 --- a/crates/core/models/Cargo.toml +++ b/crates/core/models/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-models" -version = "0.8.9" +version = "0.8.8" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -20,8 +20,8 @@ default = ["serde", "partials", "rocket"] [dependencies] # Core -revolt-config = { version = "0.8.9", path = "../config" } -revolt-permissions = { version = "0.8.9", path = "../permissions" } +revolt-config = { version = "0.8.8", path = "../config" } +revolt-permissions = { version = "0.8.8", path = "../permissions" } # Utility regex = "1.11" diff --git a/crates/core/parser/Cargo.toml b/crates/core/parser/Cargo.toml index aa6b7fc2e..a6e1869b7 100644 --- a/crates/core/parser/Cargo.toml +++ b/crates/core/parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-parser" -version = "0.8.9" +version = "0.8.8" edition = "2021" license = "MIT" authors = ["Zomatree ", "Paul Makles "] diff --git a/crates/core/permissions/Cargo.toml b/crates/core/permissions/Cargo.toml index 6fcc38287..d5ee32165 100644 --- a/crates/core/permissions/Cargo.toml +++ b/crates/core/permissions/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-permissions" -version = "0.8.9" +version = "0.8.8" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -21,7 +21,7 @@ async-std = { version = "1.8.0", features = ["attributes"] } [dependencies] # Core -revolt-result = { version = "0.8.9", path = "../result" } +revolt-result = { version = "0.8.8", path = "../result" } # Utility auto_ops = "0.3.0" diff --git a/crates/core/presence/Cargo.toml b/crates/core/presence/Cargo.toml index b2e232228..2e53c3e70 100644 --- a/crates/core/presence/Cargo.toml +++ b/crates/core/presence/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-presence" -version = "0.8.9" +version = "0.8.8" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -16,7 +16,7 @@ redis-is-patched = [] async-std = { version = "1.8.0", features = ["attributes"] } # Config for loading Redis URI -revolt-config = { version = "0.8.9", path = "../config" } +revolt-config = { version = "0.8.8", path = "../config" } [dependencies] # Utility diff --git a/crates/core/ratelimits/Cargo.toml b/crates/core/ratelimits/Cargo.toml index a41952bb9..05e1e362d 100644 --- a/crates/core/ratelimits/Cargo.toml +++ b/crates/core/ratelimits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-ratelimits" -version = "0.8.9" +version = "0.8.8" edition = "2024" [features] @@ -10,9 +10,9 @@ axum = ["dep:axum", "revolt-database/axum-impl"] default = ["rocket", "axum"] [dependencies] -revolt-database = { version = "0.8.9", path = "../database"} -revolt-result = { version = "0.8.9", path = "../result" } -revolt-config = { version = "0.8.9", path = "../config" } +revolt-database = { version = "0.8.8", path = "../database"} +revolt-result = { version = "0.8.8", path = "../result" } +revolt-config = { version = "0.8.8", path = "../config" } rocket = { version = "0.5.1", optional = true } revolt_rocket_okapi = { version = "0.10.0", optional = true } diff --git a/crates/core/result/Cargo.toml b/crates/core/result/Cargo.toml index ebc0764ea..9004b570e 100644 --- a/crates/core/result/Cargo.toml +++ b/crates/core/result/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-result" -version = "0.8.9" +version = "0.8.8" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/daemons/crond/Cargo.toml b/crates/daemons/crond/Cargo.toml index 1e070e38b..2c55f2f76 100644 --- a/crates/daemons/crond/Cargo.toml +++ b/crates/daemons/crond/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-crond" -version = "0.8.9" +version = "0.8.8" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2021" @@ -16,7 +16,7 @@ log = "0.4" tokio = { version = "1" } # Core -revolt-database = { version = "0.8.9", path = "../../core/database" } -revolt-result = { version = "0.8.9", path = "../../core/result" } -revolt-config = { version = "0.8.9", path = "../../core/config" } -revolt-files = { version = "0.8.9", path = "../../core/files" } +revolt-database = { version = "0.8.8", path = "../../core/database" } +revolt-result = { version = "0.8.8", path = "../../core/result" } +revolt-config = { version = "0.8.8", path = "../../core/config" } +revolt-files = { version = "0.8.8", path = "../../core/files" } diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index 71fc002bf..40a280081 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -1,20 +1,20 @@ [package] name = "revolt-pushd" -version = "0.8.9" +version = "0.8.8" edition = "2021" license = "AGPL-3.0-or-later" [dependencies] -revolt-result = { version = "0.8.9", path = "../../core/result" } -revolt-config = { version = "0.8.9", path = "../../core/config", features = [ +revolt-result = { version = "0.8.8", path = "../../core/result" } +revolt-config = { version = "0.8.8", path = "../../core/config", features = [ "report-macros", "anyhow" ] } -revolt-database = { version = "0.8.9", path = "../../core/database" } -revolt-models = { version = "0.8.9", path = "../../core/models", features = [ +revolt-database = { version = "0.8.8", path = "../../core/database" } +revolt-models = { version = "0.8.8", path = "../../core/models", features = [ "validator", ] } -revolt-presence = { version = "0.8.9", path = "../../core/presence", features = [ +revolt-presence = { version = "0.8.8", path = "../../core/presence", features = [ "redis-is-patched", ] } diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index fc4b1d49e..3667d83fd 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-delta" -version = "0.8.9" +version = "0.8.8" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2018" diff --git a/crates/services/autumn/Cargo.toml b/crates/services/autumn/Cargo.toml index e15fbf0e6..3514f501d 100644 --- a/crates/services/autumn/Cargo.toml +++ b/crates/services/autumn/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-autumn" -version = "0.8.9" +version = "0.8.8" edition = "2021" license = "AGPL-3.0-or-later" @@ -43,16 +43,16 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # Core crates -revolt-files = { version = "0.8.9", path = "../../core/files" } -revolt-config = { version = "0.8.9", path = "../../core/config" } -revolt-database = { version = "0.8.9", path = "../../core/database", features = [ +revolt-files = { version = "0.8.8", path = "../../core/files" } +revolt-config = { version = "0.8.8", path = "../../core/config" } +revolt-database = { version = "0.8.8", path = "../../core/database", features = [ "axum-impl", ] } -revolt-result = { version = "0.8.9", path = "../../core/result", features = [ +revolt-result = { version = "0.8.8", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-ratelimits = { version = "0.8.9", path = "../../core/ratelimits", features = ["axum"] } +revolt-ratelimits = { version = "0.8.8", path = "../../core/ratelimits", features = ["axum"] } # Axum / web server tempfile = "3.12.0" diff --git a/crates/services/gifbox/Cargo.toml b/crates/services/gifbox/Cargo.toml index c611f59d9..3e2b41736 100644 --- a/crates/services/gifbox/Cargo.toml +++ b/crates/services/gifbox/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-gifbox" -version = "0.8.9" +version = "0.8.8" edition = "2021" license = "AGPL-3.0-or-later" @@ -16,19 +16,19 @@ tokio = { version = "1.0", features = ["full"] } reqwest = { version = "0.12", features = ["json"] } # Core crates -revolt-config = { version = "0.8.9", path = "../../core/config" } -revolt-models = { version = "0.8.9", path = "../../core/models" } -revolt-result = { version = "0.8.9", path = "../../core/result", features = [ +revolt-config = { version = "0.8.8", path = "../../core/config" } +revolt-models = { version = "0.8.8", path = "../../core/models" } +revolt-result = { version = "0.8.8", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-coalesced = { version = "0.8.9", path = "../../core/coalesced", features = [ +revolt-coalesced = { version = "0.8.8", path = "../../core/coalesced", features = [ "queue", ] } -revolt-database = { version = "0.8.9", path = "../../core/database", features = [ +revolt-database = { version = "0.8.8", path = "../../core/database", features = [ "axum-impl", ] } -revolt-ratelimits = { version = "0.8.9", path = "../../core/ratelimits", features = [ +revolt-ratelimits = { version = "0.8.8", path = "../../core/ratelimits", features = [ "axum", ] } diff --git a/crates/services/january/Cargo.toml b/crates/services/january/Cargo.toml index b549882aa..80b5e5228 100644 --- a/crates/services/january/Cargo.toml +++ b/crates/services/january/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-january" -version = "0.8.9" +version = "0.8.8" edition = "2021" license = "AGPL-3.0-or-later" @@ -32,13 +32,13 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # Core crates -revolt-config = { version = "0.8.9", path = "../../core/config" } -revolt-models = { version = "0.8.9", path = "../../core/models" } -revolt-result = { version = "0.8.9", path = "../../core/result", features = [ +revolt-config = { version = "0.8.8", path = "../../core/config" } +revolt-models = { version = "0.8.8", path = "../../core/models" } +revolt-result = { version = "0.8.8", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-files = { version = "0.8.9", path = "../../core/files" } +revolt-files = { version = "0.8.8", path = "../../core/files" } # Axum / web server axum = { version = "0.7.5" } diff --git a/release-please-config.json b/release-please-config.json new file mode 100644 index 000000000..6cb3a3722 --- /dev/null +++ b/release-please-config.json @@ -0,0 +1,33 @@ +{ + "packages": { + ".": { + "changelog-path": "CHANGELOG.md", + "release-type": "rust", + "bump-minor-pre-major": false, + "bump-patch-for-minor-pre-major": false, + "draft": false, + "prerelease": false, + "extra-files": [ + "crates/bonfire/Cargo.toml", + "crates/core/coalesced/Cargo.toml", + "crates/core/config/Cargo.toml", + "crates/core/database/Cargo.toml", + "crates/core/files/Cargo.toml", + "crates/core/models/Cargo.toml", + "crates/core/parser/Cargo.toml", + "crates/core/permissions/Cargo.toml", + "crates/core/presence/Cargo.toml", + "crates/core/ratelimits/Cargo.toml", + "crates/core/result/Cargo.toml", + "crates/daemons/crond/Cargo.toml", + "crates/daemons/pushd/Cargo.toml", + "crates/daemons/voice-ingress/Cargo.toml", + "crates/delta/Cargo.toml", + "crates/services/autumn/Cargo.toml", + "crates/services/gifbox/Cargo.toml", + "crates/services/january/Cargo.toml" + ] + } + }, + "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json" +} \ No newline at end of file From ffdb2b6900e663a08612ab8e9093415546ca9e61 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Thu, 8 Jan 2026 22:24:45 +0000 Subject: [PATCH 035/211] ci: switch api server as main package for release please (#473) --- .release-please-manifest.json | 2 +- release-please-config.json | 108 +++++++++++++++++++++++++++------- 2 files changed, 89 insertions(+), 21 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index c96cf72b3..a312649aa 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.8.8" + "crates/delta": "0.8.8" } \ No newline at end of file diff --git a/release-please-config.json b/release-please-config.json index 6cb3a3722..a101f422e 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -1,31 +1,99 @@ { + "include-component-in-tag": false, "packages": { - ".": { - "changelog-path": "CHANGELOG.md", + "crates/delta": { + "changelog-path": "../../CHANGELOG.md", "release-type": "rust", "bump-minor-pre-major": false, "bump-patch-for-minor-pre-major": false, "draft": false, "prerelease": false, "extra-files": [ - "crates/bonfire/Cargo.toml", - "crates/core/coalesced/Cargo.toml", - "crates/core/config/Cargo.toml", - "crates/core/database/Cargo.toml", - "crates/core/files/Cargo.toml", - "crates/core/models/Cargo.toml", - "crates/core/parser/Cargo.toml", - "crates/core/permissions/Cargo.toml", - "crates/core/presence/Cargo.toml", - "crates/core/ratelimits/Cargo.toml", - "crates/core/result/Cargo.toml", - "crates/daemons/crond/Cargo.toml", - "crates/daemons/pushd/Cargo.toml", - "crates/daemons/voice-ingress/Cargo.toml", - "crates/delta/Cargo.toml", - "crates/services/autumn/Cargo.toml", - "crates/services/gifbox/Cargo.toml", - "crates/services/january/Cargo.toml" + { + "type": "toml", + "path": "crates/bonfire/Cargo.toml", + "jsonpath": "$.package.version" + }, + { + "type": "toml", + "path": "crates/core/coalesced/Cargo.toml", + "jsonpath": "$.package.version" + }, + { + "type": "toml", + "path": "crates/core/config/Cargo.toml", + "jsonpath": "$.package.version" + }, + { + "type": "toml", + "path": "crates/core/database/Cargo.toml", + "jsonpath": "$.package.version" + }, + { + "type": "toml", + "path": "crates/core/files/Cargo.toml", + "jsonpath": "$.package.version" + }, + { + "type": "toml", + "path": "crates/core/models/Cargo.toml", + "jsonpath": "$.package.version" + }, + { + "type": "toml", + "path": "crates/core/parser/Cargo.toml", + "jsonpath": "$.package.version" + }, + { + "type": "toml", + "path": "crates/core/permissions/Cargo.toml", + "jsonpath": "$.package.version" + }, + { + "type": "toml", + "path": "crates/core/presence/Cargo.toml", + "jsonpath": "$.package.version" + }, + { + "type": "toml", + "path": "crates/core/ratelimits/Cargo.toml", + "jsonpath": "$.package.version" + }, + { + "type": "toml", + "path": "crates/core/result/Cargo.toml", + "jsonpath": "$.package.version" + }, + { + "type": "toml", + "path": "crates/daemons/crond/Cargo.toml", + "jsonpath": "$.package.version" + }, + { + "type": "toml", + "path": "crates/daemons/pushd/Cargo.toml", + "jsonpath": "$.package.version" + }, + { + "type": "toml", + "path": "crates/daemons/voice-ingress/Cargo.toml", + "jsonpath": "$.package.version" + }, + { + "type": "toml", + "path": "crates/services/autumn/Cargo.toml", + "jsonpath": "$.package.version" + }, + { + "type": "toml", + "path": "crates/services/gifbox/Cargo.toml", + "jsonpath": "$.package.version" + }, + { + "type": "toml", + "path": "crates/services/january/Cargo.toml", + "jsonpath": "$.package.version" + } ] } }, From 22e46194abd1cab72bbed8565816d46fc9c997d1 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Thu, 8 Jan 2026 22:36:04 +0000 Subject: [PATCH 036/211] ci: switch release please to simple mode (#474) --- .release-please-manifest.json | 2 +- release-please-config.json | 13 +++++++++---- version.txt | 1 + 3 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 version.txt diff --git a/.release-please-manifest.json b/.release-please-manifest.json index a312649aa..c96cf72b3 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - "crates/delta": "0.8.8" + ".": "0.8.8" } \ No newline at end of file diff --git a/release-please-config.json b/release-please-config.json index a101f422e..bbc01a54e 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -1,14 +1,19 @@ { - "include-component-in-tag": false, "packages": { - "crates/delta": { - "changelog-path": "../../CHANGELOG.md", - "release-type": "rust", + ".": { + "changelog-path": "CHANGELOG.md", + "release-type": "simple", "bump-minor-pre-major": false, "bump-patch-for-minor-pre-major": false, "draft": false, "prerelease": false, + "include-component-in-tag": false, "extra-files": [ + { + "type": "toml", + "path": "crates/delta/Cargo.toml", + "jsonpath": "$.package.version" + }, { "type": "toml", "path": "crates/bonfire/Cargo.toml", diff --git a/version.txt b/version.txt new file mode 100644 index 000000000..5c5cbb3b8 --- /dev/null +++ b/version.txt @@ -0,0 +1 @@ +0.8.8 \ No newline at end of file From 924c7f5b1849f50ab56176672ed94c2c5a87bc30 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Thu, 8 Jan 2026 22:39:44 +0000 Subject: [PATCH 037/211] ci: bootstrap sha (#476) --- release-please-config.json | 1 + 1 file changed, 1 insertion(+) diff --git a/release-please-config.json b/release-please-config.json index bbc01a54e..c44e86e65 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -1,4 +1,5 @@ { + "bootstrap-sha": "0cf4a8ecc41c7984ba3ee5664dd979c5f14b59b4", "packages": { ".": { "changelog-path": "CHANGELOG.md", From e2016a2ab4a4bc3f292068027ca82c737e1217b4 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Thu, 8 Jan 2026 23:07:33 +0000 Subject: [PATCH 038/211] ci: add the dependency chain into release please (#477) --- crates/bonfire/Cargo.toml | 2 +- release-please-config.json | 200 +++++++++++++++++++++++++++++++++++++ 2 files changed, 201 insertions(+), 1 deletion(-) diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index 63badcce8..9a6055d67 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -42,7 +42,7 @@ revolt-result = { path = "../core/result" } revolt-models = { path = "../core/models" } revolt-config = { path = "../core/config" } revolt-database = { path = "../core/database", features = ["voice"] } -revolt-permissions = { version = "0.8.8", path = "../core/permissions" } +revolt-permissions = { path = "../core/permissions" } revolt-presence = { path = "../core/presence", features = ["redis-is-patched"] } # redis diff --git a/release-please-config.json b/release-please-config.json index c44e86e65..3a35283a3 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -30,21 +30,76 @@ "path": "crates/core/config/Cargo.toml", "jsonpath": "$.package.version" }, + { + "type": "toml", + "path": "crates/core/config/Cargo.toml", + "jsonpath": "$.dependencies['revolt-result'].version" + }, { "type": "toml", "path": "crates/core/database/Cargo.toml", "jsonpath": "$.package.version" }, + { + "type": "toml", + "path": "crates/core/database/Cargo.toml", + "jsonpath": "$.dependencies['revolt-config'].version" + }, + { + "type": "toml", + "path": "crates/core/database/Cargo.toml", + "jsonpath": "$.dependencies['revolt-result'].version" + }, + { + "type": "toml", + "path": "crates/core/database/Cargo.toml", + "jsonpath": "$.dependencies['revolt-models'].version" + }, + { + "type": "toml", + "path": "crates/core/database/Cargo.toml", + "jsonpath": "$.dependencies['revolt-presence'].version" + }, + { + "type": "toml", + "path": "crates/core/database/Cargo.toml", + "jsonpath": "$.dependencies['revolt-permissions'].version" + }, + { + "type": "toml", + "path": "crates/core/database/Cargo.toml", + "jsonpath": "$.dependencies['revolt-parser'].version" + }, { "type": "toml", "path": "crates/core/files/Cargo.toml", "jsonpath": "$.package.version" }, + { + "type": "toml", + "path": "crates/core/files/Cargo.toml", + "jsonpath": "$.dependencies['revolt-config'].version" + }, + { + "type": "toml", + "path": "crates/core/files/Cargo.toml", + "jsonpath": "$.dependencies['revolt-result'].version" + }, { "type": "toml", "path": "crates/core/models/Cargo.toml", "jsonpath": "$.package.version" }, + { + "type": "toml", + "path": "crates/core/models/Cargo.toml", + "jsonpath": "$.dependencies['revolt-config'].version" + }, + { + "type": "toml", + "path": "crates/core/models/Cargo.toml", + "jsonpath": "$.dependencies['revolt-permissions'].version" + }, { "type": "toml", "path": "crates/core/parser/Cargo.toml", @@ -55,16 +110,41 @@ "path": "crates/core/permissions/Cargo.toml", "jsonpath": "$.package.version" }, + { + "type": "toml", + "path": "crates/core/permissions/Cargo.toml", + "jsonpath": "$.dependencies['revolt-result'].version" + }, { "type": "toml", "path": "crates/core/presence/Cargo.toml", "jsonpath": "$.package.version" }, + { + "type": "toml", + "path": "crates/core/presence/Cargo.toml", + "jsonpath": "$.dependencies['revolt-config'].version" + }, { "type": "toml", "path": "crates/core/ratelimits/Cargo.toml", "jsonpath": "$.package.version" }, + { + "type": "toml", + "path": "crates/core/ratelimits/Cargo.toml", + "jsonpath": "$.dependencies['revolt-database'].version" + }, + { + "type": "toml", + "path": "crates/core/ratelimits/Cargo.toml", + "jsonpath": "$.dependencies['revolt-result'].version" + }, + { + "type": "toml", + "path": "crates/core/ratelimits/Cargo.toml", + "jsonpath": "$.dependencies['revolt-config'].version" + }, { "type": "toml", "path": "crates/core/result/Cargo.toml", @@ -75,11 +155,56 @@ "path": "crates/daemons/crond/Cargo.toml", "jsonpath": "$.package.version" }, + { + "type": "toml", + "path": "crates/daemons/crond/Cargo.toml", + "jsonpath": "$.dependencies['revolt-database'].version" + }, + { + "type": "toml", + "path": "crates/daemons/crond/Cargo.toml", + "jsonpath": "$.dependencies['revolt-result'].version" + }, + { + "type": "toml", + "path": "crates/daemons/crond/Cargo.toml", + "jsonpath": "$.dependencies['revolt-config'].version" + }, + { + "type": "toml", + "path": "crates/daemons/crond/Cargo.toml", + "jsonpath": "$.dependencies['revolt-files'].version" + }, { "type": "toml", "path": "crates/daemons/pushd/Cargo.toml", "jsonpath": "$.package.version" }, + { + "type": "toml", + "path": "crates/daemons/pushd/Cargo.toml", + "jsonpath": "$.dependencies['revolt-result'].version" + }, + { + "type": "toml", + "path": "crates/daemons/pushd/Cargo.toml", + "jsonpath": "$.dependencies['revolt-config'].version" + }, + { + "type": "toml", + "path": "crates/daemons/pushd/Cargo.toml", + "jsonpath": "$.dependencies['revolt-database'].version" + }, + { + "type": "toml", + "path": "crates/daemons/pushd/Cargo.toml", + "jsonpath": "$.dependencies['revolt-models'].version" + }, + { + "type": "toml", + "path": "crates/daemons/pushd/Cargo.toml", + "jsonpath": "$.dependencies['revolt-presence'].version" + }, { "type": "toml", "path": "crates/daemons/voice-ingress/Cargo.toml", @@ -90,15 +215,90 @@ "path": "crates/services/autumn/Cargo.toml", "jsonpath": "$.package.version" }, + { + "type": "toml", + "path": "crates/services/autumn/Cargo.toml", + "jsonpath": "$.dependencies['revolt-files'].version" + }, + { + "type": "toml", + "path": "crates/services/autumn/Cargo.toml", + "jsonpath": "$.dependencies['revolt-config'].version" + }, + { + "type": "toml", + "path": "crates/services/autumn/Cargo.toml", + "jsonpath": "$.dependencies['revolt-database'].version" + }, + { + "type": "toml", + "path": "crates/services/autumn/Cargo.toml", + "jsonpath": "$.dependencies['revolt-result'].version" + }, + { + "type": "toml", + "path": "crates/services/autumn/Cargo.toml", + "jsonpath": "$.dependencies['revolt-ratelimits'].version" + }, { "type": "toml", "path": "crates/services/gifbox/Cargo.toml", "jsonpath": "$.package.version" }, + { + "type": "toml", + "path": "crates/services/gifbox/Cargo.toml", + "jsonpath": "$.dependencies['revolt-config'].version" + }, + { + "type": "toml", + "path": "crates/services/gifbox/Cargo.toml", + "jsonpath": "$.dependencies['revolt-models'].version" + }, + { + "type": "toml", + "path": "crates/services/gifbox/Cargo.toml", + "jsonpath": "$.dependencies['revolt-result'].version" + }, + { + "type": "toml", + "path": "crates/services/gifbox/Cargo.toml", + "jsonpath": "$.dependencies['revolt-coalesced'].version" + }, + { + "type": "toml", + "path": "crates/services/gifbox/Cargo.toml", + "jsonpath": "$.dependencies['revolt-database'].version" + }, + { + "type": "toml", + "path": "crates/services/gifbox/Cargo.toml", + "jsonpath": "$.dependencies['revolt-ratelimits'].version" + }, { "type": "toml", "path": "crates/services/january/Cargo.toml", "jsonpath": "$.package.version" + }, + { + "type": "toml", + "path": "crates/services/january/Cargo.toml", + "jsonpath": "$.dependencies['revolt-config'].version" + }, + { + "type": "toml", + "path": "crates/services/january/Cargo.toml", + "jsonpath": "$.dependencies['revolt-models'].version" + }, + { + "type": "toml", + "path": "crates/services/january/Cargo.toml", + "jsonpath": "$.dependencies['revolt-result'].version" + }, + { + "type": "toml", + "path": "crates/services/january/Cargo.toml", + "jsonpath": "$.dependencies['revolt-files'].version" } ] } From 5d27a91e901dd2ea3e860aeaed8468db6c5f3214 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Fri, 9 Jan 2026 19:05:49 +0000 Subject: [PATCH 039/211] fix: correct miniz_oxide in lockfile (#478) --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 5772e212a..d3c759ee9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4742,7 +4742,7 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ From 0b178fc791583064bf9ca94b1d39b42d021e1d79 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Fri, 9 Jan 2026 19:10:01 +0000 Subject: [PATCH 040/211] fix: correct string_cache in lockfile (#479) --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index d3c759ee9..6320f82f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8236,7 +8236,7 @@ dependencies = [ [[package]] name = "string_cache" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" dependencies = [ From a5387b64af213081561305c2824ba9daefccb4bd Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Fri, 9 Jan 2026 19:21:45 +0000 Subject: [PATCH 041/211] ci: use dev-dependency for revolt-presence (#480) --- release-please-config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release-please-config.json b/release-please-config.json index 3a35283a3..bac633610 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -123,7 +123,7 @@ { "type": "toml", "path": "crates/core/presence/Cargo.toml", - "jsonpath": "$.dependencies['revolt-config'].version" + "jsonpath": "$['dev-dependencies']['revolt-config'].version" }, { "type": "toml", From 2afea56e56017f02de98e67316b4457568ad5b26 Mon Sep 17 00:00:00 2001 From: Angelo Kontaxis Date: Fri, 9 Jan 2026 20:06:16 +0000 Subject: [PATCH 042/211] feat: add id field to role (#470) --- .../database/fixtures/server_with_roles.json | 2 + .../admin_migrations/ops/mongodb/scripts.rs | 46 ++++++++++++++++++- .../core/database/src/models/servers/model.rs | 43 ++++++++++------- .../core/database/src/models/servers/ops.rs | 2 +- .../src/models/servers/ops/mongodb.rs | 4 +- .../src/models/servers/ops/reference.rs | 4 +- crates/core/database/src/util/bridge/v0.rs | 4 ++ crates/core/models/src/v0/servers.rs | 4 ++ .../fixtures/server_with_many_roles.json | 4 ++ .../delta/src/routes/channels/message_send.rs | 33 +++++-------- .../delta/src/routes/servers/roles_create.rs | 11 +---- .../delta/src/routes/servers/roles_delete.rs | 2 +- crates/delta/src/routes/servers/roles_edit.rs | 1 - crates/delta/src/util/test.rs | 33 +++++++------ 14 files changed, 124 insertions(+), 69 deletions(-) diff --git a/crates/core/database/fixtures/server_with_roles.json b/crates/core/database/fixtures/server_with_roles.json index 0a76489dd..21ea5656e 100644 --- a/crates/core/database/fixtures/server_with_roles.json +++ b/crates/core/database/fixtures/server_with_roles.json @@ -47,6 +47,7 @@ ], "roles": { "__ID:5__": { + "_id": "__ID:5__", "name": "Moderator", "permissions": { "a": 545270208, @@ -55,6 +56,7 @@ "rank": 1 }, "__ID:6__": { + "_id": "__ID:6__", "name": "Owner", "permissions": { "a": 0, diff --git a/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs b/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs index 472f665e9..174a81a62 100644 --- a/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs +++ b/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs @@ -25,7 +25,7 @@ struct MigrationInfo { revision: i32, } -pub const LATEST_REVISION: i32 = 49; // MUST BE +1 to last migration +pub const LATEST_REVISION: i32 = 50; // MUST BE +1 to last migration pub async fn migrate_database(db: &MongoDb) { let migrations = db.col::("migrations"); @@ -1246,7 +1246,7 @@ pub async fn run_migrations(db: &MongoDb, revision: i32) -> i32 { .expect("Failed to update voice channels"); }; - if revision <= 48 { + if revision <= 48 { info!("Running migration [revision 48 / 22-10-2025]: Add Video + Listen to default permissions"); db.col::("servers") @@ -1264,6 +1264,48 @@ pub async fn run_migrations(db: &MongoDb, revision: i32) -> i32 { .expect("Failed to update default_permissions"); }; + if revision <= 49 { + info!("Running migration [revision 49 / 12-12-2025]: Add _id key to roles"); + + #[derive(Serialize, Deserialize, Clone)] + struct Server { + #[serde(rename = "_id")] + pub id: String, + #[serde(default = "HashMap::::new")] + pub roles: HashMap, + } + + let mut servers = db + .db() + .collection::("servers") + .find(doc! { + "roles": { + "$exists": true, + "$ne": {} + } + }) + .await + .unwrap() + .map(|res| res.expect("Failed to decode Server { id, roles }")); + + while let Some(server) = servers.next().await { + let mut doc = doc! {}; + + for id in server.roles.keys() { + doc.insert( + format!("roles.{id}._id"), + id, + ); + } + + db.db() + .collection::("servers") + .update_one(doc! { "_id": &server.id }, doc! { "$set": doc }) + .await + .unwrap(); + } + }; + // Reminder to update LATEST_REVISION when adding new migrations. LATEST_REVISION.max(revision) } diff --git a/crates/core/database/src/models/servers/model.rs b/crates/core/database/src/models/servers/model.rs index eea8f3922..183dd3d2d 100644 --- a/crates/core/database/src/models/servers/model.rs +++ b/crates/core/database/src/models/servers/model.rs @@ -68,6 +68,9 @@ auto_derived_partial!( auto_derived_partial!( /// Role pub struct Role { + /// Unique Id + #[serde(rename = "_id")] + pub id: String, /// Role name pub name: String, /// Permissions available to this role @@ -246,7 +249,6 @@ impl Server { role.update( db, &self.id, - role_id, PartialRole { permissions: Some(permissions), ..Default::default() @@ -297,6 +299,7 @@ impl Role { /// Into optional struct pub fn into_optional(self) -> PartialRole { PartialRole { + id: Some(self.id), name: Some(self.name), permissions: Some(self.permissions), colour: self.colour, @@ -306,20 +309,29 @@ impl Role { } /// Create a role - pub async fn create(&self, db: &Database, server_id: &str) -> Result { - let role_id = Ulid::new().to_string(); - db.insert_role(server_id, &role_id, self).await?; + pub async fn create(db: &Database, server: &Server, name: String) -> Result { + let role = Role { + id: Ulid::new().to_string(), + name, + // Rank of the new role should be below the lowest role + rank: server.roles.len() as i64, + colour: None, + hoist: false, + permissions: Default::default(), + }; + + db.insert_role(&server.id, &role).await?; EventV1::ServerRoleUpdate { - id: server_id.to_string(), - role_id: role_id.to_string(), - data: self.clone().into_optional().into(), + id: server.id.clone(), + role_id: role.id.clone(), + data: role.clone().into_optional().into(), clear: vec![], } - .p(server_id.to_string()) + .p(server.id.clone()) .await; - Ok(role_id) + Ok(role) } /// Update server data @@ -327,7 +339,6 @@ impl Role { &mut self, db: &Database, server_id: &str, - role_id: &str, partial: PartialRole, remove: Vec, ) -> Result<()> { @@ -337,14 +348,14 @@ impl Role { self.apply_options(partial.clone()); - db.update_role(server_id, role_id, &partial, remove.clone()) + db.update_role(server_id, &self.id, &partial, remove.clone()) .await?; EventV1::ServerRoleUpdate { id: server_id.to_string(), - role_id: role_id.to_string(), + role_id: self.id.clone(), data: partial.into(), - clear: vec![], + clear: remove.into_iter().map(Into::into).collect(), } .p(server_id.to_string()) .await; @@ -360,15 +371,15 @@ impl Role { } /// Delete a role - pub async fn delete(self, db: &Database, server_id: &str, role_id: &str) -> Result<()> { + pub async fn delete(self, db: &Database, server_id: &str) -> Result<()> { EventV1::ServerRoleDelete { id: server_id.to_string(), - role_id: role_id.to_string(), + role_id: self.id.clone(), } .p(server_id.to_string()) .await; - db.delete_role(server_id, role_id).await + db.delete_role(server_id, &self.id).await } } diff --git a/crates/core/database/src/models/servers/ops.rs b/crates/core/database/src/models/servers/ops.rs index ee07ba8ff..c7ae6228d 100644 --- a/crates/core/database/src/models/servers/ops.rs +++ b/crates/core/database/src/models/servers/ops.rs @@ -29,7 +29,7 @@ pub trait AbstractServers: Sync + Send { async fn delete_server(&self, id: &str) -> Result<()>; /// Insert a new role into server object - async fn insert_role(&self, server_id: &str, role_id: &str, role: &Role) -> Result<()>; + async fn insert_role(&self, server_id: &str, role: &Role) -> Result<()>; /// Update an existing role on a server async fn update_role( diff --git a/crates/core/database/src/models/servers/ops/mongodb.rs b/crates/core/database/src/models/servers/ops/mongodb.rs index 958963c9c..ecdff53bf 100644 --- a/crates/core/database/src/models/servers/ops/mongodb.rs +++ b/crates/core/database/src/models/servers/ops/mongodb.rs @@ -69,7 +69,7 @@ impl AbstractServers for MongoDb { } /// Insert a new role into server object - async fn insert_role(&self, server_id: &str, role_id: &str, role: &Role) -> Result<()> { + async fn insert_role(&self, server_id: &str, role: &Role) -> Result<()> { self.col::(COL) .update_one( doc! { @@ -77,7 +77,7 @@ impl AbstractServers for MongoDb { }, doc! { "$set": { - "roles.".to_owned() + role_id: to_document(role) + "roles.".to_owned() + &role.id: to_document(role) .map_err(|_| create_database_error!("to_document", "role"))? } }, diff --git a/crates/core/database/src/models/servers/ops/reference.rs b/crates/core/database/src/models/servers/ops/reference.rs index 18ee1b384..572311bde 100644 --- a/crates/core/database/src/models/servers/ops/reference.rs +++ b/crates/core/database/src/models/servers/ops/reference.rs @@ -72,10 +72,10 @@ impl AbstractServers for ReferenceDb { } /// Insert a new role into server object - async fn insert_role(&self, server_id: &str, role_id: &str, role: &Role) -> Result<()> { + async fn insert_role(&self, server_id: &str, role: &Role) -> Result<()> { let mut servers = self.servers.lock().await; if let Some(server) = servers.get_mut(server_id) { - server.roles.insert(role_id.to_string(), role.clone()); + server.roles.insert(role.id.clone(), role.clone()); Ok(()) } else { Err(create_error!(NotFound)) diff --git a/crates/core/database/src/util/bridge/v0.rs b/crates/core/database/src/util/bridge/v0.rs index 915b75ce1..de63db907 100644 --- a/crates/core/database/src/util/bridge/v0.rs +++ b/crates/core/database/src/util/bridge/v0.rs @@ -896,6 +896,7 @@ impl From for crate::SystemMessageChannels { impl From for Role { fn from(value: crate::Role) -> Self { Role { + id: value.id, name: value.name, permissions: value.permissions, colour: value.colour, @@ -908,6 +909,7 @@ impl From for Role { impl From for crate::Role { fn from(value: Role) -> crate::Role { crate::Role { + id: value.id, name: value.name, permissions: value.permissions, colour: value.colour, @@ -920,6 +922,7 @@ impl From for crate::Role { impl From for PartialRole { fn from(value: crate::PartialRole) -> Self { PartialRole { + id: value.id, name: value.name, permissions: value.permissions, colour: value.colour, @@ -932,6 +935,7 @@ impl From for PartialRole { impl From for crate::PartialRole { fn from(value: PartialRole) -> crate::PartialRole { crate::PartialRole { + id: value.id, name: value.name, permissions: value.permissions, colour: value.colour, diff --git a/crates/core/models/src/v0/servers.rs b/crates/core/models/src/v0/servers.rs index c3ed20a8b..0d330334c 100644 --- a/crates/core/models/src/v0/servers.rs +++ b/crates/core/models/src/v0/servers.rs @@ -85,6 +85,9 @@ auto_derived_partial!( auto_derived_partial!( /// Role pub struct Role { + /// Unique Id + #[cfg_attr(feature = "serde", serde(rename = "_id"))] + pub id: String, /// Role name pub name: String, /// Permissions available to this role @@ -181,6 +184,7 @@ auto_derived!( } /// Response after creating new role + // TODO: remove this in favor of just Role pub struct NewRoleResponse { /// Id of the role pub id: String, diff --git a/crates/delta/fixtures/server_with_many_roles.json b/crates/delta/fixtures/server_with_many_roles.json index 49cfe276c..c32529a51 100644 --- a/crates/delta/fixtures/server_with_many_roles.json +++ b/crates/delta/fixtures/server_with_many_roles.json @@ -47,6 +47,7 @@ ], "roles": { "__ID:5__": { + "_id": "__ID:5__", "name": "Moderator", "permissions": { "a": 545270216, @@ -55,6 +56,7 @@ "rank": 1 }, "__ID:6__": { + "_id": "__ID:6__", "name": "Owner", "permissions": { "a": 0, @@ -63,6 +65,7 @@ "rank": 0 }, "__ID:7__": { + "_id": "__ID:7__", "name": "Lower Rank 1", "permissions": { "a": 0, @@ -71,6 +74,7 @@ "rank": 2 }, "__ID:8__": { + "_id": "__ID:8__", "name": "Lower Rank 2", "permissions": { "a": 0, diff --git a/crates/delta/src/routes/channels/message_send.rs b/crates/delta/src/routes/channels/message_send.rs index e0dac2765..d0479fa1a 100644 --- a/crates/delta/src/routes/channels/message_send.rs +++ b/crates/delta/src/routes/channels/message_send.rs @@ -151,29 +151,20 @@ mod test { name: "Hidden Channel".to_string(), description: None, nsfw: Some(false), - voice: None + voice: None, }, true, ) .await .expect("Failed to make new channel"); - let role = Role { - name: "Show Hidden Channel".to_string(), - permissions: OverrideField { a: 0, d: 0 }, - colour: None, - hoist: false, - rank: 5, - }; - - let role_id = role - .create(&harness.db, &server.id) + let role = Role::create(&harness.db, &server, "Show Hidden Channel".to_string()) .await .expect("Failed to create the role"); let mut overrides = HashMap::new(); overrides.insert( - role_id.clone(), + role.id.clone(), OverrideField { a: (ChannelPermission::ViewChannel) as i64, d: 0, @@ -281,7 +272,7 @@ mod test { "Mention failed to be scrubbed when the user cannot see the channel" ); - let second_member_roles = vec![role_id.clone()]; + let second_member_roles = vec![role.id.clone()]; let partial = PartialMember { id: None, joined_at: None, @@ -290,7 +281,7 @@ mod test { timeout: None, roles: Some(second_member_roles), can_publish: None, - can_receive: None + can_receive: None, }; second_member .update(&harness.db, partial, vec![]) @@ -496,7 +487,7 @@ mod test { let (_, _, other_user) = harness.new_user().await; let (server, _) = harness.new_server(&user).await; let channel = harness.new_channel(&server).await; - let (role_id, _role) = harness + let role = harness .new_role( &server, 1, @@ -518,7 +509,7 @@ mod test { Some(&harness.amqp), channel.clone(), v0::DataMessageSend { - content: Some(format!("Mentioning @everyone and role <%{}>", &role_id)), + content: Some(format!("Mentioning @everyone and role <%{}>", &role.id)), nonce: None, attachments: None, replies: None, @@ -563,7 +554,7 @@ mod test { Some(&harness.amqp), channel.clone(), v0::DataMessageSend { - content: Some(format!("Mentioning `@everyone` and role `<%{}>`", &role_id)), + content: Some(format!("Mentioning `@everyone` and role `<%{}>`", &role.id)), nonce: None, attachments: None, replies: None, @@ -605,7 +596,7 @@ mod test { "Role mentions detected when inside codeblock" ); - other_member.roles.push(role_id.clone()); + other_member.roles.push(role.id.clone()); harness .db .update_member( @@ -615,10 +606,10 @@ mod test { id: None, joined_at: None, nickname: None, - roles: Some(vec![role_id.clone()]), + roles: Some(vec![role.id.clone()]), timeout: None, can_publish: None, - can_receive: None + can_receive: None, }, vec![], ) @@ -632,7 +623,7 @@ mod test { Some(&harness.amqp), channel.clone(), v0::DataMessageSend { - content: Some(format!("Mentioning @everyone and role <%{}>", &role_id)), + content: Some(format!("Mentioning @everyone and role <%{}>", &role.id)), nonce: None, attachments: None, replies: None, diff --git a/crates/delta/src/routes/servers/roles_create.rs b/crates/delta/src/routes/servers/roles_create.rs index e68d5ea6a..20a3c94ba 100644 --- a/crates/delta/src/routes/servers/roles_create.rs +++ b/crates/delta/src/routes/servers/roles_create.rs @@ -40,17 +40,10 @@ pub async fn create( })); }; - let role = Role { - name: data.name, - // Rank of the new role should be below the lowest role - rank: server.roles.len() as i64, - colour: None, - hoist: false, - permissions: Default::default(), - }; + let role = Role::create(db, &server, data.name).await?; Ok(Json(v0::NewRoleResponse { - id: role.create(db, &server.id).await?, + id: role.id.clone(), role: role.into(), })) } diff --git a/crates/delta/src/routes/servers/roles_delete.rs b/crates/delta/src/routes/servers/roles_delete.rs index 77df2501d..232ae92ef 100644 --- a/crates/delta/src/routes/servers/roles_delete.rs +++ b/crates/delta/src/routes/servers/roles_delete.rs @@ -37,7 +37,7 @@ pub async fn delete( return Err(create_error!(NotElevated)); } - role.delete(db, &server.id, &role_id).await?; + role.delete(db, &server.id).await?; for channel_id in &server.channels { let channel = Reference::from_unchecked(channel_id).as_channel(db).await?; diff --git a/crates/delta/src/routes/servers/roles_edit.rs b/crates/delta/src/routes/servers/roles_edit.rs index 639589afa..0a122c1fb 100644 --- a/crates/delta/src/routes/servers/roles_edit.rs +++ b/crates/delta/src/routes/servers/roles_edit.rs @@ -61,7 +61,6 @@ pub async fn edit( role.update( db, &server.id, - &role_id, partial, remove.into_iter().map(Into::into).collect(), ) diff --git a/crates/delta/src/util/test.rs b/crates/delta/src/util/test.rs index b90a1a5cd..a62515091 100644 --- a/crates/delta/src/util/test.rs +++ b/crates/delta/src/util/test.rs @@ -6,7 +6,7 @@ use futures::StreamExt; use rand::Rng; use redis_kiss::redis::aio::PubSub; use revolt_database::{ - events::client::EventV1, Channel, Database, Member, Message, Server, User, AMQP, + events::client::EventV1, Channel, Database, Member, Message, PartialRole, Server, User, AMQP, }; use revolt_database::{util::idempotency::IdempotencyKey, Role}; use revolt_models::v0; @@ -139,21 +139,26 @@ impl TestHarness { server: &Server, rank: i64, overrides: Option, - ) -> (String, Role) { - let role = Role { - name: TestHarness::rand_string(), - permissions: overrides.unwrap_or(OverrideField { a: 0, d: 0 }), - rank, - colour: None, - hoist: false, - }; - - let id = role - .create(&self.db, &server.id) + ) -> Role { + let mut role = Role::create(&self.db, &server, TestHarness::rand_string()) .await .expect("Failed to create test role"); - (id, role) + if let Some(overrides) = overrides { + role.update( + &self.db, + &server.id, + PartialRole { + permissions: Some(overrides), + ..Default::default() + }, + Vec::new(), + ) + .await + .expect("Failed to set test role overrides"); + }; + + role } pub async fn new_channel(&self, server: &Server) -> Channel { @@ -165,7 +170,7 @@ impl TestHarness { name: "Test Channel".to_string(), description: None, nsfw: Some(false), - voice: None + voice: None, }, true, ) From f89ee5a370d864510076f75b51f0d87320bfe862 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Fri, 9 Jan 2026 21:05:42 +0000 Subject: [PATCH 043/211] ci: send release notification on create (#481) --- .github/workflows/docker.yaml | 1 + .github/workflows/release-please.yml | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index e12f3a8bb..997a98d9b 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -7,6 +7,7 @@ on: pull_request: paths: - "Dockerfile" + workflow_dispatch: permissions: contents: read diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 8b5215639..69b53a2e4 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -20,6 +20,7 @@ jobs: runs-on: ubuntu-latest outputs: release_created: ${{ steps.rp.outputs.release_created }} + tag_name: ${{ steps.rp.outputs.tag_name }} steps: - id: app-token uses: actions/create-github-app-token@v2 @@ -32,8 +33,8 @@ jobs: token: ${{ steps.app-token.outputs.token }} config-file: release-please-config.json - publish-stable: - name: Publish release to stable branch + publish-please: + name: Publish Please needs: release-please if: needs.release-please.outputs.release_created == 'true' runs-on: ubuntu-latest @@ -44,6 +45,15 @@ jobs: with: app-id: ${{ secrets.GH_STOAT_RELEASE_APP_ID }} private-key: ${{ secrets.GH_STOAT_RELEASE_APP_PRIVATE_KEY }} - - uses: katyo/publish-crates@v2 + + - name: Send release notification webhook + run: | + RELEASE_URL="https://github.com/revoltchat/backend/releases/tag/${{ needs.release-please.outputs.tag_name }}" + curl -X POST "${{ secrets.STOAT_WEBHOOK_UPDATES_URL }}" \ + -H "Content-Type: application/json" \ + -d "{\"content\": \"$RELEASE_URL\"}" + + - name: Publish crates + uses: katyo/publish-crates@v2 with: registry-token: ${{ secrets.CRATES_IO_PUBLISH_TOKEN }} From 67d49b461f4d9610d746ad053e65181f6b4dbf41 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Sat, 10 Jan 2026 12:44:26 +0000 Subject: [PATCH 044/211] ci: use our arc runner set for Rust builds (#482) --- .github/workflows/docker.yaml | 4 ++-- .github/workflows/rust.yaml | 35 +++++++++++++++++------------------ 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 997a98d9b..85cd31269 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -20,7 +20,7 @@ concurrency: jobs: base: name: Test base image build - runs-on: ubuntu-latest + runs-on: arc-runner-set if: github.event_name == 'pull_request' steps: # Configure build environment @@ -41,7 +41,7 @@ jobs: cache-to: type=gha,scope=buildx-base-multi-arch,mode=max publish: - runs-on: self-hosted + runs-on: arc-runner-set if: github.event_name != 'pull_request' name: Publish Docker images steps: diff --git a/.github/workflows/rust.yaml b/.github/workflows/rust.yaml index ceb2c9188..359c30191 100644 --- a/.github/workflows/rust.yaml +++ b/.github/workflows/rust.yaml @@ -15,29 +15,28 @@ env: jobs: check: name: Rust project - runs-on: ubuntu-latest + runs-on: arc-runner-set steps: - - uses: actions/checkout@v2 - - name: Free up disk space - run: | - sudo rm -rf /usr/local/lib/android /usr/share/dotnet /opt/ghc + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + + # Using our own runners for now: + # - name: Free up disk space + # run: | + # sudo rm -rf /usr/local/lib/android /usr/share/dotnet /opt/ghc - name: Install latest stable - uses: actions-rs/toolchain@v1 + uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # v1 with: toolchain: stable - override: true components: rustfmt, clippy + - name: Install cargo-nextest - uses: baptiste0928/cargo-install@v1 + uses: taiki-e/install-action@a58ae9526b2c3acee9ad8e1926b950b7863305d4 # 2.65.16 with: - crate: cargo-nextest - args: --locked + tool: cargo-nextest@0.9.119 - name: Run cargo build - uses: actions-rs/cargo@v1 - with: - command: build + run: cargo build - name: Run services in background run: | @@ -65,13 +64,13 @@ jobs: - name: Wait for API to go up if: github.event_name != 'pull_request' && github.ref_name == 'main' - uses: nev7n/wait_for_response@v1 + uses: nev7n/wait_for_response@7fef3c1a6e8939d0b09062f14fec50d3c5d15fa1 # v1.0.1 with: url: "http://localhost:14702/" - name: Checkout API repository if: github.event_name != 'pull_request' && github.ref_name == 'main' - uses: actions/checkout@v3 + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: repository: stoatchat/javascript-client-api path: api @@ -83,10 +82,10 @@ jobs: - name: Commit changes if: github.event_name != 'pull_request' && github.ref_name == 'main' - uses: EndBug/add-and-commit@v4 + uses: EndBug/add-and-commit@a94899bca583c204427a224a7af87c02f9b325d5 # v9.1.4 with: cwd: "api" add: "*.json" - author_name: Revolt CI - author_email: revolt-ci@users.noreply.github.com + author_name: Stoat CI + author_email: stoat-ci@users.noreply.github.com message: "chore: generate OpenAPI specification" From 868894f500ae8a58a2324c48d28947714b2f512f Mon Sep 17 00:00:00 2001 From: "stoat-release[bot]" <245062572+stoat-release[bot]@users.noreply.github.com> Date: Sat, 10 Jan 2026 12:51:09 +0000 Subject: [PATCH 045/211] chore(main): release 0.9.0 (#475) Co-authored-by: stoat-release[bot] <245062572+stoat-release[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 44 +++++++++++++++++++++++++ crates/bonfire/Cargo.toml | 2 +- crates/core/coalesced/Cargo.toml | 2 +- crates/core/config/Cargo.toml | 4 +-- crates/core/database/Cargo.toml | 14 ++++---- crates/core/files/Cargo.toml | 6 ++-- crates/core/models/Cargo.toml | 6 ++-- crates/core/parser/Cargo.toml | 2 +- crates/core/permissions/Cargo.toml | 4 +-- crates/core/presence/Cargo.toml | 4 +-- crates/core/ratelimits/Cargo.toml | 8 ++--- crates/core/result/Cargo.toml | 2 +- crates/daemons/crond/Cargo.toml | 10 +++--- crates/daemons/pushd/Cargo.toml | 12 +++---- crates/daemons/voice-ingress/Cargo.toml | 2 +- crates/delta/Cargo.toml | 2 +- crates/services/autumn/Cargo.toml | 12 +++---- crates/services/gifbox/Cargo.toml | 14 ++++---- crates/services/january/Cargo.toml | 10 +++--- version.txt | 2 +- 21 files changed, 104 insertions(+), 60 deletions(-) create mode 100644 CHANGELOG.md diff --git a/.release-please-manifest.json b/.release-please-manifest.json index c96cf72b3..2101ae57f 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.8.8" + ".": "0.9.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..7b7ab6351 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,44 @@ +# Changelog + +## [0.9.0](https://github.com/stoatchat/stoatchat/compare/v0.8.8...v0.9.0) (2026-01-10) + + +### Features + +* add id field to role ([#470](https://github.com/stoatchat/stoatchat/issues/470)) ([2afea56](https://github.com/stoatchat/stoatchat/commit/2afea56e56017f02de98e67316b4457568ad5b26)) +* add ratelimits to gifbox ([1542047](https://github.com/stoatchat/stoatchat/commit/154204742d21cbeff6e2577b00f50b495ea44631)) +* include groups and dms in fetch mutuals ([caa8607](https://github.com/stoatchat/stoatchat/commit/caa86074680d46223cebc20f41e9c91c41ec825d)) +* include member payload in ServerMemberJoin event ([480f210](https://github.com/stoatchat/stoatchat/commit/480f210ce85271e13d1dac58a5dae08de108579d)) +* initial work on tenor gif searching ([b0c977b](https://github.com/stoatchat/stoatchat/commit/b0c977b324b8144c1152589546eb8fec5954c3e7)) +* make message lexer use unowned string ([1561481](https://github.com/stoatchat/stoatchat/commit/1561481eb4cdc0f385fbf0a81e4950408050e11f)) +* ready payload field customisation ([db57706](https://github.com/stoatchat/stoatchat/commit/db577067948f13e830b5fb773034e9713a1abaff)) +* require auth for search ([b5cd5e3](https://github.com/stoatchat/stoatchat/commit/b5cd5e30ef7d5e56e8964fb7c543965fa6bf5a4a)) +* trending and categories routes ([5885e06](https://github.com/stoatchat/stoatchat/commit/5885e067a627b8fff1c8ce2bf9e852ff8cf3f07a)) +* voice chats v2 ([#414](https://github.com/stoatchat/stoatchat/issues/414)) ([d567155](https://github.com/stoatchat/stoatchat/commit/d567155f124e4da74115b1a8f810062f7c6559d9)) + + +### Bug Fixes + +* add license to revolt-parser ([5335124](https://github.com/stoatchat/stoatchat/commit/53351243064cac8d499dd74284be73928fa78a43)) +* allow for disabling default features ([65fbd36](https://github.com/stoatchat/stoatchat/commit/65fbd3662462aed1333b79e59155fa6377e83fcc)) +* apple music to use original url instead of metadata url ([bfe4018](https://github.com/stoatchat/stoatchat/commit/bfe4018e436a4075bae780dd4d35a9b58315e12f)) +* apply uname fix to january and autumn ([8f9015a](https://github.com/stoatchat/stoatchat/commit/8f9015a6ff181d208d9269ab8691bd417d39811a)) +* **ci:** publish images under stoatchat and remove docker hub ([d65c1a1](https://github.com/stoatchat/stoatchat/commit/d65c1a1ab3bdc7e5684b03f280af77d881661a3d)) +* correct miniz_oxide in lockfile ([#478](https://github.com/stoatchat/stoatchat/issues/478)) ([5d27a91](https://github.com/stoatchat/stoatchat/commit/5d27a91e901dd2ea3e860aeaed8468db6c5f3214)) +* correct shebang for try-tag-and-release ([050ba16](https://github.com/stoatchat/stoatchat/commit/050ba16d4adad5d0fb247867aa3e94e3d42bd12d)) +* correct string_cache in lockfile ([#479](https://github.com/stoatchat/stoatchat/issues/479)) ([0b178fc](https://github.com/stoatchat/stoatchat/commit/0b178fc791583064bf9ca94b1d39b42d021e1d79)) +* don't remove timeouts when a member leaves a server ([#409](https://github.com/stoatchat/stoatchat/issues/409)) ([e635bc2](https://github.com/stoatchat/stoatchat/commit/e635bc23ec857d648d5705e1a3875d7bc3402b0d)) +* don't update the same field while trying to remove it ([f4ee35f](https://github.com/stoatchat/stoatchat/commit/f4ee35fb093ca49f0a64ff4b17fd61587df28145)), closes [#392](https://github.com/stoatchat/stoatchat/issues/392) +* github webhook incorrect payload and formatting ([#468](https://github.com/stoatchat/stoatchat/issues/468)) ([dc9c82a](https://github.com/stoatchat/stoatchat/commit/dc9c82aa4e9667ea6639256c65ac8de37a24d1f7)) +* implement Serialize to ClientMessage ([dea0f67](https://github.com/stoatchat/stoatchat/commit/dea0f675dde7a63c7a59b38d469f878b7a8a3af4)) +* newly created roles should be ranked the lowest ([947eb15](https://github.com/stoatchat/stoatchat/commit/947eb15771ed6785b3dcd16c354c03ded5e4cbe0)) +* permit empty `remove` array in edit requests ([6ad3da5](https://github.com/stoatchat/stoatchat/commit/6ad3da5f35f989a2e7d8e29718b98374248e76af)) +* preserve order of replies in message ([#447](https://github.com/stoatchat/stoatchat/issues/447)) ([657a3f0](https://github.com/stoatchat/stoatchat/commit/657a3f08e5d652814bbf0647e089ed9ebb139bbf)) +* prevent timing out members which have TimeoutMembers permission ([e36fc97](https://github.com/stoatchat/stoatchat/commit/e36fc9738bac0de4f3fcbccba521f1e3754f7ae7)) +* relax settings name regex ([3a34159](https://github.com/stoatchat/stoatchat/commit/3a3415915f0d0fdce1499d47a2b7fa097f5946ea)) +* remove authentication tag bytes from attachment download ([32e6600](https://github.com/stoatchat/stoatchat/commit/32e6600272b885c595c094f0bc69459250220dcb)) +* rename openapi operation ids ([6048587](https://github.com/stoatchat/stoatchat/commit/6048587d348fbca0dc3a9b47690c56df8fece576)), closes [#406](https://github.com/stoatchat/stoatchat/issues/406) +* respond with 201 if no body in requests ([#465](https://github.com/stoatchat/stoatchat/issues/465)) ([24fedf8](https://github.com/stoatchat/stoatchat/commit/24fedf8c4d9cd3160bdec97aa451520f8beaa739)) +* swap to using reqwest for query building ([38dd4d1](https://github.com/stoatchat/stoatchat/commit/38dd4d10797b3e6e397fc219e818f379bdff19f2)) +* use `trust_cloudflare` config value instead of env var ([cc7a796](https://github.com/stoatchat/stoatchat/commit/cc7a7962a882e1627fcd0bc75858a017415e8cfc)) +* use our own result types instead of tenors types ([a92152d](https://github.com/stoatchat/stoatchat/commit/a92152d86da136997817e797c7af8e38731cdde8)) diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index 9a6055d67..13bca0d69 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-bonfire" -version = "0.8.8" +version = "0.9.0" license = "AGPL-3.0-or-later" edition = "2021" diff --git a/crates/core/coalesced/Cargo.toml b/crates/core/coalesced/Cargo.toml index cb23a8adb..96d53b230 100644 --- a/crates/core/coalesced/Cargo.toml +++ b/crates/core/coalesced/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-coalesced" -version = "0.8.8" +version = "0.9.0" edition = "2021" license = "MIT" authors = ["Paul Makles ", "Zomatree "] diff --git a/crates/core/config/Cargo.toml b/crates/core/config/Cargo.toml index 26cc1c25f..00480fcba 100644 --- a/crates/core/config/Cargo.toml +++ b/crates/core/config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-config" -version = "0.8.8" +version = "0.9.0" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -37,4 +37,4 @@ sentry = { version = "0.31.5", optional = true } sentry-anyhow = { version = "0.38.1", optional = true } # Core -revolt-result = { version = "0.8.8", path = "../result", optional = true } +revolt-result = { version = "0.9.0", path = "../result", optional = true } diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index 9abdcbf19..a2ac060af 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-database" -version = "0.8.8" +version = "0.9.0" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -25,19 +25,19 @@ default = ["mongodb", "async-std-runtime", "tasks"] [dependencies] # Core -revolt-config = { version = "0.8.8", path = "../config", features = [ +revolt-config = { version = "0.9.0", path = "../config", features = [ "report-macros", ] } -revolt-result = { version = "0.8.8", path = "../result" } -revolt-models = { version = "0.8.8", path = "../models", features = [ +revolt-result = { version = "0.9.0", path = "../result" } +revolt-models = { version = "0.9.0", path = "../models", features = [ "validator", ] } -revolt-presence = { version = "0.8.8", path = "../presence" } -revolt-permissions = { version = "0.8.8", path = "../permissions", features = [ +revolt-presence = { version = "0.9.0", path = "../presence" } +revolt-permissions = { version = "0.9.0", path = "../permissions", features = [ "serde", "bson", ] } -revolt-parser = { version = "0.8.8", path = "../parser" } +revolt-parser = { version = "0.9.0", path = "../parser" } # Utility log = "0.4" diff --git a/crates/core/files/Cargo.toml b/crates/core/files/Cargo.toml index 7cc219f1c..510e46c6a 100644 --- a/crates/core/files/Cargo.toml +++ b/crates/core/files/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-files" -version = "0.8.8" +version = "0.9.0" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -20,10 +20,10 @@ typenum = "1.17.0" aws-config = "1.5.5" aws-sdk-s3 = { version = "1.46.0", features = ["behavior-version-latest"] } -revolt-config = { version = "0.8.8", path = "../config", features = [ +revolt-config = { version = "0.9.0", path = "../config", features = [ "report-macros", ] } -revolt-result = { version = "0.8.8", path = "../result" } +revolt-result = { version = "0.9.0", path = "../result" } # image processing jxl-oxide = "0.8.1" diff --git a/crates/core/models/Cargo.toml b/crates/core/models/Cargo.toml index e232fd6cc..be918579e 100644 --- a/crates/core/models/Cargo.toml +++ b/crates/core/models/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-models" -version = "0.8.8" +version = "0.9.0" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -20,8 +20,8 @@ default = ["serde", "partials", "rocket"] [dependencies] # Core -revolt-config = { version = "0.8.8", path = "../config" } -revolt-permissions = { version = "0.8.8", path = "../permissions" } +revolt-config = { version = "0.9.0", path = "../config" } +revolt-permissions = { version = "0.9.0", path = "../permissions" } # Utility regex = "1.11" diff --git a/crates/core/parser/Cargo.toml b/crates/core/parser/Cargo.toml index a6e1869b7..912e1de66 100644 --- a/crates/core/parser/Cargo.toml +++ b/crates/core/parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-parser" -version = "0.8.8" +version = "0.9.0" edition = "2021" license = "MIT" authors = ["Zomatree ", "Paul Makles "] diff --git a/crates/core/permissions/Cargo.toml b/crates/core/permissions/Cargo.toml index d5ee32165..439af354f 100644 --- a/crates/core/permissions/Cargo.toml +++ b/crates/core/permissions/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-permissions" -version = "0.8.8" +version = "0.9.0" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -21,7 +21,7 @@ async-std = { version = "1.8.0", features = ["attributes"] } [dependencies] # Core -revolt-result = { version = "0.8.8", path = "../result" } +revolt-result = { version = "0.9.0", path = "../result" } # Utility auto_ops = "0.3.0" diff --git a/crates/core/presence/Cargo.toml b/crates/core/presence/Cargo.toml index 2e53c3e70..6bffe55cd 100644 --- a/crates/core/presence/Cargo.toml +++ b/crates/core/presence/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-presence" -version = "0.8.8" +version = "0.9.0" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -16,7 +16,7 @@ redis-is-patched = [] async-std = { version = "1.8.0", features = ["attributes"] } # Config for loading Redis URI -revolt-config = { version = "0.8.8", path = "../config" } +revolt-config = { version = "0.9.0", path = "../config" } [dependencies] # Utility diff --git a/crates/core/ratelimits/Cargo.toml b/crates/core/ratelimits/Cargo.toml index 05e1e362d..9c52c11c4 100644 --- a/crates/core/ratelimits/Cargo.toml +++ b/crates/core/ratelimits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-ratelimits" -version = "0.8.8" +version = "0.9.0" edition = "2024" [features] @@ -10,9 +10,9 @@ axum = ["dep:axum", "revolt-database/axum-impl"] default = ["rocket", "axum"] [dependencies] -revolt-database = { version = "0.8.8", path = "../database"} -revolt-result = { version = "0.8.8", path = "../result" } -revolt-config = { version = "0.8.8", path = "../config" } +revolt-database = { version = "0.9.0", path = "../database"} +revolt-result = { version = "0.9.0", path = "../result" } +revolt-config = { version = "0.9.0", path = "../config" } rocket = { version = "0.5.1", optional = true } revolt_rocket_okapi = { version = "0.10.0", optional = true } diff --git a/crates/core/result/Cargo.toml b/crates/core/result/Cargo.toml index 9004b570e..28b316b4b 100644 --- a/crates/core/result/Cargo.toml +++ b/crates/core/result/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-result" -version = "0.8.8" +version = "0.9.0" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/daemons/crond/Cargo.toml b/crates/daemons/crond/Cargo.toml index 2c55f2f76..672be2d8a 100644 --- a/crates/daemons/crond/Cargo.toml +++ b/crates/daemons/crond/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-crond" -version = "0.8.8" +version = "0.9.0" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2021" @@ -16,7 +16,7 @@ log = "0.4" tokio = { version = "1" } # Core -revolt-database = { version = "0.8.8", path = "../../core/database" } -revolt-result = { version = "0.8.8", path = "../../core/result" } -revolt-config = { version = "0.8.8", path = "../../core/config" } -revolt-files = { version = "0.8.8", path = "../../core/files" } +revolt-database = { version = "0.9.0", path = "../../core/database" } +revolt-result = { version = "0.9.0", path = "../../core/result" } +revolt-config = { version = "0.9.0", path = "../../core/config" } +revolt-files = { version = "0.9.0", path = "../../core/files" } diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index 40a280081..0de322502 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -1,20 +1,20 @@ [package] name = "revolt-pushd" -version = "0.8.8" +version = "0.9.0" edition = "2021" license = "AGPL-3.0-or-later" [dependencies] -revolt-result = { version = "0.8.8", path = "../../core/result" } -revolt-config = { version = "0.8.8", path = "../../core/config", features = [ +revolt-result = { version = "0.9.0", path = "../../core/result" } +revolt-config = { version = "0.9.0", path = "../../core/config", features = [ "report-macros", "anyhow" ] } -revolt-database = { version = "0.8.8", path = "../../core/database" } -revolt-models = { version = "0.8.8", path = "../../core/models", features = [ +revolt-database = { version = "0.9.0", path = "../../core/database" } +revolt-models = { version = "0.9.0", path = "../../core/models", features = [ "validator", ] } -revolt-presence = { version = "0.8.8", path = "../../core/presence", features = [ +revolt-presence = { version = "0.9.0", path = "../../core/presence", features = [ "redis-is-patched", ] } diff --git a/crates/daemons/voice-ingress/Cargo.toml b/crates/daemons/voice-ingress/Cargo.toml index 3b9e69747..f2a16d92f 100644 --- a/crates/daemons/voice-ingress/Cargo.toml +++ b/crates/daemons/voice-ingress/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-voice-ingress" -version = "0.7.1" +version = "0.9.0" license = "AGPL-3.0-or-later" edition = "2021" diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index 3667d83fd..55356ff5d 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-delta" -version = "0.8.8" +version = "0.9.0" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2018" diff --git a/crates/services/autumn/Cargo.toml b/crates/services/autumn/Cargo.toml index 3514f501d..838f0ffec 100644 --- a/crates/services/autumn/Cargo.toml +++ b/crates/services/autumn/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-autumn" -version = "0.8.8" +version = "0.9.0" edition = "2021" license = "AGPL-3.0-or-later" @@ -43,16 +43,16 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # Core crates -revolt-files = { version = "0.8.8", path = "../../core/files" } -revolt-config = { version = "0.8.8", path = "../../core/config" } -revolt-database = { version = "0.8.8", path = "../../core/database", features = [ +revolt-files = { version = "0.9.0", path = "../../core/files" } +revolt-config = { version = "0.9.0", path = "../../core/config" } +revolt-database = { version = "0.9.0", path = "../../core/database", features = [ "axum-impl", ] } -revolt-result = { version = "0.8.8", path = "../../core/result", features = [ +revolt-result = { version = "0.9.0", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-ratelimits = { version = "0.8.8", path = "../../core/ratelimits", features = ["axum"] } +revolt-ratelimits = { version = "0.9.0", path = "../../core/ratelimits", features = ["axum"] } # Axum / web server tempfile = "3.12.0" diff --git a/crates/services/gifbox/Cargo.toml b/crates/services/gifbox/Cargo.toml index 3e2b41736..0c5b97b47 100644 --- a/crates/services/gifbox/Cargo.toml +++ b/crates/services/gifbox/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-gifbox" -version = "0.8.8" +version = "0.9.0" edition = "2021" license = "AGPL-3.0-or-later" @@ -16,19 +16,19 @@ tokio = { version = "1.0", features = ["full"] } reqwest = { version = "0.12", features = ["json"] } # Core crates -revolt-config = { version = "0.8.8", path = "../../core/config" } -revolt-models = { version = "0.8.8", path = "../../core/models" } -revolt-result = { version = "0.8.8", path = "../../core/result", features = [ +revolt-config = { version = "0.9.0", path = "../../core/config" } +revolt-models = { version = "0.9.0", path = "../../core/models" } +revolt-result = { version = "0.9.0", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-coalesced = { version = "0.8.8", path = "../../core/coalesced", features = [ +revolt-coalesced = { version = "0.9.0", path = "../../core/coalesced", features = [ "queue", ] } -revolt-database = { version = "0.8.8", path = "../../core/database", features = [ +revolt-database = { version = "0.9.0", path = "../../core/database", features = [ "axum-impl", ] } -revolt-ratelimits = { version = "0.8.8", path = "../../core/ratelimits", features = [ +revolt-ratelimits = { version = "0.9.0", path = "../../core/ratelimits", features = [ "axum", ] } diff --git a/crates/services/january/Cargo.toml b/crates/services/january/Cargo.toml index 80b5e5228..33e8c1db9 100644 --- a/crates/services/january/Cargo.toml +++ b/crates/services/january/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-january" -version = "0.8.8" +version = "0.9.0" edition = "2021" license = "AGPL-3.0-or-later" @@ -32,13 +32,13 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # Core crates -revolt-config = { version = "0.8.8", path = "../../core/config" } -revolt-models = { version = "0.8.8", path = "../../core/models" } -revolt-result = { version = "0.8.8", path = "../../core/result", features = [ +revolt-config = { version = "0.9.0", path = "../../core/config" } +revolt-models = { version = "0.9.0", path = "../../core/models" } +revolt-result = { version = "0.9.0", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-files = { version = "0.8.8", path = "../../core/files" } +revolt-files = { version = "0.9.0", path = "../../core/files" } # Axum / web server axum = { version = "0.7.5" } diff --git a/version.txt b/version.txt index 5c5cbb3b8..ac39a106c 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.8.8 \ No newline at end of file +0.9.0 From 303e52b476585eea81c33837f1b01506ce387684 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Sat, 10 Jan 2026 12:59:20 +0000 Subject: [PATCH 046/211] fix(ci): pipeline fixes (marked as fix to force release) (#483) --- .github/workflows/docker.yaml | 4 ++-- .github/workflows/release-please.yml | 1 + .github/workflows/rust.yaml | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 85cd31269..2be1f4387 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -13,8 +13,8 @@ permissions: contents: read packages: write -concurrency: - group: ${{ github.head_ref }} +concurrency: + group: ${{ github.head_ref || github.ref }} cancel-in-progress: true jobs: diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 69b53a2e4..8fda87f1d 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -40,6 +40,7 @@ jobs: runs-on: ubuntu-latest steps: + - uses: actions/checkout@v4 - id: app-token uses: actions/create-github-app-token@v2 with: diff --git a/.github/workflows/rust.yaml b/.github/workflows/rust.yaml index 359c30191..e0f8ae49e 100644 --- a/.github/workflows/rust.yaml +++ b/.github/workflows/rust.yaml @@ -5,8 +5,8 @@ on: branches: [main] pull_request: -concurrency: - group: ${{ github.head_ref }} +concurrency: + group: ${{ github.head_ref || github.ref }} cancel-in-progress: true env: From 58fb2694501c23b8f1448c7a41324b54ff3a76df Mon Sep 17 00:00:00 2001 From: "stoat-release[bot]" <245062572+stoat-release[bot]@users.noreply.github.com> Date: Sat, 10 Jan 2026 12:59:50 +0000 Subject: [PATCH 047/211] chore(main): release 0.9.1 (#484) Co-authored-by: stoat-release[bot] <245062572+stoat-release[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 7 +++++++ crates/bonfire/Cargo.toml | 2 +- crates/core/coalesced/Cargo.toml | 2 +- crates/core/config/Cargo.toml | 4 ++-- crates/core/database/Cargo.toml | 14 +++++++------- crates/core/files/Cargo.toml | 6 +++--- crates/core/models/Cargo.toml | 6 +++--- crates/core/parser/Cargo.toml | 2 +- crates/core/permissions/Cargo.toml | 4 ++-- crates/core/presence/Cargo.toml | 4 ++-- crates/core/ratelimits/Cargo.toml | 8 ++++---- crates/core/result/Cargo.toml | 2 +- crates/daemons/crond/Cargo.toml | 10 +++++----- crates/daemons/pushd/Cargo.toml | 12 ++++++------ crates/daemons/voice-ingress/Cargo.toml | 2 +- crates/delta/Cargo.toml | 2 +- crates/services/autumn/Cargo.toml | 12 ++++++------ crates/services/gifbox/Cargo.toml | 14 +++++++------- crates/services/january/Cargo.toml | 10 +++++----- version.txt | 2 +- 21 files changed, 67 insertions(+), 60 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 2101ae57f..97dd7ac80 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.9.0" + ".": "0.9.1" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b7ab6351..e1beff20f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [0.9.1](https://github.com/stoatchat/stoatchat/compare/v0.9.0...v0.9.1) (2026-01-10) + + +### Bug Fixes + +* **ci:** pipeline fixes (marked as fix to force release) ([#483](https://github.com/stoatchat/stoatchat/issues/483)) ([303e52b](https://github.com/stoatchat/stoatchat/commit/303e52b476585eea81c33837f1b01506ce387684)) + ## [0.9.0](https://github.com/stoatchat/stoatchat/compare/v0.8.8...v0.9.0) (2026-01-10) diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index 13bca0d69..3ec12a1a0 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-bonfire" -version = "0.9.0" +version = "0.9.1" license = "AGPL-3.0-or-later" edition = "2021" diff --git a/crates/core/coalesced/Cargo.toml b/crates/core/coalesced/Cargo.toml index 96d53b230..0fc6dd0fb 100644 --- a/crates/core/coalesced/Cargo.toml +++ b/crates/core/coalesced/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-coalesced" -version = "0.9.0" +version = "0.9.1" edition = "2021" license = "MIT" authors = ["Paul Makles ", "Zomatree "] diff --git a/crates/core/config/Cargo.toml b/crates/core/config/Cargo.toml index 00480fcba..81d2cac64 100644 --- a/crates/core/config/Cargo.toml +++ b/crates/core/config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-config" -version = "0.9.0" +version = "0.9.1" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -37,4 +37,4 @@ sentry = { version = "0.31.5", optional = true } sentry-anyhow = { version = "0.38.1", optional = true } # Core -revolt-result = { version = "0.9.0", path = "../result", optional = true } +revolt-result = { version = "0.9.1", path = "../result", optional = true } diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index a2ac060af..19519bc36 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-database" -version = "0.9.0" +version = "0.9.1" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -25,19 +25,19 @@ default = ["mongodb", "async-std-runtime", "tasks"] [dependencies] # Core -revolt-config = { version = "0.9.0", path = "../config", features = [ +revolt-config = { version = "0.9.1", path = "../config", features = [ "report-macros", ] } -revolt-result = { version = "0.9.0", path = "../result" } -revolt-models = { version = "0.9.0", path = "../models", features = [ +revolt-result = { version = "0.9.1", path = "../result" } +revolt-models = { version = "0.9.1", path = "../models", features = [ "validator", ] } -revolt-presence = { version = "0.9.0", path = "../presence" } -revolt-permissions = { version = "0.9.0", path = "../permissions", features = [ +revolt-presence = { version = "0.9.1", path = "../presence" } +revolt-permissions = { version = "0.9.1", path = "../permissions", features = [ "serde", "bson", ] } -revolt-parser = { version = "0.9.0", path = "../parser" } +revolt-parser = { version = "0.9.1", path = "../parser" } # Utility log = "0.4" diff --git a/crates/core/files/Cargo.toml b/crates/core/files/Cargo.toml index 510e46c6a..27cf6c455 100644 --- a/crates/core/files/Cargo.toml +++ b/crates/core/files/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-files" -version = "0.9.0" +version = "0.9.1" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -20,10 +20,10 @@ typenum = "1.17.0" aws-config = "1.5.5" aws-sdk-s3 = { version = "1.46.0", features = ["behavior-version-latest"] } -revolt-config = { version = "0.9.0", path = "../config", features = [ +revolt-config = { version = "0.9.1", path = "../config", features = [ "report-macros", ] } -revolt-result = { version = "0.9.0", path = "../result" } +revolt-result = { version = "0.9.1", path = "../result" } # image processing jxl-oxide = "0.8.1" diff --git a/crates/core/models/Cargo.toml b/crates/core/models/Cargo.toml index be918579e..f3e336fcc 100644 --- a/crates/core/models/Cargo.toml +++ b/crates/core/models/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-models" -version = "0.9.0" +version = "0.9.1" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -20,8 +20,8 @@ default = ["serde", "partials", "rocket"] [dependencies] # Core -revolt-config = { version = "0.9.0", path = "../config" } -revolt-permissions = { version = "0.9.0", path = "../permissions" } +revolt-config = { version = "0.9.1", path = "../config" } +revolt-permissions = { version = "0.9.1", path = "../permissions" } # Utility regex = "1.11" diff --git a/crates/core/parser/Cargo.toml b/crates/core/parser/Cargo.toml index 912e1de66..dc91165d2 100644 --- a/crates/core/parser/Cargo.toml +++ b/crates/core/parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-parser" -version = "0.9.0" +version = "0.9.1" edition = "2021" license = "MIT" authors = ["Zomatree ", "Paul Makles "] diff --git a/crates/core/permissions/Cargo.toml b/crates/core/permissions/Cargo.toml index 439af354f..bf9577a05 100644 --- a/crates/core/permissions/Cargo.toml +++ b/crates/core/permissions/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-permissions" -version = "0.9.0" +version = "0.9.1" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -21,7 +21,7 @@ async-std = { version = "1.8.0", features = ["attributes"] } [dependencies] # Core -revolt-result = { version = "0.9.0", path = "../result" } +revolt-result = { version = "0.9.1", path = "../result" } # Utility auto_ops = "0.3.0" diff --git a/crates/core/presence/Cargo.toml b/crates/core/presence/Cargo.toml index 6bffe55cd..8569dda92 100644 --- a/crates/core/presence/Cargo.toml +++ b/crates/core/presence/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-presence" -version = "0.9.0" +version = "0.9.1" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -16,7 +16,7 @@ redis-is-patched = [] async-std = { version = "1.8.0", features = ["attributes"] } # Config for loading Redis URI -revolt-config = { version = "0.9.0", path = "../config" } +revolt-config = { version = "0.9.1", path = "../config" } [dependencies] # Utility diff --git a/crates/core/ratelimits/Cargo.toml b/crates/core/ratelimits/Cargo.toml index 9c52c11c4..d6eb495d2 100644 --- a/crates/core/ratelimits/Cargo.toml +++ b/crates/core/ratelimits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-ratelimits" -version = "0.9.0" +version = "0.9.1" edition = "2024" [features] @@ -10,9 +10,9 @@ axum = ["dep:axum", "revolt-database/axum-impl"] default = ["rocket", "axum"] [dependencies] -revolt-database = { version = "0.9.0", path = "../database"} -revolt-result = { version = "0.9.0", path = "../result" } -revolt-config = { version = "0.9.0", path = "../config" } +revolt-database = { version = "0.9.1", path = "../database"} +revolt-result = { version = "0.9.1", path = "../result" } +revolt-config = { version = "0.9.1", path = "../config" } rocket = { version = "0.5.1", optional = true } revolt_rocket_okapi = { version = "0.10.0", optional = true } diff --git a/crates/core/result/Cargo.toml b/crates/core/result/Cargo.toml index 28b316b4b..0b44a0e12 100644 --- a/crates/core/result/Cargo.toml +++ b/crates/core/result/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-result" -version = "0.9.0" +version = "0.9.1" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/daemons/crond/Cargo.toml b/crates/daemons/crond/Cargo.toml index 672be2d8a..25c9fa701 100644 --- a/crates/daemons/crond/Cargo.toml +++ b/crates/daemons/crond/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-crond" -version = "0.9.0" +version = "0.9.1" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2021" @@ -16,7 +16,7 @@ log = "0.4" tokio = { version = "1" } # Core -revolt-database = { version = "0.9.0", path = "../../core/database" } -revolt-result = { version = "0.9.0", path = "../../core/result" } -revolt-config = { version = "0.9.0", path = "../../core/config" } -revolt-files = { version = "0.9.0", path = "../../core/files" } +revolt-database = { version = "0.9.1", path = "../../core/database" } +revolt-result = { version = "0.9.1", path = "../../core/result" } +revolt-config = { version = "0.9.1", path = "../../core/config" } +revolt-files = { version = "0.9.1", path = "../../core/files" } diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index 0de322502..01cb03017 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -1,20 +1,20 @@ [package] name = "revolt-pushd" -version = "0.9.0" +version = "0.9.1" edition = "2021" license = "AGPL-3.0-or-later" [dependencies] -revolt-result = { version = "0.9.0", path = "../../core/result" } -revolt-config = { version = "0.9.0", path = "../../core/config", features = [ +revolt-result = { version = "0.9.1", path = "../../core/result" } +revolt-config = { version = "0.9.1", path = "../../core/config", features = [ "report-macros", "anyhow" ] } -revolt-database = { version = "0.9.0", path = "../../core/database" } -revolt-models = { version = "0.9.0", path = "../../core/models", features = [ +revolt-database = { version = "0.9.1", path = "../../core/database" } +revolt-models = { version = "0.9.1", path = "../../core/models", features = [ "validator", ] } -revolt-presence = { version = "0.9.0", path = "../../core/presence", features = [ +revolt-presence = { version = "0.9.1", path = "../../core/presence", features = [ "redis-is-patched", ] } diff --git a/crates/daemons/voice-ingress/Cargo.toml b/crates/daemons/voice-ingress/Cargo.toml index f2a16d92f..d253ae8d4 100644 --- a/crates/daemons/voice-ingress/Cargo.toml +++ b/crates/daemons/voice-ingress/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-voice-ingress" -version = "0.9.0" +version = "0.9.1" license = "AGPL-3.0-or-later" edition = "2021" diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index 55356ff5d..f15bf6814 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-delta" -version = "0.9.0" +version = "0.9.1" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2018" diff --git a/crates/services/autumn/Cargo.toml b/crates/services/autumn/Cargo.toml index 838f0ffec..c7cd1acff 100644 --- a/crates/services/autumn/Cargo.toml +++ b/crates/services/autumn/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-autumn" -version = "0.9.0" +version = "0.9.1" edition = "2021" license = "AGPL-3.0-or-later" @@ -43,16 +43,16 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # Core crates -revolt-files = { version = "0.9.0", path = "../../core/files" } -revolt-config = { version = "0.9.0", path = "../../core/config" } -revolt-database = { version = "0.9.0", path = "../../core/database", features = [ +revolt-files = { version = "0.9.1", path = "../../core/files" } +revolt-config = { version = "0.9.1", path = "../../core/config" } +revolt-database = { version = "0.9.1", path = "../../core/database", features = [ "axum-impl", ] } -revolt-result = { version = "0.9.0", path = "../../core/result", features = [ +revolt-result = { version = "0.9.1", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-ratelimits = { version = "0.9.0", path = "../../core/ratelimits", features = ["axum"] } +revolt-ratelimits = { version = "0.9.1", path = "../../core/ratelimits", features = ["axum"] } # Axum / web server tempfile = "3.12.0" diff --git a/crates/services/gifbox/Cargo.toml b/crates/services/gifbox/Cargo.toml index 0c5b97b47..8440ae31c 100644 --- a/crates/services/gifbox/Cargo.toml +++ b/crates/services/gifbox/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-gifbox" -version = "0.9.0" +version = "0.9.1" edition = "2021" license = "AGPL-3.0-or-later" @@ -16,19 +16,19 @@ tokio = { version = "1.0", features = ["full"] } reqwest = { version = "0.12", features = ["json"] } # Core crates -revolt-config = { version = "0.9.0", path = "../../core/config" } -revolt-models = { version = "0.9.0", path = "../../core/models" } -revolt-result = { version = "0.9.0", path = "../../core/result", features = [ +revolt-config = { version = "0.9.1", path = "../../core/config" } +revolt-models = { version = "0.9.1", path = "../../core/models" } +revolt-result = { version = "0.9.1", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-coalesced = { version = "0.9.0", path = "../../core/coalesced", features = [ +revolt-coalesced = { version = "0.9.1", path = "../../core/coalesced", features = [ "queue", ] } -revolt-database = { version = "0.9.0", path = "../../core/database", features = [ +revolt-database = { version = "0.9.1", path = "../../core/database", features = [ "axum-impl", ] } -revolt-ratelimits = { version = "0.9.0", path = "../../core/ratelimits", features = [ +revolt-ratelimits = { version = "0.9.1", path = "../../core/ratelimits", features = [ "axum", ] } diff --git a/crates/services/january/Cargo.toml b/crates/services/january/Cargo.toml index 33e8c1db9..92d3fba56 100644 --- a/crates/services/january/Cargo.toml +++ b/crates/services/january/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-january" -version = "0.9.0" +version = "0.9.1" edition = "2021" license = "AGPL-3.0-or-later" @@ -32,13 +32,13 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # Core crates -revolt-config = { version = "0.9.0", path = "../../core/config" } -revolt-models = { version = "0.9.0", path = "../../core/models" } -revolt-result = { version = "0.9.0", path = "../../core/result", features = [ +revolt-config = { version = "0.9.1", path = "../../core/config" } +revolt-models = { version = "0.9.1", path = "../../core/models" } +revolt-result = { version = "0.9.1", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-files = { version = "0.9.0", path = "../../core/files" } +revolt-files = { version = "0.9.1", path = "../../core/files" } # Axum / web server axum = { version = "0.7.5" } diff --git a/version.txt b/version.txt index ac39a106c..f374f6662 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.9.0 +0.9.1 From d13609c37279d6a40445dcd99564e5c3dd03bac1 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Sat, 10 Jan 2026 13:06:33 +0000 Subject: [PATCH 048/211] fix: disable publish for services (#485) --- crates/bonfire/Cargo.toml | 1 + crates/daemons/crond/Cargo.toml | 1 + crates/daemons/pushd/Cargo.toml | 1 + crates/daemons/voice-ingress/Cargo.toml | 1 + crates/delta/Cargo.toml | 1 + crates/services/autumn/Cargo.toml | 1 + crates/services/gifbox/Cargo.toml | 1 + crates/services/january/Cargo.toml | 1 + justfile | 21 --------------------- scripts/try-tag-and-release.sh | 14 -------------- 10 files changed, 8 insertions(+), 35 deletions(-) delete mode 100644 justfile delete mode 100755 scripts/try-tag-and-release.sh diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index 3ec12a1a0..8f3a18c18 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -3,6 +3,7 @@ name = "revolt-bonfire" version = "0.9.1" license = "AGPL-3.0-or-later" edition = "2021" +publish = false # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/crates/daemons/crond/Cargo.toml b/crates/daemons/crond/Cargo.toml index 25c9fa701..9a9ea0aa5 100644 --- a/crates/daemons/crond/Cargo.toml +++ b/crates/daemons/crond/Cargo.toml @@ -5,6 +5,7 @@ license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2021" description = "Revolt Daemon Service: Timed data clean up tasks" +publish = false # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index 01cb03017..600baa3ba 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -3,6 +3,7 @@ name = "revolt-pushd" version = "0.9.1" edition = "2021" license = "AGPL-3.0-or-later" +publish = false [dependencies] revolt-result = { version = "0.9.1", path = "../../core/result" } diff --git a/crates/daemons/voice-ingress/Cargo.toml b/crates/daemons/voice-ingress/Cargo.toml index d253ae8d4..1fa064429 100644 --- a/crates/daemons/voice-ingress/Cargo.toml +++ b/crates/daemons/voice-ingress/Cargo.toml @@ -3,6 +3,7 @@ name = "revolt-voice-ingress" version = "0.9.1" license = "AGPL-3.0-or-later" edition = "2021" +publish = false # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index f15bf6814..56160b289 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -4,6 +4,7 @@ version = "0.9.1" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2018" +publish = false # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/crates/services/autumn/Cargo.toml b/crates/services/autumn/Cargo.toml index c7cd1acff..23e42c711 100644 --- a/crates/services/autumn/Cargo.toml +++ b/crates/services/autumn/Cargo.toml @@ -3,6 +3,7 @@ name = "revolt-autumn" version = "0.9.1" edition = "2021" license = "AGPL-3.0-or-later" +publish = false [dependencies] # ID generation diff --git a/crates/services/gifbox/Cargo.toml b/crates/services/gifbox/Cargo.toml index 8440ae31c..435430d77 100644 --- a/crates/services/gifbox/Cargo.toml +++ b/crates/services/gifbox/Cargo.toml @@ -3,6 +3,7 @@ name = "revolt-gifbox" version = "0.9.1" edition = "2021" license = "AGPL-3.0-or-later" +publish = false [dependencies] # Serialisation diff --git a/crates/services/january/Cargo.toml b/crates/services/january/Cargo.toml index 92d3fba56..08cc5fc00 100644 --- a/crates/services/january/Cargo.toml +++ b/crates/services/january/Cargo.toml @@ -3,6 +3,7 @@ name = "revolt-january" version = "0.9.1" edition = "2021" license = "AGPL-3.0-or-later" +publish = false [dependencies] # Utility diff --git a/justfile b/justfile deleted file mode 100644 index 74c7082d1..000000000 --- a/justfile +++ /dev/null @@ -1,21 +0,0 @@ -publish: - cargo publish --package revolt-parser - cargo publish --package revolt-result - cargo publish --package revolt-config - cargo publish --package revolt-files - cargo publish --package revolt-permissions - cargo publish --package revolt-models - cargo publish --package revolt-presence - cargo publish --package revolt-database - -patch: - cargo release version patch --execute - -minor: - cargo release version minor --execute - -major: - cargo release version major --execute - -release: - scripts/try-tag-and-release.sh diff --git a/scripts/try-tag-and-release.sh b/scripts/try-tag-and-release.sh deleted file mode 100755 index 2ab918458..000000000 --- a/scripts/try-tag-and-release.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash -date=$(date +'%Y%m%d') -incr=1 - -while [ $(git tag -l "$date-$incr") ]; do - incr=$((incr+1)) -done - -tag=$date-$incr -echo About to tag and push $tag in 3 seconds... -sleep 3s - -git tag $tag -git push --atomic origin $(git rev-parse --abbrev-ref HEAD) $tag From b4ba02218f2f07bfc8b9364131e07f57554b0def Mon Sep 17 00:00:00 2001 From: "stoat-release[bot]" <245062572+stoat-release[bot]@users.noreply.github.com> Date: Sat, 10 Jan 2026 13:07:06 +0000 Subject: [PATCH 049/211] chore(main): release 0.9.2 (#486) Co-authored-by: stoat-release[bot] <245062572+stoat-release[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 7 +++++++ crates/bonfire/Cargo.toml | 2 +- crates/core/coalesced/Cargo.toml | 2 +- crates/core/config/Cargo.toml | 4 ++-- crates/core/database/Cargo.toml | 14 +++++++------- crates/core/files/Cargo.toml | 6 +++--- crates/core/models/Cargo.toml | 6 +++--- crates/core/parser/Cargo.toml | 2 +- crates/core/permissions/Cargo.toml | 4 ++-- crates/core/presence/Cargo.toml | 4 ++-- crates/core/ratelimits/Cargo.toml | 8 ++++---- crates/core/result/Cargo.toml | 2 +- crates/daemons/crond/Cargo.toml | 10 +++++----- crates/daemons/pushd/Cargo.toml | 12 ++++++------ crates/daemons/voice-ingress/Cargo.toml | 2 +- crates/delta/Cargo.toml | 2 +- crates/services/autumn/Cargo.toml | 12 ++++++------ crates/services/gifbox/Cargo.toml | 14 +++++++------- crates/services/january/Cargo.toml | 10 +++++----- version.txt | 2 +- 21 files changed, 67 insertions(+), 60 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 97dd7ac80..19735b032 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.9.1" + ".": "0.9.2" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index e1beff20f..4c7466e91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [0.9.2](https://github.com/stoatchat/stoatchat/compare/v0.9.1...v0.9.2) (2026-01-10) + + +### Bug Fixes + +* disable publish for services ([#485](https://github.com/stoatchat/stoatchat/issues/485)) ([d13609c](https://github.com/stoatchat/stoatchat/commit/d13609c37279d6a40445dcd99564e5c3dd03bac1)) + ## [0.9.1](https://github.com/stoatchat/stoatchat/compare/v0.9.0...v0.9.1) (2026-01-10) diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index 8f3a18c18..cea3987ae 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-bonfire" -version = "0.9.1" +version = "0.9.2" license = "AGPL-3.0-or-later" edition = "2021" publish = false diff --git a/crates/core/coalesced/Cargo.toml b/crates/core/coalesced/Cargo.toml index 0fc6dd0fb..70d249bdc 100644 --- a/crates/core/coalesced/Cargo.toml +++ b/crates/core/coalesced/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-coalesced" -version = "0.9.1" +version = "0.9.2" edition = "2021" license = "MIT" authors = ["Paul Makles ", "Zomatree "] diff --git a/crates/core/config/Cargo.toml b/crates/core/config/Cargo.toml index 81d2cac64..60b9a9137 100644 --- a/crates/core/config/Cargo.toml +++ b/crates/core/config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-config" -version = "0.9.1" +version = "0.9.2" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -37,4 +37,4 @@ sentry = { version = "0.31.5", optional = true } sentry-anyhow = { version = "0.38.1", optional = true } # Core -revolt-result = { version = "0.9.1", path = "../result", optional = true } +revolt-result = { version = "0.9.2", path = "../result", optional = true } diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index 19519bc36..a3782b8cc 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-database" -version = "0.9.1" +version = "0.9.2" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -25,19 +25,19 @@ default = ["mongodb", "async-std-runtime", "tasks"] [dependencies] # Core -revolt-config = { version = "0.9.1", path = "../config", features = [ +revolt-config = { version = "0.9.2", path = "../config", features = [ "report-macros", ] } -revolt-result = { version = "0.9.1", path = "../result" } -revolt-models = { version = "0.9.1", path = "../models", features = [ +revolt-result = { version = "0.9.2", path = "../result" } +revolt-models = { version = "0.9.2", path = "../models", features = [ "validator", ] } -revolt-presence = { version = "0.9.1", path = "../presence" } -revolt-permissions = { version = "0.9.1", path = "../permissions", features = [ +revolt-presence = { version = "0.9.2", path = "../presence" } +revolt-permissions = { version = "0.9.2", path = "../permissions", features = [ "serde", "bson", ] } -revolt-parser = { version = "0.9.1", path = "../parser" } +revolt-parser = { version = "0.9.2", path = "../parser" } # Utility log = "0.4" diff --git a/crates/core/files/Cargo.toml b/crates/core/files/Cargo.toml index 27cf6c455..5a8fad2fe 100644 --- a/crates/core/files/Cargo.toml +++ b/crates/core/files/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-files" -version = "0.9.1" +version = "0.9.2" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -20,10 +20,10 @@ typenum = "1.17.0" aws-config = "1.5.5" aws-sdk-s3 = { version = "1.46.0", features = ["behavior-version-latest"] } -revolt-config = { version = "0.9.1", path = "../config", features = [ +revolt-config = { version = "0.9.2", path = "../config", features = [ "report-macros", ] } -revolt-result = { version = "0.9.1", path = "../result" } +revolt-result = { version = "0.9.2", path = "../result" } # image processing jxl-oxide = "0.8.1" diff --git a/crates/core/models/Cargo.toml b/crates/core/models/Cargo.toml index f3e336fcc..eaae7d8f6 100644 --- a/crates/core/models/Cargo.toml +++ b/crates/core/models/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-models" -version = "0.9.1" +version = "0.9.2" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -20,8 +20,8 @@ default = ["serde", "partials", "rocket"] [dependencies] # Core -revolt-config = { version = "0.9.1", path = "../config" } -revolt-permissions = { version = "0.9.1", path = "../permissions" } +revolt-config = { version = "0.9.2", path = "../config" } +revolt-permissions = { version = "0.9.2", path = "../permissions" } # Utility regex = "1.11" diff --git a/crates/core/parser/Cargo.toml b/crates/core/parser/Cargo.toml index dc91165d2..fc3e4456e 100644 --- a/crates/core/parser/Cargo.toml +++ b/crates/core/parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-parser" -version = "0.9.1" +version = "0.9.2" edition = "2021" license = "MIT" authors = ["Zomatree ", "Paul Makles "] diff --git a/crates/core/permissions/Cargo.toml b/crates/core/permissions/Cargo.toml index bf9577a05..d12f9d356 100644 --- a/crates/core/permissions/Cargo.toml +++ b/crates/core/permissions/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-permissions" -version = "0.9.1" +version = "0.9.2" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -21,7 +21,7 @@ async-std = { version = "1.8.0", features = ["attributes"] } [dependencies] # Core -revolt-result = { version = "0.9.1", path = "../result" } +revolt-result = { version = "0.9.2", path = "../result" } # Utility auto_ops = "0.3.0" diff --git a/crates/core/presence/Cargo.toml b/crates/core/presence/Cargo.toml index 8569dda92..74455b584 100644 --- a/crates/core/presence/Cargo.toml +++ b/crates/core/presence/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-presence" -version = "0.9.1" +version = "0.9.2" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -16,7 +16,7 @@ redis-is-patched = [] async-std = { version = "1.8.0", features = ["attributes"] } # Config for loading Redis URI -revolt-config = { version = "0.9.1", path = "../config" } +revolt-config = { version = "0.9.2", path = "../config" } [dependencies] # Utility diff --git a/crates/core/ratelimits/Cargo.toml b/crates/core/ratelimits/Cargo.toml index d6eb495d2..1335c8ec5 100644 --- a/crates/core/ratelimits/Cargo.toml +++ b/crates/core/ratelimits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-ratelimits" -version = "0.9.1" +version = "0.9.2" edition = "2024" [features] @@ -10,9 +10,9 @@ axum = ["dep:axum", "revolt-database/axum-impl"] default = ["rocket", "axum"] [dependencies] -revolt-database = { version = "0.9.1", path = "../database"} -revolt-result = { version = "0.9.1", path = "../result" } -revolt-config = { version = "0.9.1", path = "../config" } +revolt-database = { version = "0.9.2", path = "../database"} +revolt-result = { version = "0.9.2", path = "../result" } +revolt-config = { version = "0.9.2", path = "../config" } rocket = { version = "0.5.1", optional = true } revolt_rocket_okapi = { version = "0.10.0", optional = true } diff --git a/crates/core/result/Cargo.toml b/crates/core/result/Cargo.toml index 0b44a0e12..a6f2ae329 100644 --- a/crates/core/result/Cargo.toml +++ b/crates/core/result/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-result" -version = "0.9.1" +version = "0.9.2" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/daemons/crond/Cargo.toml b/crates/daemons/crond/Cargo.toml index 9a9ea0aa5..3673cd6b6 100644 --- a/crates/daemons/crond/Cargo.toml +++ b/crates/daemons/crond/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-crond" -version = "0.9.1" +version = "0.9.2" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2021" @@ -17,7 +17,7 @@ log = "0.4" tokio = { version = "1" } # Core -revolt-database = { version = "0.9.1", path = "../../core/database" } -revolt-result = { version = "0.9.1", path = "../../core/result" } -revolt-config = { version = "0.9.1", path = "../../core/config" } -revolt-files = { version = "0.9.1", path = "../../core/files" } +revolt-database = { version = "0.9.2", path = "../../core/database" } +revolt-result = { version = "0.9.2", path = "../../core/result" } +revolt-config = { version = "0.9.2", path = "../../core/config" } +revolt-files = { version = "0.9.2", path = "../../core/files" } diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index 600baa3ba..7b17ae7e7 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -1,21 +1,21 @@ [package] name = "revolt-pushd" -version = "0.9.1" +version = "0.9.2" edition = "2021" license = "AGPL-3.0-or-later" publish = false [dependencies] -revolt-result = { version = "0.9.1", path = "../../core/result" } -revolt-config = { version = "0.9.1", path = "../../core/config", features = [ +revolt-result = { version = "0.9.2", path = "../../core/result" } +revolt-config = { version = "0.9.2", path = "../../core/config", features = [ "report-macros", "anyhow" ] } -revolt-database = { version = "0.9.1", path = "../../core/database" } -revolt-models = { version = "0.9.1", path = "../../core/models", features = [ +revolt-database = { version = "0.9.2", path = "../../core/database" } +revolt-models = { version = "0.9.2", path = "../../core/models", features = [ "validator", ] } -revolt-presence = { version = "0.9.1", path = "../../core/presence", features = [ +revolt-presence = { version = "0.9.2", path = "../../core/presence", features = [ "redis-is-patched", ] } diff --git a/crates/daemons/voice-ingress/Cargo.toml b/crates/daemons/voice-ingress/Cargo.toml index 1fa064429..82ee3a3ca 100644 --- a/crates/daemons/voice-ingress/Cargo.toml +++ b/crates/daemons/voice-ingress/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-voice-ingress" -version = "0.9.1" +version = "0.9.2" license = "AGPL-3.0-or-later" edition = "2021" publish = false diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index 56160b289..5457ab3ee 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-delta" -version = "0.9.1" +version = "0.9.2" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2018" diff --git a/crates/services/autumn/Cargo.toml b/crates/services/autumn/Cargo.toml index 23e42c711..5ffdb808e 100644 --- a/crates/services/autumn/Cargo.toml +++ b/crates/services/autumn/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-autumn" -version = "0.9.1" +version = "0.9.2" edition = "2021" license = "AGPL-3.0-or-later" publish = false @@ -44,16 +44,16 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # Core crates -revolt-files = { version = "0.9.1", path = "../../core/files" } -revolt-config = { version = "0.9.1", path = "../../core/config" } -revolt-database = { version = "0.9.1", path = "../../core/database", features = [ +revolt-files = { version = "0.9.2", path = "../../core/files" } +revolt-config = { version = "0.9.2", path = "../../core/config" } +revolt-database = { version = "0.9.2", path = "../../core/database", features = [ "axum-impl", ] } -revolt-result = { version = "0.9.1", path = "../../core/result", features = [ +revolt-result = { version = "0.9.2", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-ratelimits = { version = "0.9.1", path = "../../core/ratelimits", features = ["axum"] } +revolt-ratelimits = { version = "0.9.2", path = "../../core/ratelimits", features = ["axum"] } # Axum / web server tempfile = "3.12.0" diff --git a/crates/services/gifbox/Cargo.toml b/crates/services/gifbox/Cargo.toml index 435430d77..9f7f6f3cd 100644 --- a/crates/services/gifbox/Cargo.toml +++ b/crates/services/gifbox/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-gifbox" -version = "0.9.1" +version = "0.9.2" edition = "2021" license = "AGPL-3.0-or-later" publish = false @@ -17,19 +17,19 @@ tokio = { version = "1.0", features = ["full"] } reqwest = { version = "0.12", features = ["json"] } # Core crates -revolt-config = { version = "0.9.1", path = "../../core/config" } -revolt-models = { version = "0.9.1", path = "../../core/models" } -revolt-result = { version = "0.9.1", path = "../../core/result", features = [ +revolt-config = { version = "0.9.2", path = "../../core/config" } +revolt-models = { version = "0.9.2", path = "../../core/models" } +revolt-result = { version = "0.9.2", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-coalesced = { version = "0.9.1", path = "../../core/coalesced", features = [ +revolt-coalesced = { version = "0.9.2", path = "../../core/coalesced", features = [ "queue", ] } -revolt-database = { version = "0.9.1", path = "../../core/database", features = [ +revolt-database = { version = "0.9.2", path = "../../core/database", features = [ "axum-impl", ] } -revolt-ratelimits = { version = "0.9.1", path = "../../core/ratelimits", features = [ +revolt-ratelimits = { version = "0.9.2", path = "../../core/ratelimits", features = [ "axum", ] } diff --git a/crates/services/january/Cargo.toml b/crates/services/january/Cargo.toml index 08cc5fc00..b63b54341 100644 --- a/crates/services/january/Cargo.toml +++ b/crates/services/january/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-january" -version = "0.9.1" +version = "0.9.2" edition = "2021" license = "AGPL-3.0-or-later" publish = false @@ -33,13 +33,13 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # Core crates -revolt-config = { version = "0.9.1", path = "../../core/config" } -revolt-models = { version = "0.9.1", path = "../../core/models" } -revolt-result = { version = "0.9.1", path = "../../core/result", features = [ +revolt-config = { version = "0.9.2", path = "../../core/config" } +revolt-models = { version = "0.9.2", path = "../../core/models" } +revolt-result = { version = "0.9.2", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-files = { version = "0.9.1", path = "../../core/files" } +revolt-files = { version = "0.9.2", path = "../../core/files" } # Axum / web server axum = { version = "0.7.5" } diff --git a/version.txt b/version.txt index f374f6662..2003b639c 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.9.1 +0.9.2 From bf0048a052456ad35884e01f6bfb311e1bf2971b Mon Sep 17 00:00:00 2001 From: "stoat-tofu[bot]" <242700035+stoat-tofu[bot]@users.noreply.github.com> Date: Sat, 10 Jan 2026 13:19:24 +0000 Subject: [PATCH 050/211] chore: modify .github/workflows/release-webhook.yml --- .github/workflows/release-webhook.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .github/workflows/release-webhook.yml diff --git a/.github/workflows/release-webhook.yml b/.github/workflows/release-webhook.yml new file mode 100644 index 000000000..41e856521 --- /dev/null +++ b/.github/workflows/release-webhook.yml @@ -0,0 +1,19 @@ +name: Release Webhook + +on: + workflow_dispatch: + release: + types: [published] + +jobs: + release-webhook: + name: Send Release Webhook + runs-on: ubuntu-latest + + steps: + - name: Send release notification webhook + run: | + RELEASE_URL="https://github.com/${{ github.repository }}/releases/tag/${{ needs.release-please.outputs.tag_name }}" + curl -X POST "${{ secrets.STOAT_WEBHOOK_UPDATES_URL }}" \ + -H "Content-Type: application/json" \ + -d "{\"content\": \"$RELEASE_URL\"}" From aeeafebefc36a43a656cf797c9251ca50292733c Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Sat, 10 Jan 2026 14:46:57 +0000 Subject: [PATCH 051/211] fix: pipeline fixes (#487) --- .github/workflows/publish-crates.yml | 21 ++++++ .github/workflows/release-please.yml | 45 +++++++------ .github/workflows/rust.yaml | 2 + Cargo.lock | 98 +++++++++++++++++----------- compose.yml | 12 ++-- crates/core/coalesced/Cargo.toml | 4 +- 6 files changed, 112 insertions(+), 70 deletions(-) create mode 100644 .github/workflows/publish-crates.yml diff --git a/.github/workflows/publish-crates.yml b/.github/workflows/publish-crates.yml new file mode 100644 index 000000000..c952a35d8 --- /dev/null +++ b/.github/workflows/publish-crates.yml @@ -0,0 +1,21 @@ +name: Publish Crates + +on: + workflow_dispatch: + release: + types: [published] + +jobs: + publish: + name: Publish Crates + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + with: + persist-credentials: false + + - name: Publish crates + uses: katyo/publish-crates@02cc2f1ad653fb25c7d1ff9eb590a8a50d06186b # v2 + with: + registry-token: ${{ secrets.CRATES_IO_PUBLISH_TOKEN }} diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 8fda87f1d..7633e2bc8 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -33,28 +33,27 @@ jobs: token: ${{ steps.app-token.outputs.token }} config-file: release-please-config.json - publish-please: - name: Publish Please - needs: release-please - if: needs.release-please.outputs.release_created == 'true' - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - id: app-token - uses: actions/create-github-app-token@v2 + - name: Install latest stable + uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # v1 with: - app-id: ${{ secrets.GH_STOAT_RELEASE_APP_ID }} - private-key: ${{ secrets.GH_STOAT_RELEASE_APP_PRIVATE_KEY }} - - - name: Send release notification webhook + toolchain: stable + + - name: Update Cargo.lock + if: ${{ steps.rp.outputs.prs_created == 'true' || steps.rp.outputs.prs_updated == 'true' }} + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} run: | - RELEASE_URL="https://github.com/revoltchat/backend/releases/tag/${{ needs.release-please.outputs.tag_name }}" - curl -X POST "${{ secrets.STOAT_WEBHOOK_UPDATES_URL }}" \ - -H "Content-Type: application/json" \ - -d "{\"content\": \"$RELEASE_URL\"}" - - - name: Publish crates - uses: katyo/publish-crates@v2 - with: - registry-token: ${{ secrets.CRATES_IO_PUBLISH_TOKEN }} + PR_NUMBER=$(echo '${{ steps.rp.outputs.prs }}' | jq -r '.[0].number') + gh pr checkout "$PR_NUMBER" + + cargo update -w + + if git diff --quiet Cargo.lock; then + echo "No changes to Cargo.lock" + else + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add Cargo.lock + git commit -s -m "chore: update Cargo.lock" + git push + fi diff --git a/.github/workflows/rust.yaml b/.github/workflows/rust.yaml index e0f8ae49e..c65d03f3a 100644 --- a/.github/workflows/rust.yaml +++ b/.github/workflows/rust.yaml @@ -18,6 +18,8 @@ jobs: runs-on: arc-runner-set steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + with: + persist-credentials: false # Using our own runners for now: # - name: Free up disk space diff --git a/Cargo.lock b/Cargo.lock index 6320f82f8..5326152fa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1275,7 +1275,7 @@ dependencies = [ "getrandom 0.2.16", "getrandom 0.3.3", "hex", - "indexmap 2.11.4", + "indexmap 2.13.0", "js-sys", "once_cell", "rand 0.9.2", @@ -2642,6 +2642,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + [[package]] name = "fontconfig-parser" version = "0.5.8" @@ -3072,7 +3078,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.11.4", + "indexmap 2.13.0", "slab", "tokio 1.47.1", "tokio-util", @@ -3091,7 +3097,7 @@ dependencies = [ "futures-core", "futures-sink", "http 1.3.1", - "indexmap 2.11.4", + "indexmap 2.13.0", "slab", "tokio 1.47.1", "tokio-util", @@ -3155,14 +3161,19 @@ checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ "allocator-api2", "equivalent", - "foldhash", + "foldhash 0.1.5", ] [[package]] name = "hashbrown" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.2.0", +] [[package]] name = "headers" @@ -3812,12 +3823,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.11.4" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", - "hashbrown 0.16.0", + "hashbrown 0.16.1", "serde", "serde_core", ] @@ -4573,6 +4584,15 @@ dependencies = [ "hashbrown 0.15.5", ] +[[package]] +name = "lru" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1dc47f592c06f33f8e3aea9591776ec7c9f9e4124778ff8a3c3b87159f7e593" +dependencies = [ + "hashbrown 0.16.1", +] + [[package]] name = "lru-cache" version = "0.1.2" @@ -5480,7 +5500,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.11.4", + "indexmap 2.13.0", ] [[package]] @@ -5673,7 +5693,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "740ebea15c5d1428f910cd1a5f52cebf8d25006245ed8ade92702f4943d91e07" dependencies = [ "base64 0.22.1", - "indexmap 2.11.4", + "indexmap 2.13.0", "quick-xml", "serde", "time", @@ -6519,7 +6539,7 @@ dependencies = [ [[package]] name = "revolt-autumn" -version = "0.8.8" +version = "0.9.1" dependencies = [ "axum", "axum-macros", @@ -6557,7 +6577,7 @@ dependencies = [ [[package]] name = "revolt-bonfire" -version = "0.8.8" +version = "0.9.1" dependencies = [ "async-channel 2.5.0", "async-std", @@ -6588,16 +6608,16 @@ dependencies = [ [[package]] name = "revolt-coalesced" -version = "0.8.8" +version = "0.9.1" dependencies = [ - "indexmap 2.11.4", - "lru 0.7.8", + "indexmap 2.13.0", + "lru 0.16.3", "tokio 1.47.1", ] [[package]] name = "revolt-config" -version = "0.8.8" +version = "0.9.1" dependencies = [ "async-std", "cached", @@ -6614,7 +6634,7 @@ dependencies = [ [[package]] name = "revolt-crond" -version = "0.8.8" +version = "0.9.1" dependencies = [ "log", "revolt-config", @@ -6626,7 +6646,7 @@ dependencies = [ [[package]] name = "revolt-database" -version = "0.8.8" +version = "0.9.1" dependencies = [ "amqprs", "async-lock 2.8.0", @@ -6676,7 +6696,7 @@ dependencies = [ [[package]] name = "revolt-delta" -version = "0.8.8" +version = "0.9.1" dependencies = [ "amqprs", "async-channel 1.9.0", @@ -6726,7 +6746,7 @@ dependencies = [ [[package]] name = "revolt-files" -version = "0.8.8" +version = "0.9.1" dependencies = [ "aes-gcm", "aws-config", @@ -6749,7 +6769,7 @@ dependencies = [ [[package]] name = "revolt-gifbox" -version = "0.8.8" +version = "0.9.1" dependencies = [ "axum", "axum-extra", @@ -6771,7 +6791,7 @@ dependencies = [ [[package]] name = "revolt-january" -version = "0.8.8" +version = "0.9.1" dependencies = [ "async-recursion", "axum", @@ -6799,7 +6819,7 @@ dependencies = [ [[package]] name = "revolt-models" -version = "0.8.8" +version = "0.9.1" dependencies = [ "indexmap 1.9.3", "iso8601-timestamp", @@ -6818,14 +6838,14 @@ dependencies = [ [[package]] name = "revolt-parser" -version = "0.8.8" +version = "0.9.1" dependencies = [ "logos", ] [[package]] name = "revolt-permissions" -version = "0.8.8" +version = "0.9.1" dependencies = [ "async-std", "async-trait", @@ -6840,7 +6860,7 @@ dependencies = [ [[package]] name = "revolt-presence" -version = "0.8.8" +version = "0.9.1" dependencies = [ "async-std", "log", @@ -6852,7 +6872,7 @@ dependencies = [ [[package]] name = "revolt-pushd" -version = "0.8.8" +version = "0.9.1" dependencies = [ "amqprs", "anyhow", @@ -6880,7 +6900,7 @@ dependencies = [ [[package]] name = "revolt-ratelimits" -version = "0.8.8" +version = "0.9.1" dependencies = [ "async-trait", "authifier", @@ -6897,7 +6917,7 @@ dependencies = [ [[package]] name = "revolt-result" -version = "0.8.8" +version = "0.9.1" dependencies = [ "axum", "log", @@ -6913,7 +6933,7 @@ dependencies = [ [[package]] name = "revolt-voice-ingress" -version = "0.7.1" +version = "0.9.1" dependencies = [ "amqprs", "async-std", @@ -7100,7 +7120,7 @@ dependencies = [ "either", "figment", "futures", - "indexmap 2.11.4", + "indexmap 2.13.0", "log", "memchr", "multer", @@ -7148,7 +7168,7 @@ checksum = "575d32d7ec1a9770108c879fc7c47815a80073f96ca07ff9525a94fcede1dd46" dependencies = [ "devise", "glob", - "indexmap 2.11.4", + "indexmap 2.13.0", "proc-macro2", "quote 1.0.40", "rocket_http", @@ -7195,7 +7215,7 @@ dependencies = [ "futures", "http 0.2.12", "hyper 0.14.32", - "indexmap 2.11.4", + "indexmap 2.13.0", "log", "memchr", "pear", @@ -7907,7 +7927,7 @@ version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ - "indexmap 2.11.4", + "indexmap 2.13.0", "itoa", "memchr", "ryu", @@ -7957,7 +7977,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.11.4", + "indexmap 2.13.0", "schemars 0.9.0", "schemars 1.0.4", "serde", @@ -8817,7 +8837,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.11.4", + "indexmap 2.13.0", "toml_datetime", "winnow 0.5.40", ] @@ -8828,7 +8848,7 @@ version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 2.11.4", + "indexmap 2.13.0", "serde", "serde_spanned", "toml_datetime", @@ -9306,7 +9326,7 @@ version = "4.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5afb1a60e207dca502682537fefcfd9921e71d0b83e9576060f09abc6efab23" dependencies = [ - "indexmap 2.11.4", + "indexmap 2.13.0", "serde", "serde_json", "utoipa-gen", diff --git a/compose.yml b/compose.yml index fadc22f84..008549c8a 100644 --- a/compose.yml +++ b/compose.yml @@ -1,13 +1,13 @@ services: # Redis redis: - image: eqalpha/keydb + image: public.ecr.aws/docker/library/redis ports: - "6379:6379" # MongoDB database: - image: mongo + image: public.ecr.aws/docker/library/mongo ports: - "27017:27017" volumes: @@ -15,7 +15,7 @@ services: # MinIO minio: - image: minio/minio + image: quay.io/minio/minio command: server /data environment: MINIO_ROOT_USER: minioautumn @@ -29,7 +29,7 @@ services: # Create buckets for minio. createbuckets: - image: minio/mc + image: quay.io/minio/mc depends_on: - minio entrypoint: > @@ -40,7 +40,7 @@ services: # Rabbit rabbit: - image: rabbitmq:4-management + image: public.ecr.aws/docker/library/rabbitmq:4-management environment: RABBITMQ_DEFAULT_USER: rabbituser RABBITMQ_DEFAULT_PASS: rabbitpass @@ -55,7 +55,7 @@ services: # Mock SMTP server maildev: - image: soulteary/maildev + image: maildev/maildev ports: - "14025:25" - "14080:8080" diff --git a/crates/core/coalesced/Cargo.toml b/crates/core/coalesced/Cargo.toml index 70d249bdc..b5bd2195e 100644 --- a/crates/core/coalesced/Cargo.toml +++ b/crates/core/coalesced/Cargo.toml @@ -15,8 +15,8 @@ default = ["tokio"] [dependencies] tokio = { version = "1.47.0", features = ["sync"], optional = true } -indexmap = { version = "*", optional = true } -lru = { version = "*", optional = true } +indexmap = { version = "2.13.0", optional = true } +lru = { version = "0.16.3", optional = true } [dev-dependencies] tokio = { version = "1.47.0", features = ["rt", "rt-multi-thread", "macros", "time"] } From 92b466a5f0601cf5e0ec0af7bf55a740513cd63a Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Sat, 10 Jan 2026 14:49:51 +0000 Subject: [PATCH 052/211] chore: switch back to docker hub since we cache it now (#489) --- compose.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/compose.yml b/compose.yml index 008549c8a..4ea6d9bc9 100644 --- a/compose.yml +++ b/compose.yml @@ -1,13 +1,13 @@ services: # Redis redis: - image: public.ecr.aws/docker/library/redis + image: eqalpha/keydb ports: - "6379:6379" # MongoDB database: - image: public.ecr.aws/docker/library/mongo + image: mongo ports: - "27017:27017" volumes: @@ -15,7 +15,7 @@ services: # MinIO minio: - image: quay.io/minio/minio + image: minio/minio command: server /data environment: MINIO_ROOT_USER: minioautumn @@ -29,7 +29,7 @@ services: # Create buckets for minio. createbuckets: - image: quay.io/minio/mc + image: minio/mc depends_on: - minio entrypoint: > @@ -40,7 +40,7 @@ services: # Rabbit rabbit: - image: public.ecr.aws/docker/library/rabbitmq:4-management + image: rabbitmq:4-management environment: RABBITMQ_DEFAULT_USER: rabbituser RABBITMQ_DEFAULT_PASS: rabbitpass From d0ea88f1f884ae2f96aa4db9a48483e6ba564211 Mon Sep 17 00:00:00 2001 From: "stoat-release[bot]" <245062572+stoat-release[bot]@users.noreply.github.com> Date: Sat, 10 Jan 2026 16:04:28 +0000 Subject: [PATCH 053/211] chore(main): release 0.9.3 (#488) Co-authored-by: stoat-release[bot] <245062572+stoat-release[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 7 +++++++ crates/bonfire/Cargo.toml | 2 +- crates/core/coalesced/Cargo.toml | 2 +- crates/core/config/Cargo.toml | 4 ++-- crates/core/database/Cargo.toml | 14 +++++++------- crates/core/files/Cargo.toml | 6 +++--- crates/core/models/Cargo.toml | 6 +++--- crates/core/parser/Cargo.toml | 2 +- crates/core/permissions/Cargo.toml | 4 ++-- crates/core/presence/Cargo.toml | 4 ++-- crates/core/ratelimits/Cargo.toml | 8 ++++---- crates/core/result/Cargo.toml | 2 +- crates/daemons/crond/Cargo.toml | 10 +++++----- crates/daemons/pushd/Cargo.toml | 12 ++++++------ crates/daemons/voice-ingress/Cargo.toml | 2 +- crates/delta/Cargo.toml | 2 +- crates/services/autumn/Cargo.toml | 12 ++++++------ crates/services/gifbox/Cargo.toml | 14 +++++++------- crates/services/january/Cargo.toml | 10 +++++----- version.txt | 2 +- 21 files changed, 67 insertions(+), 60 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 19735b032..968b3cc76 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.9.2" + ".": "0.9.3" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c7466e91..e56879011 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [0.9.3](https://github.com/stoatchat/stoatchat/compare/v0.9.2...v0.9.3) (2026-01-10) + + +### Bug Fixes + +* pipeline fixes ([#487](https://github.com/stoatchat/stoatchat/issues/487)) ([aeeafeb](https://github.com/stoatchat/stoatchat/commit/aeeafebefc36a43a656cf797c9251ca50292733c)) + ## [0.9.2](https://github.com/stoatchat/stoatchat/compare/v0.9.1...v0.9.2) (2026-01-10) diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index cea3987ae..861ed1dad 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-bonfire" -version = "0.9.2" +version = "0.9.3" license = "AGPL-3.0-or-later" edition = "2021" publish = false diff --git a/crates/core/coalesced/Cargo.toml b/crates/core/coalesced/Cargo.toml index b5bd2195e..8ceefb782 100644 --- a/crates/core/coalesced/Cargo.toml +++ b/crates/core/coalesced/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-coalesced" -version = "0.9.2" +version = "0.9.3" edition = "2021" license = "MIT" authors = ["Paul Makles ", "Zomatree "] diff --git a/crates/core/config/Cargo.toml b/crates/core/config/Cargo.toml index 60b9a9137..d18e5b8e1 100644 --- a/crates/core/config/Cargo.toml +++ b/crates/core/config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-config" -version = "0.9.2" +version = "0.9.3" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -37,4 +37,4 @@ sentry = { version = "0.31.5", optional = true } sentry-anyhow = { version = "0.38.1", optional = true } # Core -revolt-result = { version = "0.9.2", path = "../result", optional = true } +revolt-result = { version = "0.9.3", path = "../result", optional = true } diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index a3782b8cc..de84f88ad 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-database" -version = "0.9.2" +version = "0.9.3" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -25,19 +25,19 @@ default = ["mongodb", "async-std-runtime", "tasks"] [dependencies] # Core -revolt-config = { version = "0.9.2", path = "../config", features = [ +revolt-config = { version = "0.9.3", path = "../config", features = [ "report-macros", ] } -revolt-result = { version = "0.9.2", path = "../result" } -revolt-models = { version = "0.9.2", path = "../models", features = [ +revolt-result = { version = "0.9.3", path = "../result" } +revolt-models = { version = "0.9.3", path = "../models", features = [ "validator", ] } -revolt-presence = { version = "0.9.2", path = "../presence" } -revolt-permissions = { version = "0.9.2", path = "../permissions", features = [ +revolt-presence = { version = "0.9.3", path = "../presence" } +revolt-permissions = { version = "0.9.3", path = "../permissions", features = [ "serde", "bson", ] } -revolt-parser = { version = "0.9.2", path = "../parser" } +revolt-parser = { version = "0.9.3", path = "../parser" } # Utility log = "0.4" diff --git a/crates/core/files/Cargo.toml b/crates/core/files/Cargo.toml index 5a8fad2fe..fa9e99d27 100644 --- a/crates/core/files/Cargo.toml +++ b/crates/core/files/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-files" -version = "0.9.2" +version = "0.9.3" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -20,10 +20,10 @@ typenum = "1.17.0" aws-config = "1.5.5" aws-sdk-s3 = { version = "1.46.0", features = ["behavior-version-latest"] } -revolt-config = { version = "0.9.2", path = "../config", features = [ +revolt-config = { version = "0.9.3", path = "../config", features = [ "report-macros", ] } -revolt-result = { version = "0.9.2", path = "../result" } +revolt-result = { version = "0.9.3", path = "../result" } # image processing jxl-oxide = "0.8.1" diff --git a/crates/core/models/Cargo.toml b/crates/core/models/Cargo.toml index eaae7d8f6..feda14cee 100644 --- a/crates/core/models/Cargo.toml +++ b/crates/core/models/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-models" -version = "0.9.2" +version = "0.9.3" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -20,8 +20,8 @@ default = ["serde", "partials", "rocket"] [dependencies] # Core -revolt-config = { version = "0.9.2", path = "../config" } -revolt-permissions = { version = "0.9.2", path = "../permissions" } +revolt-config = { version = "0.9.3", path = "../config" } +revolt-permissions = { version = "0.9.3", path = "../permissions" } # Utility regex = "1.11" diff --git a/crates/core/parser/Cargo.toml b/crates/core/parser/Cargo.toml index fc3e4456e..f6cb19404 100644 --- a/crates/core/parser/Cargo.toml +++ b/crates/core/parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-parser" -version = "0.9.2" +version = "0.9.3" edition = "2021" license = "MIT" authors = ["Zomatree ", "Paul Makles "] diff --git a/crates/core/permissions/Cargo.toml b/crates/core/permissions/Cargo.toml index d12f9d356..26217db66 100644 --- a/crates/core/permissions/Cargo.toml +++ b/crates/core/permissions/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-permissions" -version = "0.9.2" +version = "0.9.3" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -21,7 +21,7 @@ async-std = { version = "1.8.0", features = ["attributes"] } [dependencies] # Core -revolt-result = { version = "0.9.2", path = "../result" } +revolt-result = { version = "0.9.3", path = "../result" } # Utility auto_ops = "0.3.0" diff --git a/crates/core/presence/Cargo.toml b/crates/core/presence/Cargo.toml index 74455b584..d73b188de 100644 --- a/crates/core/presence/Cargo.toml +++ b/crates/core/presence/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-presence" -version = "0.9.2" +version = "0.9.3" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -16,7 +16,7 @@ redis-is-patched = [] async-std = { version = "1.8.0", features = ["attributes"] } # Config for loading Redis URI -revolt-config = { version = "0.9.2", path = "../config" } +revolt-config = { version = "0.9.3", path = "../config" } [dependencies] # Utility diff --git a/crates/core/ratelimits/Cargo.toml b/crates/core/ratelimits/Cargo.toml index 1335c8ec5..e2302b542 100644 --- a/crates/core/ratelimits/Cargo.toml +++ b/crates/core/ratelimits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-ratelimits" -version = "0.9.2" +version = "0.9.3" edition = "2024" [features] @@ -10,9 +10,9 @@ axum = ["dep:axum", "revolt-database/axum-impl"] default = ["rocket", "axum"] [dependencies] -revolt-database = { version = "0.9.2", path = "../database"} -revolt-result = { version = "0.9.2", path = "../result" } -revolt-config = { version = "0.9.2", path = "../config" } +revolt-database = { version = "0.9.3", path = "../database"} +revolt-result = { version = "0.9.3", path = "../result" } +revolt-config = { version = "0.9.3", path = "../config" } rocket = { version = "0.5.1", optional = true } revolt_rocket_okapi = { version = "0.10.0", optional = true } diff --git a/crates/core/result/Cargo.toml b/crates/core/result/Cargo.toml index a6f2ae329..3c29470d3 100644 --- a/crates/core/result/Cargo.toml +++ b/crates/core/result/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-result" -version = "0.9.2" +version = "0.9.3" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/daemons/crond/Cargo.toml b/crates/daemons/crond/Cargo.toml index 3673cd6b6..04560126c 100644 --- a/crates/daemons/crond/Cargo.toml +++ b/crates/daemons/crond/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-crond" -version = "0.9.2" +version = "0.9.3" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2021" @@ -17,7 +17,7 @@ log = "0.4" tokio = { version = "1" } # Core -revolt-database = { version = "0.9.2", path = "../../core/database" } -revolt-result = { version = "0.9.2", path = "../../core/result" } -revolt-config = { version = "0.9.2", path = "../../core/config" } -revolt-files = { version = "0.9.2", path = "../../core/files" } +revolt-database = { version = "0.9.3", path = "../../core/database" } +revolt-result = { version = "0.9.3", path = "../../core/result" } +revolt-config = { version = "0.9.3", path = "../../core/config" } +revolt-files = { version = "0.9.3", path = "../../core/files" } diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index 7b17ae7e7..abe74a5cd 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -1,21 +1,21 @@ [package] name = "revolt-pushd" -version = "0.9.2" +version = "0.9.3" edition = "2021" license = "AGPL-3.0-or-later" publish = false [dependencies] -revolt-result = { version = "0.9.2", path = "../../core/result" } -revolt-config = { version = "0.9.2", path = "../../core/config", features = [ +revolt-result = { version = "0.9.3", path = "../../core/result" } +revolt-config = { version = "0.9.3", path = "../../core/config", features = [ "report-macros", "anyhow" ] } -revolt-database = { version = "0.9.2", path = "../../core/database" } -revolt-models = { version = "0.9.2", path = "../../core/models", features = [ +revolt-database = { version = "0.9.3", path = "../../core/database" } +revolt-models = { version = "0.9.3", path = "../../core/models", features = [ "validator", ] } -revolt-presence = { version = "0.9.2", path = "../../core/presence", features = [ +revolt-presence = { version = "0.9.3", path = "../../core/presence", features = [ "redis-is-patched", ] } diff --git a/crates/daemons/voice-ingress/Cargo.toml b/crates/daemons/voice-ingress/Cargo.toml index 82ee3a3ca..06b30cf9e 100644 --- a/crates/daemons/voice-ingress/Cargo.toml +++ b/crates/daemons/voice-ingress/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-voice-ingress" -version = "0.9.2" +version = "0.9.3" license = "AGPL-3.0-or-later" edition = "2021" publish = false diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index 5457ab3ee..5057d315f 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-delta" -version = "0.9.2" +version = "0.9.3" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2018" diff --git a/crates/services/autumn/Cargo.toml b/crates/services/autumn/Cargo.toml index 5ffdb808e..d082b6d08 100644 --- a/crates/services/autumn/Cargo.toml +++ b/crates/services/autumn/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-autumn" -version = "0.9.2" +version = "0.9.3" edition = "2021" license = "AGPL-3.0-or-later" publish = false @@ -44,16 +44,16 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # Core crates -revolt-files = { version = "0.9.2", path = "../../core/files" } -revolt-config = { version = "0.9.2", path = "../../core/config" } -revolt-database = { version = "0.9.2", path = "../../core/database", features = [ +revolt-files = { version = "0.9.3", path = "../../core/files" } +revolt-config = { version = "0.9.3", path = "../../core/config" } +revolt-database = { version = "0.9.3", path = "../../core/database", features = [ "axum-impl", ] } -revolt-result = { version = "0.9.2", path = "../../core/result", features = [ +revolt-result = { version = "0.9.3", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-ratelimits = { version = "0.9.2", path = "../../core/ratelimits", features = ["axum"] } +revolt-ratelimits = { version = "0.9.3", path = "../../core/ratelimits", features = ["axum"] } # Axum / web server tempfile = "3.12.0" diff --git a/crates/services/gifbox/Cargo.toml b/crates/services/gifbox/Cargo.toml index 9f7f6f3cd..0684fcbd6 100644 --- a/crates/services/gifbox/Cargo.toml +++ b/crates/services/gifbox/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-gifbox" -version = "0.9.2" +version = "0.9.3" edition = "2021" license = "AGPL-3.0-or-later" publish = false @@ -17,19 +17,19 @@ tokio = { version = "1.0", features = ["full"] } reqwest = { version = "0.12", features = ["json"] } # Core crates -revolt-config = { version = "0.9.2", path = "../../core/config" } -revolt-models = { version = "0.9.2", path = "../../core/models" } -revolt-result = { version = "0.9.2", path = "../../core/result", features = [ +revolt-config = { version = "0.9.3", path = "../../core/config" } +revolt-models = { version = "0.9.3", path = "../../core/models" } +revolt-result = { version = "0.9.3", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-coalesced = { version = "0.9.2", path = "../../core/coalesced", features = [ +revolt-coalesced = { version = "0.9.3", path = "../../core/coalesced", features = [ "queue", ] } -revolt-database = { version = "0.9.2", path = "../../core/database", features = [ +revolt-database = { version = "0.9.3", path = "../../core/database", features = [ "axum-impl", ] } -revolt-ratelimits = { version = "0.9.2", path = "../../core/ratelimits", features = [ +revolt-ratelimits = { version = "0.9.3", path = "../../core/ratelimits", features = [ "axum", ] } diff --git a/crates/services/january/Cargo.toml b/crates/services/january/Cargo.toml index b63b54341..f12ba6b89 100644 --- a/crates/services/january/Cargo.toml +++ b/crates/services/january/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-january" -version = "0.9.2" +version = "0.9.3" edition = "2021" license = "AGPL-3.0-or-later" publish = false @@ -33,13 +33,13 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # Core crates -revolt-config = { version = "0.9.2", path = "../../core/config" } -revolt-models = { version = "0.9.2", path = "../../core/models" } -revolt-result = { version = "0.9.2", path = "../../core/result", features = [ +revolt-config = { version = "0.9.3", path = "../../core/config" } +revolt-models = { version = "0.9.3", path = "../../core/models" } +revolt-result = { version = "0.9.3", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-files = { version = "0.9.2", path = "../../core/files" } +revolt-files = { version = "0.9.3", path = "../../core/files" } # Axum / web server axum = { version = "0.7.5" } diff --git a/version.txt b/version.txt index 2003b639c..965065db5 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.9.2 +0.9.3 From b2da2a858787853be43136fd526a0bd72baf78ef Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Sat, 10 Jan 2026 16:22:42 +0000 Subject: [PATCH 054/211] fix: checkout repo. before bumping lock (#490) --- .github/workflows/release-please.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 7633e2bc8..a1ea1393e 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -38,6 +38,9 @@ jobs: with: toolchain: stable + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + with: + persist-credentials: false - name: Update Cargo.lock if: ${{ steps.rp.outputs.prs_created == 'true' || steps.rp.outputs.prs_updated == 'true' }} env: From c674a9fd4e0abbd51569870e4b38074d4a1de03c Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Sat, 10 Jan 2026 16:25:29 +0000 Subject: [PATCH 055/211] fix: persist credentials for git repo (#492) --- .github/workflows/release-please.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index a1ea1393e..7e68e112b 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -40,7 +40,7 @@ jobs: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: - persist-credentials: false + token: ${{ steps.app-token.outputs.token }} - name: Update Cargo.lock if: ${{ steps.rp.outputs.prs_created == 'true' || steps.rp.outputs.prs_updated == 'true' }} env: From c413fbcb585b0a2a096e0844420335463448d202 Mon Sep 17 00:00:00 2001 From: "stoat-tofu[bot]" <242700035+stoat-tofu[bot]@users.noreply.github.com> Date: Sat, 10 Jan 2026 16:33:17 +0000 Subject: [PATCH 056/211] chore: modify .github/workflows/release-webhook.yml --- .github/workflows/release-webhook.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-webhook.yml b/.github/workflows/release-webhook.yml index 41e856521..58a1d4198 100644 --- a/.github/workflows/release-webhook.yml +++ b/.github/workflows/release-webhook.yml @@ -13,7 +13,7 @@ jobs: steps: - name: Send release notification webhook run: | - RELEASE_URL="https://github.com/${{ github.repository }}/releases/tag/${{ needs.release-please.outputs.tag_name }}" + RELEASE_URL="https://github.com/${{ github.repository }}/releases/tag/${{ github.event.release.tag_name }}" curl -X POST "${{ secrets.STOAT_WEBHOOK_UPDATES_URL }}" \ -H "Content-Type: application/json" \ -d "{\"content\": \"$RELEASE_URL\"}" From 50835f08c85c223e79513f51298658fa18c31a5a Mon Sep 17 00:00:00 2001 From: "stoat-release[bot]" <245062572+stoat-release[bot]@users.noreply.github.com> Date: Sat, 10 Jan 2026 17:55:04 +0000 Subject: [PATCH 057/211] chore(main): release 0.9.4 (#491) Co-authored-by: stoat-release[bot] <245062572+stoat-release[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] Co-authored-by: izzy --- .release-please-manifest.json | 2 +- CHANGELOG.md | 8 ++++++ Cargo.lock | 36 ++++++++++++------------- crates/bonfire/Cargo.toml | 2 +- crates/core/coalesced/Cargo.toml | 2 +- crates/core/config/Cargo.toml | 4 +-- crates/core/database/Cargo.toml | 14 +++++----- crates/core/files/Cargo.toml | 6 ++--- crates/core/models/Cargo.toml | 6 ++--- crates/core/parser/Cargo.toml | 2 +- crates/core/permissions/Cargo.toml | 4 +-- crates/core/presence/Cargo.toml | 4 +-- crates/core/ratelimits/Cargo.toml | 8 +++--- crates/core/result/Cargo.toml | 2 +- crates/daemons/crond/Cargo.toml | 10 +++---- crates/daemons/pushd/Cargo.toml | 12 ++++----- crates/daemons/voice-ingress/Cargo.toml | 2 +- crates/delta/Cargo.toml | 2 +- crates/services/autumn/Cargo.toml | 12 ++++----- crates/services/gifbox/Cargo.toml | 14 +++++----- crates/services/january/Cargo.toml | 10 +++---- version.txt | 2 +- 22 files changed, 86 insertions(+), 78 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 968b3cc76..7bff16bcd 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.9.3" + ".": "0.9.4" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index e56879011..22da6e66c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [0.9.4](https://github.com/stoatchat/stoatchat/compare/v0.9.3...v0.9.4) (2026-01-10) + + +### Bug Fixes + +* checkout repo. before bumping lock ([#490](https://github.com/stoatchat/stoatchat/issues/490)) ([b2da2a8](https://github.com/stoatchat/stoatchat/commit/b2da2a858787853be43136fd526a0bd72baf78ef)) +* persist credentials for git repo ([#492](https://github.com/stoatchat/stoatchat/issues/492)) ([c674a9f](https://github.com/stoatchat/stoatchat/commit/c674a9fd4e0abbd51569870e4b38074d4a1de03c)) + ## [0.9.3](https://github.com/stoatchat/stoatchat/compare/v0.9.2...v0.9.3) (2026-01-10) diff --git a/Cargo.lock b/Cargo.lock index 5326152fa..878658d7d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6539,7 +6539,7 @@ dependencies = [ [[package]] name = "revolt-autumn" -version = "0.9.1" +version = "0.9.4" dependencies = [ "axum", "axum-macros", @@ -6577,7 +6577,7 @@ dependencies = [ [[package]] name = "revolt-bonfire" -version = "0.9.1" +version = "0.9.4" dependencies = [ "async-channel 2.5.0", "async-std", @@ -6608,7 +6608,7 @@ dependencies = [ [[package]] name = "revolt-coalesced" -version = "0.9.1" +version = "0.9.4" dependencies = [ "indexmap 2.13.0", "lru 0.16.3", @@ -6617,7 +6617,7 @@ dependencies = [ [[package]] name = "revolt-config" -version = "0.9.1" +version = "0.9.4" dependencies = [ "async-std", "cached", @@ -6634,7 +6634,7 @@ dependencies = [ [[package]] name = "revolt-crond" -version = "0.9.1" +version = "0.9.4" dependencies = [ "log", "revolt-config", @@ -6646,7 +6646,7 @@ dependencies = [ [[package]] name = "revolt-database" -version = "0.9.1" +version = "0.9.4" dependencies = [ "amqprs", "async-lock 2.8.0", @@ -6696,7 +6696,7 @@ dependencies = [ [[package]] name = "revolt-delta" -version = "0.9.1" +version = "0.9.4" dependencies = [ "amqprs", "async-channel 1.9.0", @@ -6746,7 +6746,7 @@ dependencies = [ [[package]] name = "revolt-files" -version = "0.9.1" +version = "0.9.4" dependencies = [ "aes-gcm", "aws-config", @@ -6769,7 +6769,7 @@ dependencies = [ [[package]] name = "revolt-gifbox" -version = "0.9.1" +version = "0.9.4" dependencies = [ "axum", "axum-extra", @@ -6791,7 +6791,7 @@ dependencies = [ [[package]] name = "revolt-january" -version = "0.9.1" +version = "0.9.4" dependencies = [ "async-recursion", "axum", @@ -6819,7 +6819,7 @@ dependencies = [ [[package]] name = "revolt-models" -version = "0.9.1" +version = "0.9.4" dependencies = [ "indexmap 1.9.3", "iso8601-timestamp", @@ -6838,14 +6838,14 @@ dependencies = [ [[package]] name = "revolt-parser" -version = "0.9.1" +version = "0.9.4" dependencies = [ "logos", ] [[package]] name = "revolt-permissions" -version = "0.9.1" +version = "0.9.4" dependencies = [ "async-std", "async-trait", @@ -6860,7 +6860,7 @@ dependencies = [ [[package]] name = "revolt-presence" -version = "0.9.1" +version = "0.9.4" dependencies = [ "async-std", "log", @@ -6872,7 +6872,7 @@ dependencies = [ [[package]] name = "revolt-pushd" -version = "0.9.1" +version = "0.9.4" dependencies = [ "amqprs", "anyhow", @@ -6900,7 +6900,7 @@ dependencies = [ [[package]] name = "revolt-ratelimits" -version = "0.9.1" +version = "0.9.4" dependencies = [ "async-trait", "authifier", @@ -6917,7 +6917,7 @@ dependencies = [ [[package]] name = "revolt-result" -version = "0.9.1" +version = "0.9.4" dependencies = [ "axum", "log", @@ -6933,7 +6933,7 @@ dependencies = [ [[package]] name = "revolt-voice-ingress" -version = "0.9.1" +version = "0.9.4" dependencies = [ "amqprs", "async-std", diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index 861ed1dad..ca0ce9bb5 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-bonfire" -version = "0.9.3" +version = "0.9.4" license = "AGPL-3.0-or-later" edition = "2021" publish = false diff --git a/crates/core/coalesced/Cargo.toml b/crates/core/coalesced/Cargo.toml index 8ceefb782..f267999bd 100644 --- a/crates/core/coalesced/Cargo.toml +++ b/crates/core/coalesced/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-coalesced" -version = "0.9.3" +version = "0.9.4" edition = "2021" license = "MIT" authors = ["Paul Makles ", "Zomatree "] diff --git a/crates/core/config/Cargo.toml b/crates/core/config/Cargo.toml index d18e5b8e1..986f78a30 100644 --- a/crates/core/config/Cargo.toml +++ b/crates/core/config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-config" -version = "0.9.3" +version = "0.9.4" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -37,4 +37,4 @@ sentry = { version = "0.31.5", optional = true } sentry-anyhow = { version = "0.38.1", optional = true } # Core -revolt-result = { version = "0.9.3", path = "../result", optional = true } +revolt-result = { version = "0.9.4", path = "../result", optional = true } diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index de84f88ad..593e906a4 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-database" -version = "0.9.3" +version = "0.9.4" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -25,19 +25,19 @@ default = ["mongodb", "async-std-runtime", "tasks"] [dependencies] # Core -revolt-config = { version = "0.9.3", path = "../config", features = [ +revolt-config = { version = "0.9.4", path = "../config", features = [ "report-macros", ] } -revolt-result = { version = "0.9.3", path = "../result" } -revolt-models = { version = "0.9.3", path = "../models", features = [ +revolt-result = { version = "0.9.4", path = "../result" } +revolt-models = { version = "0.9.4", path = "../models", features = [ "validator", ] } -revolt-presence = { version = "0.9.3", path = "../presence" } -revolt-permissions = { version = "0.9.3", path = "../permissions", features = [ +revolt-presence = { version = "0.9.4", path = "../presence" } +revolt-permissions = { version = "0.9.4", path = "../permissions", features = [ "serde", "bson", ] } -revolt-parser = { version = "0.9.3", path = "../parser" } +revolt-parser = { version = "0.9.4", path = "../parser" } # Utility log = "0.4" diff --git a/crates/core/files/Cargo.toml b/crates/core/files/Cargo.toml index fa9e99d27..ad5f17687 100644 --- a/crates/core/files/Cargo.toml +++ b/crates/core/files/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-files" -version = "0.9.3" +version = "0.9.4" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -20,10 +20,10 @@ typenum = "1.17.0" aws-config = "1.5.5" aws-sdk-s3 = { version = "1.46.0", features = ["behavior-version-latest"] } -revolt-config = { version = "0.9.3", path = "../config", features = [ +revolt-config = { version = "0.9.4", path = "../config", features = [ "report-macros", ] } -revolt-result = { version = "0.9.3", path = "../result" } +revolt-result = { version = "0.9.4", path = "../result" } # image processing jxl-oxide = "0.8.1" diff --git a/crates/core/models/Cargo.toml b/crates/core/models/Cargo.toml index feda14cee..77721a142 100644 --- a/crates/core/models/Cargo.toml +++ b/crates/core/models/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-models" -version = "0.9.3" +version = "0.9.4" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -20,8 +20,8 @@ default = ["serde", "partials", "rocket"] [dependencies] # Core -revolt-config = { version = "0.9.3", path = "../config" } -revolt-permissions = { version = "0.9.3", path = "../permissions" } +revolt-config = { version = "0.9.4", path = "../config" } +revolt-permissions = { version = "0.9.4", path = "../permissions" } # Utility regex = "1.11" diff --git a/crates/core/parser/Cargo.toml b/crates/core/parser/Cargo.toml index f6cb19404..8f287a593 100644 --- a/crates/core/parser/Cargo.toml +++ b/crates/core/parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-parser" -version = "0.9.3" +version = "0.9.4" edition = "2021" license = "MIT" authors = ["Zomatree ", "Paul Makles "] diff --git a/crates/core/permissions/Cargo.toml b/crates/core/permissions/Cargo.toml index 26217db66..fb0cf0e8a 100644 --- a/crates/core/permissions/Cargo.toml +++ b/crates/core/permissions/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-permissions" -version = "0.9.3" +version = "0.9.4" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -21,7 +21,7 @@ async-std = { version = "1.8.0", features = ["attributes"] } [dependencies] # Core -revolt-result = { version = "0.9.3", path = "../result" } +revolt-result = { version = "0.9.4", path = "../result" } # Utility auto_ops = "0.3.0" diff --git a/crates/core/presence/Cargo.toml b/crates/core/presence/Cargo.toml index d73b188de..de443e3f9 100644 --- a/crates/core/presence/Cargo.toml +++ b/crates/core/presence/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-presence" -version = "0.9.3" +version = "0.9.4" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -16,7 +16,7 @@ redis-is-patched = [] async-std = { version = "1.8.0", features = ["attributes"] } # Config for loading Redis URI -revolt-config = { version = "0.9.3", path = "../config" } +revolt-config = { version = "0.9.4", path = "../config" } [dependencies] # Utility diff --git a/crates/core/ratelimits/Cargo.toml b/crates/core/ratelimits/Cargo.toml index e2302b542..da0aad74f 100644 --- a/crates/core/ratelimits/Cargo.toml +++ b/crates/core/ratelimits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-ratelimits" -version = "0.9.3" +version = "0.9.4" edition = "2024" [features] @@ -10,9 +10,9 @@ axum = ["dep:axum", "revolt-database/axum-impl"] default = ["rocket", "axum"] [dependencies] -revolt-database = { version = "0.9.3", path = "../database"} -revolt-result = { version = "0.9.3", path = "../result" } -revolt-config = { version = "0.9.3", path = "../config" } +revolt-database = { version = "0.9.4", path = "../database"} +revolt-result = { version = "0.9.4", path = "../result" } +revolt-config = { version = "0.9.4", path = "../config" } rocket = { version = "0.5.1", optional = true } revolt_rocket_okapi = { version = "0.10.0", optional = true } diff --git a/crates/core/result/Cargo.toml b/crates/core/result/Cargo.toml index 3c29470d3..66c6132a6 100644 --- a/crates/core/result/Cargo.toml +++ b/crates/core/result/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-result" -version = "0.9.3" +version = "0.9.4" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/daemons/crond/Cargo.toml b/crates/daemons/crond/Cargo.toml index 04560126c..762ce469c 100644 --- a/crates/daemons/crond/Cargo.toml +++ b/crates/daemons/crond/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-crond" -version = "0.9.3" +version = "0.9.4" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2021" @@ -17,7 +17,7 @@ log = "0.4" tokio = { version = "1" } # Core -revolt-database = { version = "0.9.3", path = "../../core/database" } -revolt-result = { version = "0.9.3", path = "../../core/result" } -revolt-config = { version = "0.9.3", path = "../../core/config" } -revolt-files = { version = "0.9.3", path = "../../core/files" } +revolt-database = { version = "0.9.4", path = "../../core/database" } +revolt-result = { version = "0.9.4", path = "../../core/result" } +revolt-config = { version = "0.9.4", path = "../../core/config" } +revolt-files = { version = "0.9.4", path = "../../core/files" } diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index abe74a5cd..59e2b1c7e 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -1,21 +1,21 @@ [package] name = "revolt-pushd" -version = "0.9.3" +version = "0.9.4" edition = "2021" license = "AGPL-3.0-or-later" publish = false [dependencies] -revolt-result = { version = "0.9.3", path = "../../core/result" } -revolt-config = { version = "0.9.3", path = "../../core/config", features = [ +revolt-result = { version = "0.9.4", path = "../../core/result" } +revolt-config = { version = "0.9.4", path = "../../core/config", features = [ "report-macros", "anyhow" ] } -revolt-database = { version = "0.9.3", path = "../../core/database" } -revolt-models = { version = "0.9.3", path = "../../core/models", features = [ +revolt-database = { version = "0.9.4", path = "../../core/database" } +revolt-models = { version = "0.9.4", path = "../../core/models", features = [ "validator", ] } -revolt-presence = { version = "0.9.3", path = "../../core/presence", features = [ +revolt-presence = { version = "0.9.4", path = "../../core/presence", features = [ "redis-is-patched", ] } diff --git a/crates/daemons/voice-ingress/Cargo.toml b/crates/daemons/voice-ingress/Cargo.toml index 06b30cf9e..6e60f765d 100644 --- a/crates/daemons/voice-ingress/Cargo.toml +++ b/crates/daemons/voice-ingress/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-voice-ingress" -version = "0.9.3" +version = "0.9.4" license = "AGPL-3.0-or-later" edition = "2021" publish = false diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index 5057d315f..895815aa3 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-delta" -version = "0.9.3" +version = "0.9.4" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2018" diff --git a/crates/services/autumn/Cargo.toml b/crates/services/autumn/Cargo.toml index d082b6d08..7d8eb27f7 100644 --- a/crates/services/autumn/Cargo.toml +++ b/crates/services/autumn/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-autumn" -version = "0.9.3" +version = "0.9.4" edition = "2021" license = "AGPL-3.0-or-later" publish = false @@ -44,16 +44,16 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # Core crates -revolt-files = { version = "0.9.3", path = "../../core/files" } -revolt-config = { version = "0.9.3", path = "../../core/config" } -revolt-database = { version = "0.9.3", path = "../../core/database", features = [ +revolt-files = { version = "0.9.4", path = "../../core/files" } +revolt-config = { version = "0.9.4", path = "../../core/config" } +revolt-database = { version = "0.9.4", path = "../../core/database", features = [ "axum-impl", ] } -revolt-result = { version = "0.9.3", path = "../../core/result", features = [ +revolt-result = { version = "0.9.4", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-ratelimits = { version = "0.9.3", path = "../../core/ratelimits", features = ["axum"] } +revolt-ratelimits = { version = "0.9.4", path = "../../core/ratelimits", features = ["axum"] } # Axum / web server tempfile = "3.12.0" diff --git a/crates/services/gifbox/Cargo.toml b/crates/services/gifbox/Cargo.toml index 0684fcbd6..fade557cd 100644 --- a/crates/services/gifbox/Cargo.toml +++ b/crates/services/gifbox/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-gifbox" -version = "0.9.3" +version = "0.9.4" edition = "2021" license = "AGPL-3.0-or-later" publish = false @@ -17,19 +17,19 @@ tokio = { version = "1.0", features = ["full"] } reqwest = { version = "0.12", features = ["json"] } # Core crates -revolt-config = { version = "0.9.3", path = "../../core/config" } -revolt-models = { version = "0.9.3", path = "../../core/models" } -revolt-result = { version = "0.9.3", path = "../../core/result", features = [ +revolt-config = { version = "0.9.4", path = "../../core/config" } +revolt-models = { version = "0.9.4", path = "../../core/models" } +revolt-result = { version = "0.9.4", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-coalesced = { version = "0.9.3", path = "../../core/coalesced", features = [ +revolt-coalesced = { version = "0.9.4", path = "../../core/coalesced", features = [ "queue", ] } -revolt-database = { version = "0.9.3", path = "../../core/database", features = [ +revolt-database = { version = "0.9.4", path = "../../core/database", features = [ "axum-impl", ] } -revolt-ratelimits = { version = "0.9.3", path = "../../core/ratelimits", features = [ +revolt-ratelimits = { version = "0.9.4", path = "../../core/ratelimits", features = [ "axum", ] } diff --git a/crates/services/january/Cargo.toml b/crates/services/january/Cargo.toml index f12ba6b89..acbba6fcc 100644 --- a/crates/services/january/Cargo.toml +++ b/crates/services/january/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-january" -version = "0.9.3" +version = "0.9.4" edition = "2021" license = "AGPL-3.0-or-later" publish = false @@ -33,13 +33,13 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # Core crates -revolt-config = { version = "0.9.3", path = "../../core/config" } -revolt-models = { version = "0.9.3", path = "../../core/models" } -revolt-result = { version = "0.9.3", path = "../../core/result", features = [ +revolt-config = { version = "0.9.4", path = "../../core/config" } +revolt-models = { version = "0.9.4", path = "../../core/models" } +revolt-result = { version = "0.9.4", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-files = { version = "0.9.3", path = "../../core/files" } +revolt-files = { version = "0.9.4", path = "../../core/files" } # Axum / web server axum = { version = "0.7.5" } diff --git a/version.txt b/version.txt index 965065db5..a602fc9e2 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.9.3 +0.9.4 From 2846f09c4525c3fd4fdcf9486e8bfb8c51f19827 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Wed, 21 Jan 2026 23:41:58 +0000 Subject: [PATCH 058/211] chore: switch to mise for tooling & update crates for publishing (#494) --- .github/workflows/docs-test.yml | 18 ++---- .github/workflows/docs.yml | 18 ++---- .github/workflows/publish-crates.yml | 9 ++- .github/workflows/rust.yaml | 32 ++++------- .mise/config.toml | 17 ++++++ .mise/tasks/build | 5 ++ .mise/tasks/check | 5 ++ .mise/tasks/docker/start | 5 ++ .mise/tasks/docker/stop | 5 ++ .mise/tasks/docs/_default | 7 +++ .mise/tasks/docs/build | 7 +++ .mise/tasks/docs/install | 6 ++ .mise/tasks/publish | 5 ++ .mise/tasks/service/api | 5 ++ .mise/tasks/service/crond | 5 ++ .mise/tasks/service/events | 5 ++ .mise/tasks/service/files | 5 ++ .mise/tasks/service/gifbox | 5 ++ .mise/tasks/service/proxy | 5 ++ .mise/tasks/service/pushd | 5 ++ .mise/tasks/test | 5 ++ README.md | 6 +- compose.yml | 4 ++ crates/core/coalesced/Cargo.toml | 8 ++- crates/core/config/Cargo.toml | 1 + crates/core/database/Cargo.toml | 13 ++++- crates/core/files/Cargo.toml | 1 + crates/core/models/Cargo.toml | 1 + crates/core/parser/Cargo.toml | 1 + crates/core/permissions/Cargo.toml | 1 + crates/core/presence/Cargo.toml | 1 + crates/core/ratelimits/Cargo.toml | 12 +++- crates/core/result/Cargo.toml | 3 +- .../src/routes/channels/message_unpin.rs | 5 +- default.nix | 57 ++++++++++++------- scripts/start.sh | 15 ----- 36 files changed, 212 insertions(+), 96 deletions(-) create mode 100644 .mise/config.toml create mode 100755 .mise/tasks/build create mode 100755 .mise/tasks/check create mode 100755 .mise/tasks/docker/start create mode 100755 .mise/tasks/docker/stop create mode 100755 .mise/tasks/docs/_default create mode 100755 .mise/tasks/docs/build create mode 100755 .mise/tasks/docs/install create mode 100755 .mise/tasks/publish create mode 100755 .mise/tasks/service/api create mode 100755 .mise/tasks/service/crond create mode 100755 .mise/tasks/service/events create mode 100755 .mise/tasks/service/files create mode 100755 .mise/tasks/service/gifbox create mode 100755 .mise/tasks/service/proxy create mode 100755 .mise/tasks/service/pushd create mode 100755 .mise/tasks/test delete mode 100755 scripts/start.sh diff --git a/.github/workflows/docs-test.yml b/.github/workflows/docs-test.yml index 38c449102..26a065fc1 100644 --- a/.github/workflows/docs-test.yml +++ b/.github/workflows/docs-test.yml @@ -14,16 +14,10 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: pnpm/action-setup@v4 - with: - package_json_file: ./docs/package.json - - uses: actions/setup-node@v4 - with: - node-version: lts/* - cache: pnpm - cache-dependency-path: ./docs/pnpm-lock.yaml - - name: Install dependencies - run: pnpm install - - name: Test build website - run: pnpm run build \ No newline at end of file + - name: Setup Mise + uses: immich-app/devtools/actions/use-mise@cd24790a7f5f6439ac32cc94f5523cb2de8bfa8c # use-mise-action-v1.1.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + + - run: mise docs:build diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 74faefc0c..451deda74 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -16,19 +16,13 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: pnpm/action-setup@v4 - with: - package_json_file: ./docs/package.json - - uses: actions/setup-node@v4 + + - name: Setup Mise + uses: immich-app/devtools/actions/use-mise@cd24790a7f5f6439ac32cc94f5523cb2de8bfa8c # use-mise-action-v1.1.0 with: - node-version: lts/* - cache: pnpm - cache-dependency-path: ./docs/pnpm-lock.yaml - - - name: Install dependencies - run: pnpm install - - name: Build website - run: pnpm run build + github-token: ${{ secrets.GITHUB_TOKEN }} + + - run: mise docs:build - name: Upload Build Artifact uses: actions/upload-pages-artifact@v3 diff --git a/.github/workflows/publish-crates.yml b/.github/workflows/publish-crates.yml index c952a35d8..ce02d8418 100644 --- a/.github/workflows/publish-crates.yml +++ b/.github/workflows/publish-crates.yml @@ -15,7 +15,10 @@ jobs: with: persist-credentials: false - - name: Publish crates - uses: katyo/publish-crates@02cc2f1ad653fb25c7d1ff9eb590a8a50d06186b # v2 + - name: Setup Mise + uses: immich-app/devtools/actions/use-mise@cd24790a7f5f6439ac32cc94f5523cb2de8bfa8c # use-mise-action-v1.1.0 with: - registry-token: ${{ secrets.CRATES_IO_PUBLISH_TOKEN }} + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Publish + run: mise publish --workspace diff --git a/.github/workflows/rust.yaml b/.github/workflows/rust.yaml index c65d03f3a..08e210a3f 100644 --- a/.github/workflows/rust.yaml +++ b/.github/workflows/rust.yaml @@ -26,43 +26,33 @@ jobs: # run: | # sudo rm -rf /usr/local/lib/android /usr/share/dotnet /opt/ghc - - name: Install latest stable - uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # v1 + - name: Setup Mise + uses: immich-app/devtools/actions/use-mise@cd24790a7f5f6439ac32cc94f5523cb2de8bfa8c # use-mise-action-v1.1.0 with: - toolchain: stable - components: rustfmt, clippy - - - name: Install cargo-nextest - uses: taiki-e/install-action@a58ae9526b2c3acee9ad8e1926b950b7863305d4 # 2.65.16 - with: - tool: cargo-nextest@0.9.119 - - - name: Run cargo build - run: cargo build - - - name: Run services in background - run: | - docker compose -f compose.yml up -d + github-token: ${{ secrets.GITHUB_TOKEN }} - - name: Run cargo test + - run: mise build + - run: mise docker:start + + - name: Reference Test env: TEST_DB: REFERENCE run: | - cargo nextest run + mise test - - name: Run cargo test (with MongoDB) + - name: MongoDB Test env: TEST_DB: MONGODB MONGODB: mongodb://localhost run: | - cargo nextest run + mise test - name: Start API in background if: github.event_name != 'pull_request' && github.ref_name == 'main' env: TEST_DB: REFERENCE run: | - cargo build --bin revolt-delta && (cargo run --bin revolt-delta &) + mise build --bin revolt-delta && (mise service:api &) - name: Wait for API to go up if: github.event_name != 'pull_request' && github.ref_name == 'main' diff --git a/.mise/config.toml b/.mise/config.toml new file mode 100644 index 000000000..1d6ad18db --- /dev/null +++ b/.mise/config.toml @@ -0,0 +1,17 @@ +[tools] +node = "25.4.0" +pnpm = "10.28.1" + +gh = "2.25.0" + +rust = "1.92.0" +"cargo:cargo-nextest" = "0.9.122" + +[settings] +experimental = true +idiomatic_version_file_enable_tools = ["rust"] + +[tasks.start] +description = "Run all services" +depends = ["docker:start", "build"] +run = [{ task = "service:*" }] diff --git a/.mise/tasks/build b/.mise/tasks/build new file mode 100755 index 000000000..c97c28d80 --- /dev/null +++ b/.mise/tasks/build @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +#MISE description="Build project" +set -e + +cargo build "$@" diff --git a/.mise/tasks/check b/.mise/tasks/check new file mode 100755 index 000000000..116f10166 --- /dev/null +++ b/.mise/tasks/check @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +#MISE description="Check project with clippy" +set -e + +cargo clippy diff --git a/.mise/tasks/docker/start b/.mise/tasks/docker/start new file mode 100755 index 000000000..cfcb0a9a5 --- /dev/null +++ b/.mise/tasks/docker/start @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +#MISE description="Start Docker containers" +set -e + +docker compose up -d diff --git a/.mise/tasks/docker/stop b/.mise/tasks/docker/stop new file mode 100755 index 000000000..51d39d613 --- /dev/null +++ b/.mise/tasks/docker/stop @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +#MISE description="Stop Docker containers" +set -e + +docker compose down diff --git a/.mise/tasks/docs/_default b/.mise/tasks/docs/_default new file mode 100755 index 000000000..742d586fd --- /dev/null +++ b/.mise/tasks/docs/_default @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +#MISE description="Start the Stoat Developers website" +#MISE depends=["docs:install"] +#MISE dir="{{config_root}}/docs" +set -e + +pnpm build diff --git a/.mise/tasks/docs/build b/.mise/tasks/docs/build new file mode 100755 index 000000000..ae3cdb65f --- /dev/null +++ b/.mise/tasks/docs/build @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +#MISE description="Build the Stoat Developers website" +#MISE depends=["docs:install"] +#MISE dir="{{config_root}}/docs" +set -e + +pnpm build diff --git a/.mise/tasks/docs/install b/.mise/tasks/docs/install new file mode 100755 index 000000000..753779c1d --- /dev/null +++ b/.mise/tasks/docs/install @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +#MISE description="Install dependencies for docs site" +#MISE dir="{{config_root}}/docs" +set -e + +pnpm i --frozen-lockfile diff --git a/.mise/tasks/publish b/.mise/tasks/publish new file mode 100755 index 000000000..27df8f9a7 --- /dev/null +++ b/.mise/tasks/publish @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +#MISE description="Publish project" +set -e + +cargo publish "$@" diff --git a/.mise/tasks/service/api b/.mise/tasks/service/api new file mode 100755 index 000000000..07915c17c --- /dev/null +++ b/.mise/tasks/service/api @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +#MISE description="Run API server" +set -e + +cargo run --bin revolt-delta diff --git a/.mise/tasks/service/crond b/.mise/tasks/service/crond new file mode 100755 index 000000000..ce4bc4918 --- /dev/null +++ b/.mise/tasks/service/crond @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +#MISE description="Run cron daemon" +set -e + +cargo run --bin revolt-crond diff --git a/.mise/tasks/service/events b/.mise/tasks/service/events new file mode 100755 index 000000000..85bea49a6 --- /dev/null +++ b/.mise/tasks/service/events @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +#MISE description="Run events server" +set -e + +cargo run --bin revolt-bonfire diff --git a/.mise/tasks/service/files b/.mise/tasks/service/files new file mode 100755 index 000000000..431c5a521 --- /dev/null +++ b/.mise/tasks/service/files @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +#MISE description="Run file server" +set -e + +cargo run --bin revolt-autumn diff --git a/.mise/tasks/service/gifbox b/.mise/tasks/service/gifbox new file mode 100755 index 000000000..bc72192be --- /dev/null +++ b/.mise/tasks/service/gifbox @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +#MISE description="Run GIF proxy server" +set -e + +cargo run --bin revolt-gifbox diff --git a/.mise/tasks/service/proxy b/.mise/tasks/service/proxy new file mode 100755 index 000000000..a16634fc4 --- /dev/null +++ b/.mise/tasks/service/proxy @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +#MISE description="Run proxy server" +set -e + +cargo run --bin revolt-january diff --git a/.mise/tasks/service/pushd b/.mise/tasks/service/pushd new file mode 100755 index 000000000..1cbb96bab --- /dev/null +++ b/.mise/tasks/service/pushd @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +#MISE description="Run push daemon" +set -e + +cargo run --bin revolt-pushd diff --git a/.mise/tasks/test b/.mise/tasks/test new file mode 100755 index 000000000..9f59fb4ca --- /dev/null +++ b/.mise/tasks/test @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +#MISE description="Test project" +set -e + +cargo nextest run diff --git a/README.md b/README.md index f5f452705..05baca7eb 100644 --- a/README.md +++ b/README.md @@ -43,13 +43,13 @@ Before contributing, make yourself familiar with [our contribution guidelines](h Before getting started, you'll want to install: -- Rust toolchain (rustup recommended) +- mise - Docker - Git - mold (optional, faster compilation) > A **default.nix** is available for Nix users! -> Just run `nix-shell` and continue. +> Run `nix-shell` to activate mise. As a heads-up, the development environment uses the following ports: @@ -72,7 +72,7 @@ Now you can clone and build the project: ```bash git clone https://github.com/revoltchat/backend revolt-backend cd revolt-backend -cargo build +mise build ``` A default configuration `Revolt.toml` is present in this project that is suited for development. diff --git a/compose.yml b/compose.yml index 4ea6d9bc9..e1e84b6fe 100644 --- a/compose.yml +++ b/compose.yml @@ -12,6 +12,10 @@ services: - "27017:27017" volumes: - ./.data/db:/data/db + ulimits: + nofile: + soft: 65536 + hard: 65536 # MinIO minio: diff --git a/crates/core/coalesced/Cargo.toml b/crates/core/coalesced/Cargo.toml index f267999bd..aac2b95be 100644 --- a/crates/core/coalesced/Cargo.toml +++ b/crates/core/coalesced/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" license = "MIT" authors = ["Paul Makles ", "Zomatree "] description = "Revolt Backend: Coalescion service" +repository = "https://github.com/stoatchat/stoatchat" [features] tokio = ["dep:tokio"] @@ -19,4 +20,9 @@ indexmap = { version = "2.13.0", optional = true } lru = { version = "0.16.3", optional = true } [dev-dependencies] -tokio = { version = "1.47.0", features = ["rt", "rt-multi-thread", "macros", "time"] } +tokio = { version = "1.47.0", features = [ + "rt", + "rt-multi-thread", + "macros", + "time", +] } diff --git a/crates/core/config/Cargo.toml b/crates/core/config/Cargo.toml index 986f78a30..e91ce5e01 100644 --- a/crates/core/config/Cargo.toml +++ b/crates/core/config/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" license = "MIT" authors = ["Paul Makles "] description = "Revolt Backend: Configuration" +repository = "https://github.com/stoatchat/stoatchat" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index 593e906a4..979d4a5d0 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] description = "Revolt Backend: Database Implementation" +repository = "https://github.com/stoatchat/stoatchat" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -15,8 +16,14 @@ mongodb = ["dep:mongodb", "bson", "authifier/database-mongodb"] # ... Other tasks = ["isahc", "linkify", "url-escape"] async-std-runtime = ["async-std", "authifier/async-std-runtime"] -rocket-impl = ["rocket", "schemars", "revolt_okapi", "revolt_rocket_okapi", "authifier/rocket_impl"] -axum-impl = ["axum"] +rocket-impl = [ + "rocket", + "schemars", + "revolt_okapi", + "revolt_rocket_okapi", + "authifier/rocket_impl", +] +axum-impl = ["axum", "revolt-result/axum"] redis-is-patched = ["revolt-presence/redis-is-patched"] voice = ["livekit-api", "livekit-protocol", "livekit-runtime"] @@ -99,6 +106,6 @@ authifier = { version = "1.0.15" } amqprs = { version = "1.7.0" } # Voice -livekit-api = { version = "0.4.4", optional = true} +livekit-api = { version = "0.4.4", optional = true } livekit-protocol = { version = "0.4.0", optional = true } livekit-runtime = { version = "0.3.1", features = ["tokio"], optional = true } diff --git a/crates/core/files/Cargo.toml b/crates/core/files/Cargo.toml index ad5f17687..f807345d1 100644 --- a/crates/core/files/Cargo.toml +++ b/crates/core/files/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] description = "Revolt Backend: S3 and encryption subroutines" +repository = "https://github.com/stoatchat/stoatchat" [dependencies] tracing = "0.1" diff --git a/crates/core/models/Cargo.toml b/crates/core/models/Cargo.toml index 77721a142..d5111c11d 100644 --- a/crates/core/models/Cargo.toml +++ b/crates/core/models/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" license = "MIT" authors = ["Paul Makles "] description = "Revolt Backend: API Models" +repository = "https://github.com/stoatchat/stoatchat" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/crates/core/parser/Cargo.toml b/crates/core/parser/Cargo.toml index 8f287a593..ba9d22558 100644 --- a/crates/core/parser/Cargo.toml +++ b/crates/core/parser/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" license = "MIT" authors = ["Zomatree ", "Paul Makles "] description = "Revolt Backend: Message Parser" +repository = "https://github.com/stoatchat/stoatchat" [dependencies] logos = { version = "0.15" } diff --git a/crates/core/permissions/Cargo.toml b/crates/core/permissions/Cargo.toml index fb0cf0e8a..86ac095d1 100644 --- a/crates/core/permissions/Cargo.toml +++ b/crates/core/permissions/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" license = "MIT" authors = ["Paul Makles "] description = "Revolt Backend: Permission Logic" +repository = "https://github.com/stoatchat/stoatchat" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/crates/core/presence/Cargo.toml b/crates/core/presence/Cargo.toml index de443e3f9..cdbcd5905 100644 --- a/crates/core/presence/Cargo.toml +++ b/crates/core/presence/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] description = "Revolt Backend: User Presence" +repository = "https://github.com/stoatchat/stoatchat" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/crates/core/ratelimits/Cargo.toml b/crates/core/ratelimits/Cargo.toml index da0aad74f..3447c48c5 100644 --- a/crates/core/ratelimits/Cargo.toml +++ b/crates/core/ratelimits/Cargo.toml @@ -2,15 +2,23 @@ name = "revolt-ratelimits" version = "0.9.4" edition = "2024" +license = "MIT" +authors = ["Zomatree ", "Paul Makles "] +description = "Revolt Backend: Ratelimit Handler" +repository = "https://github.com/stoatchat/stoatchat" [features] -rocket = ["dep:rocket", "dep:revolt_rocket_okapi", "revolt-database/rocket-impl"] +rocket = [ + "dep:rocket", + "dep:revolt_rocket_okapi", + "revolt-database/rocket-impl", +] axum = ["dep:axum", "revolt-database/axum-impl"] default = ["rocket", "axum"] [dependencies] -revolt-database = { version = "0.9.4", path = "../database"} +revolt-database = { version = "0.9.4", path = "../database" } revolt-result = { version = "0.9.4", path = "../result" } revolt-config = { version = "0.9.4", path = "../config" } diff --git a/crates/core/result/Cargo.toml b/crates/core/result/Cargo.toml index 66c6132a6..d87a7d1b2 100644 --- a/crates/core/result/Cargo.toml +++ b/crates/core/result/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" license = "MIT" authors = ["Paul Makles "] description = "Revolt Backend: Result and Error types" +repository = "https://github.com/stoatchat/stoatchat" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -38,4 +39,4 @@ log = "0.4" # Axum axum = { version = "0.7.5", optional = true } -sentry = { version = "0.31.5", optional = true } \ No newline at end of file +sentry = { version = "0.31.5", optional = true } diff --git a/crates/delta/src/routes/channels/message_unpin.rs b/crates/delta/src/routes/channels/message_unpin.rs index 3770606da..421848953 100644 --- a/crates/delta/src/routes/channels/message_unpin.rs +++ b/crates/delta/src/routes/channels/message_unpin.rs @@ -1,4 +1,7 @@ -use revolt_database::{util::{permissions::DatabasePermissionQuery, reference::Reference}, Channel, Database, FieldsMessage, PartialMessage, SystemMessage, User, AMQP}; +use revolt_database::{ + util::{permissions::DatabasePermissionQuery, reference::Reference}, + Channel, Database, FieldsMessage, PartialMessage, SystemMessage, User, AMQP, +}; use revolt_models::v0::MessageAuthor; use revolt_permissions::{calculate_channel_permissions, ChannelPermission}; use revolt_result::{create_error, Result}; diff --git a/default.nix b/default.nix index 06d2e319c..68fb5384b 100644 --- a/default.nix +++ b/default.nix @@ -1,28 +1,41 @@ -{ - pkgs ? import { }, +{ pkgs ? import (fetchTarball { + url = "https://github.com/NixOS/nixpkgs/archive/77ef7a29d276c6d8303aece3444d61118ef71ac2.tar.gz"; + sha256 = "0pm4l48jq8plzrrrisimahxqlcpx7qqq9c99hylmf7p3zlc3phsy"; + }) {}, }: -pkgs.mkShell rec { - buildInputs = [ - # Tools - pkgs.git - pkgs.just +let + nix-ld-libs = pkgs.buildEnv { + name = "nix-ld-libs"; + paths = with pkgs; [ + stdenv.cc.cc.lib + zlib + openssl.out + ]; + pathsToLink = [ "/lib" ]; + }; - # Cargo - pkgs.cargo - pkgs.cargo-nextest - pkgs.cargo-release - - # Rust - pkgs.rustc - pkgs.clippy - pkgs.rustfmt - pkgs.pkg-config - pkgs.openssl.dev +in pkgs.mkShell { + packages = with pkgs; [ + mise + cargo-binstall + (writeShellScriptBin "fish" '' + exec ${pkgs.fish}/bin/fish -C 'mise activate fish | source' "$@" + '') + ]; - # mdbook - pkgs.mdbook + buildInputs = with pkgs; [ + pkg-config + openssl.dev ]; - RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}"; -} + shellHook = '' + export TMPDIR=/tmp + export NIX_LD="${pkgs.stdenv.cc.libc}/lib/ld-linux-x86-64.so.2" + export NIX_LD_LIBRARY_PATH="${nix-ld-libs}/lib" + export LD_LIBRARY_PATH="${nix-ld-libs}/lib''${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" + + export MISE_NODE_COMPILE=false + eval "$(mise activate bash)" + ''; +} \ No newline at end of file diff --git a/scripts/start.sh b/scripts/start.sh deleted file mode 100755 index ef485d22a..000000000 --- a/scripts/start.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash -set -e -cargo build \ - --bin revolt-delta \ - --bin revolt-bonfire \ - --bin revolt-autumn \ - --bin revolt-january \ - --bin revolt-gifbox - -trap 'pkill -f revolt-' SIGINT -cargo run --bin revolt-delta & -cargo run --bin revolt-bonfire & -cargo run --bin revolt-autumn & -cargo run --bin revolt-january & -cargo run --bin revolt-gifbox From 12c187a38632dfa41e6af640a6fb8b881f22cd34 Mon Sep 17 00:00:00 2001 From: "stoat-tofu[bot]" <242700035+stoat-tofu[bot]@users.noreply.github.com> Date: Sat, 24 Jan 2026 01:11:53 +0000 Subject: [PATCH 059/211] chore: modify .github/workflows/git-town.yml --- .github/workflows/git-town.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .github/workflows/git-town.yml diff --git a/.github/workflows/git-town.yml b/.github/workflows/git-town.yml new file mode 100644 index 000000000..df7d74f61 --- /dev/null +++ b/.github/workflows/git-town.yml @@ -0,0 +1,19 @@ +name: Git Town + +on: + pull_request: + branches: + - '**' + +jobs: + git-town: + name: Display the branch stack + runs-on: ubuntu-latest + + permissions: + contents: read + pull-requests: write + + steps: + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: git-town/action@e483957e6d4827e62413707d4c8f9678c9dc19f1 # v1.3.2 From b9360b4d88810efba3b5185db728bf5ef12d1595 Mon Sep 17 00:00:00 2001 From: "stoat-tofu[bot]" <242700035+stoat-tofu[bot]@users.noreply.github.com> Date: Sat, 24 Jan 2026 01:54:01 +0000 Subject: [PATCH 060/211] chore: modify .github/workflows/git-town.yml --- .github/workflows/git-town.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/git-town.yml b/.github/workflows/git-town.yml index df7d74f61..fa99ca7ad 100644 --- a/.github/workflows/git-town.yml +++ b/.github/workflows/git-town.yml @@ -16,4 +16,4 @@ jobs: steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - - uses: git-town/action@e483957e6d4827e62413707d4c8f9678c9dc19f1 # v1.3.2 + - uses: stoatchat/action-git-town@24aa7d79612041f56486d8f34e9bc2c7a58bcb7b From 65efea020d7fa89a25ea77f949a621e365213b91 Mon Sep 17 00:00:00 2001 From: "stoat-tofu[bot]" <242700035+stoat-tofu[bot]@users.noreply.github.com> Date: Sat, 24 Jan 2026 02:01:05 +0000 Subject: [PATCH 061/211] chore: modify .github/workflows/git-town.yml --- .github/workflows/git-town.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/git-town.yml b/.github/workflows/git-town.yml index fa99ca7ad..b5ad04758 100644 --- a/.github/workflows/git-town.yml +++ b/.github/workflows/git-town.yml @@ -16,4 +16,4 @@ jobs: steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - - uses: stoatchat/action-git-town@24aa7d79612041f56486d8f34e9bc2c7a58bcb7b + - uses: stoatchat/action-git-town@4d88161562e7fd092b8ff0ea9abb784628c46d8a From 4344419cdbece1f66c8ccd63a4c4e3123c925b2d Mon Sep 17 00:00:00 2001 From: "stoat-tofu[bot]" <242700035+stoat-tofu[bot]@users.noreply.github.com> Date: Sat, 24 Jan 2026 02:10:51 +0000 Subject: [PATCH 062/211] chore: modify .github/workflows/git-town.yml --- .github/workflows/git-town.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/git-town.yml b/.github/workflows/git-town.yml index b5ad04758..40c5614d9 100644 --- a/.github/workflows/git-town.yml +++ b/.github/workflows/git-town.yml @@ -16,4 +16,4 @@ jobs: steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - - uses: stoatchat/action-git-town@4d88161562e7fd092b8ff0ea9abb784628c46d8a + - uses: stoatchat/action-git-town@082acaa53a5847c362d803996e4dda9b8ac3ab67 From 3c51fad74d14bcd0f5d52fb145efb5f3c9fc00ee Mon Sep 17 00:00:00 2001 From: "stoat-tofu[bot]" <242700035+stoat-tofu[bot]@users.noreply.github.com> Date: Sat, 24 Jan 2026 02:18:41 +0000 Subject: [PATCH 063/211] chore: modify .github/workflows/git-town.yml --- .github/workflows/git-town.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/git-town.yml b/.github/workflows/git-town.yml index 40c5614d9..a4a4042a1 100644 --- a/.github/workflows/git-town.yml +++ b/.github/workflows/git-town.yml @@ -16,4 +16,4 @@ jobs: steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - - uses: stoatchat/action-git-town@082acaa53a5847c362d803996e4dda9b8ac3ab67 + - uses: stoatchat/action-git-town@22bfb6fbeccc027b8181a3b29a9f21471ff1a6ee From 9bdb7d7feb42e85f7f7ceb96a0fddf21601b3ad9 Mon Sep 17 00:00:00 2001 From: "stoat-tofu[bot]" <242700035+stoat-tofu[bot]@users.noreply.github.com> Date: Sat, 24 Jan 2026 02:20:09 +0000 Subject: [PATCH 064/211] chore: modify .github/workflows/git-town.yml --- .github/workflows/git-town.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/git-town.yml b/.github/workflows/git-town.yml index a4a4042a1..9d77e679a 100644 --- a/.github/workflows/git-town.yml +++ b/.github/workflows/git-town.yml @@ -16,4 +16,4 @@ jobs: steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - - uses: stoatchat/action-git-town@22bfb6fbeccc027b8181a3b29a9f21471ff1a6ee + - uses: git-town/action-git-town@24aa7d79612041f56486d8f34e9bc2c7a58bcb7b # v1.3.2 From ff68679bad8b306351f356e4035c7740a786f3cd Mon Sep 17 00:00:00 2001 From: "stoat-tofu[bot]" <242700035+stoat-tofu[bot]@users.noreply.github.com> Date: Sat, 24 Jan 2026 23:35:02 +0000 Subject: [PATCH 065/211] chore: modify .github/workflows/git-town.yml --- .github/workflows/git-town.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/git-town.yml b/.github/workflows/git-town.yml index 9d77e679a..17446dd0d 100644 --- a/.github/workflows/git-town.yml +++ b/.github/workflows/git-town.yml @@ -16,4 +16,4 @@ jobs: steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - - uses: git-town/action-git-town@24aa7d79612041f56486d8f34e9bc2c7a58bcb7b # v1.3.2 + - uses: git-town/action-git-town@976a691cb87648a96528d952e77aebd48ff1cd97 From ce2a4eccbd61f781bb0b83b5e22e200028bcba07 Mon Sep 17 00:00:00 2001 From: "stoat-tofu[bot]" <242700035+stoat-tofu[bot]@users.noreply.github.com> Date: Sat, 24 Jan 2026 23:36:32 +0000 Subject: [PATCH 066/211] chore: modify .github/workflows/git-town.yml --- .github/workflows/git-town.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/git-town.yml b/.github/workflows/git-town.yml index 17446dd0d..b87ca71dd 100644 --- a/.github/workflows/git-town.yml +++ b/.github/workflows/git-town.yml @@ -16,4 +16,4 @@ jobs: steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - - uses: git-town/action-git-town@976a691cb87648a96528d952e77aebd48ff1cd97 + - uses: stoatchat/action-git-town@976a691cb87648a96528d952e77aebd48ff1cd97 From 24cfc33907686d9463fc0589122fd25581391dcf Mon Sep 17 00:00:00 2001 From: "stoat-tofu[bot]" <242700035+stoat-tofu[bot]@users.noreply.github.com> Date: Sat, 24 Jan 2026 23:44:00 +0000 Subject: [PATCH 067/211] chore: modify .github/workflows/git-town.yml --- .github/workflows/git-town.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/git-town.yml b/.github/workflows/git-town.yml index b87ca71dd..03b9d9a0d 100644 --- a/.github/workflows/git-town.yml +++ b/.github/workflows/git-town.yml @@ -8,7 +8,7 @@ on: jobs: git-town: name: Display the branch stack - runs-on: ubuntu-latest + runs-on: ubuntu-slim permissions: contents: read @@ -16,4 +16,4 @@ jobs: steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - - uses: stoatchat/action-git-town@976a691cb87648a96528d952e77aebd48ff1cd97 + - uses: stoatchat/action-git-town@4bc5c942e4603bffa0806b51d5fe5f0bc5deb0ac From 9fb55f74dc6180cab0b4d25a819ac34929815f85 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Sat, 24 Jan 2026 23:46:10 +0000 Subject: [PATCH 068/211] chore: add git-town to mise tools (#497) --- .mise/config.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.mise/config.toml b/.mise/config.toml index 1d6ad18db..85fcd8983 100644 --- a/.mise/config.toml +++ b/.mise/config.toml @@ -7,6 +7,8 @@ gh = "2.25.0" rust = "1.92.0" "cargo:cargo-nextest" = "0.9.122" +"github:git-town/git-town" = "22.4.0" + [settings] experimental = true idiomatic_version_file_enable_tools = ["rust"] From 0dc544249825a49c793309edee5ec1838458a6da Mon Sep 17 00:00:00 2001 From: Angelo Kontaxis Date: Sun, 25 Jan 2026 19:42:48 +0000 Subject: [PATCH 069/211] feat: allow kicking members from voice channels (#495) --- .../src/models/server_members/model.rs | 4 ++- .../src/models/server_members/ops/mongodb.rs | 19 ++++++------ crates/core/database/src/util/bridge/v0.rs | 2 ++ crates/core/models/src/v0/server_members.rs | 1 + .../delta/src/routes/servers/member_edit.rs | 30 +++++++++++++++---- 5 files changed, 40 insertions(+), 16 deletions(-) diff --git a/crates/core/database/src/models/server_members/model.rs b/crates/core/database/src/models/server_members/model.rs index 74ec04a8e..0062a2708 100644 --- a/crates/core/database/src/models/server_members/model.rs +++ b/crates/core/database/src/models/server_members/model.rs @@ -72,6 +72,7 @@ auto_derived!( CanReceive, CanPublish, JoinedAt, + VoiceChannel, } /// Member removal intention @@ -224,13 +225,14 @@ impl Member { pub fn remove_field(&mut self, field: &FieldsMember) { match field { - FieldsMember::JoinedAt => (), + FieldsMember::JoinedAt => {}, FieldsMember::Avatar => self.avatar = None, FieldsMember::Nickname => self.nickname = None, FieldsMember::Roles => self.roles.clear(), FieldsMember::Timeout => self.timeout = None, FieldsMember::CanReceive => self.can_receive = true, FieldsMember::CanPublish => self.can_publish = true, + FieldsMember::VoiceChannel => {}, } } diff --git a/crates/core/database/src/models/server_members/ops/mongodb.rs b/crates/core/database/src/models/server_members/ops/mongodb.rs index 198ad6a80..377e5877a 100644 --- a/crates/core/database/src/models/server_members/ops/mongodb.rs +++ b/crates/core/database/src/models/server_members/ops/mongodb.rs @@ -330,14 +330,15 @@ impl AbstractServerMembers for MongoDb { impl IntoDocumentPath for FieldsMember { fn as_path(&self) -> Option<&'static str> { - Some(match self { - FieldsMember::JoinedAt => "joined_at", - FieldsMember::Avatar => "avatar", - FieldsMember::Nickname => "nickname", - FieldsMember::Roles => "roles", - FieldsMember::Timeout => "timeout", - FieldsMember::CanPublish => "can_publish", - FieldsMember::CanReceive => "can_receive", - }) + match self { + FieldsMember::JoinedAt => Some("joined_at"), + FieldsMember::Avatar => Some("avatar"), + FieldsMember::Nickname => Some("nickname"), + FieldsMember::Roles => Some("roles"), + FieldsMember::Timeout => Some("timeout"), + FieldsMember::CanPublish => Some("can_publish"), + FieldsMember::CanReceive => Some("can_receive"), + FieldsMember::VoiceChannel => None, + } } } diff --git a/crates/core/database/src/util/bridge/v0.rs b/crates/core/database/src/util/bridge/v0.rs index de63db907..aafb23135 100644 --- a/crates/core/database/src/util/bridge/v0.rs +++ b/crates/core/database/src/util/bridge/v0.rs @@ -691,6 +691,7 @@ impl From for FieldsMember { crate::FieldsMember::CanReceive => FieldsMember::CanReceive, crate::FieldsMember::CanPublish => FieldsMember::CanPublish, crate::FieldsMember::JoinedAt => FieldsMember::JoinedAt, + crate::FieldsMember::VoiceChannel => FieldsMember::VoiceChannel, } } } @@ -705,6 +706,7 @@ impl From for crate::FieldsMember { FieldsMember::CanReceive => crate::FieldsMember::CanReceive, FieldsMember::CanPublish => crate::FieldsMember::CanPublish, FieldsMember::JoinedAt => crate::FieldsMember::JoinedAt, + FieldsMember::VoiceChannel => crate::FieldsMember::VoiceChannel, } } } diff --git a/crates/core/models/src/v0/server_members.rs b/crates/core/models/src/v0/server_members.rs index d1ccb0589..41ec99ae8 100644 --- a/crates/core/models/src/v0/server_members.rs +++ b/crates/core/models/src/v0/server_members.rs @@ -95,6 +95,7 @@ auto_derived!( CanReceive, CanPublish, JoinedAt, + VoiceChannel, } /// Member removal intention diff --git a/crates/delta/src/routes/servers/member_edit.rs b/crates/delta/src/routes/servers/member_edit.rs index 458c10bae..ecc1d919d 100644 --- a/crates/delta/src/routes/servers/member_edit.rs +++ b/crates/delta/src/routes/servers/member_edit.rs @@ -98,13 +98,21 @@ pub async fn edit( permissions.throw_if_lacking_channel_permission(ChannelPermission::DeafenMembers)?; } - let new_voice_channel = if let Some(new_channel) = &data.voice_channel { + if data.voice_channel.is_some() && data.remove.contains(&FieldsMember::VoiceChannel) { + return Err(create_error!(InvalidOperation)) + } + + if data.voice_channel.is_some() || data.remove.contains(&FieldsMember::VoiceChannel) { if !voice_client.is_enabled() { return Err(create_error!(LiveKitUnavailable)); }; - permissions.throw_if_lacking_channel_permission(ChannelPermission::MoveMembers)?; + if member.id.user != user.id { + permissions.throw_if_lacking_channel_permission(ChannelPermission::MoveMembers)?; + } + } + let new_voice_channel = if let Some(new_channel) = &data.voice_channel { // ensure the channel we are moving them to is in the server and is a voice channel let channel = Reference::from_unchecked(new_channel) @@ -116,6 +124,9 @@ pub async fn edit( Err(create_error!(UnknownChannel))? } + let channel_permissions = calculate_channel_permissions(&mut query.clone().channel(&channel)).await; + channel_permissions.throw_if_lacking_channel_permission(ChannelPermission::Connect)?; + if get_user_voice_channel_in_server(&target_user.id, &server.id) .await? .is_none() @@ -189,10 +200,8 @@ pub async fn edit( partial.avatar = Some(File::use_user_avatar(db, &avatar, &user.id, &user.id).await?); } - let remove_contains_voice = remove.contains(FieldsMember::CanPublish) || remove.contains(FieldsMember::CanReceive); - member - .update(db, partial, remove.into_iter().map(Into::into).collect()) + .update(db, partial, remove.clone().into_iter().map(Into::into).collect()) .await?; if let Some(new_voice_channel) = new_voice_channel { @@ -234,7 +243,7 @@ pub async fn edit( .private(target_user.id.clone()) .await; }; - } else if can_publish.is_some() || can_receive.is_some() || remove_contains_voice { + } else if can_publish.is_some() || can_receive.is_some() || remove.contains(FieldsMember::CanPublish) || remove.contains(FieldsMember::CanReceive) { if let Some(channel) = get_user_voice_channel_in_server(&target_user.id, &server.id).await? { let node = get_channel_node(&channel).await?.unwrap(); @@ -253,5 +262,14 @@ pub async fn edit( }; }; + if remove.contains(&FieldsMember::VoiceChannel) { + if let Some(channel) = get_user_voice_channel_in_server(&target_user.id, &server.id).await? + { + let node = get_channel_node(&channel).await?.unwrap(); + + voice_client.remove_user(&node, &user.id, &channel).await?; + }; + } + Ok(Json(member.into())) } From a1a21252d0ad58937e41f16e5fb86f96bebd2a51 Mon Sep 17 00:00:00 2001 From: Angelo Kontaxis Date: Sun, 25 Jan 2026 19:43:06 +0000 Subject: [PATCH 070/211] fix: expose ratelimit headers via cors (#496) --- Cargo.lock | 1 + crates/delta/src/main.rs | 9 +++++++++ crates/services/autumn/src/api.rs | 6 ++++++ crates/services/gifbox/Cargo.toml | 1 + crates/services/gifbox/src/routes/mod.rs | 18 +++++++++++++++++- 5 files changed, 34 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 878658d7d..f68169500 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6784,6 +6784,7 @@ dependencies = [ "serde", "serde_json", "tokio 1.47.1", + "tower-http 0.5.2", "tracing", "utoipa", "utoipa-scalar", diff --git a/crates/delta/src/main.rs b/crates/delta/src/main.rs index e7c060be7..882609cce 100644 --- a/crates/delta/src/main.rs +++ b/crates/delta/src/main.rs @@ -70,6 +70,15 @@ pub async fn web() -> Rocket { .iter() .map(|s| FromStr::from_str(s).unwrap()) .collect(), + expose_headers: [ + "X-Ratelimit-Limit", + "X-Ratelimit-Bucket", + "X-Ratelimit-Remaining", + "X-Ratelimit-Reset-After", + ] + .iter() + .map(|s| s.to_string()) + .collect(), ..Default::default() } .to_cors() diff --git a/crates/services/autumn/src/api.rs b/crates/services/autumn/src/api.rs index 5c5671467..d711e5331 100644 --- a/crates/services/autumn/src/api.rs +++ b/crates/services/autumn/src/api.rs @@ -34,6 +34,12 @@ pub async fn router() -> Router { let cors = CorsLayer::new() .allow_methods([Method::POST]) .allow_headers(AllowHeaders::mirror_request()) + .expose_headers(vec![ + "X-RateLimit-Limit".try_into().unwrap(), + "X-RateLimit-Bucket".try_into().unwrap(), + "X-RateLimit-Remaining".try_into().unwrap(), + "X-RateLimit-Reset-After".try_into().unwrap(), + ]) .allow_origin(Any); Router::new() diff --git a/crates/services/gifbox/Cargo.toml b/crates/services/gifbox/Cargo.toml index fade557cd..6588f8efb 100644 --- a/crates/services/gifbox/Cargo.toml +++ b/crates/services/gifbox/Cargo.toml @@ -36,6 +36,7 @@ revolt-ratelimits = { version = "0.9.4", path = "../../core/ratelimits", feature # Axum / web server axum = { version = "0.7.5" } axum-extra = { version = "0.9", features = ["typed-header"] } +tower-http = { version = "0.5.2", features = ["cors"] } # OpenAPI & documentation generation utoipa-scalar = { version = "0.1.0", features = ["axum"] } diff --git a/crates/services/gifbox/src/routes/mod.rs b/crates/services/gifbox/src/routes/mod.rs index efee317f6..e47e19f0e 100644 --- a/crates/services/gifbox/src/routes/mod.rs +++ b/crates/services/gifbox/src/routes/mod.rs @@ -1,5 +1,9 @@ use crate::AppState; -use axum::routing::{get, Router}; +use axum::{ + http::Method, + routing::{get, Router}, +}; +use tower_http::cors::{AllowHeaders, Any, CorsLayer}; pub mod categories; pub mod root; @@ -7,9 +11,21 @@ pub mod search; pub mod trending; pub fn router() -> Router { + let cors = CorsLayer::new() + .allow_methods([Method::GET]) + .allow_headers(AllowHeaders::mirror_request()) + .expose_headers(vec![ + "X-RateLimit-Limit".try_into().unwrap(), + "X-RateLimit-Bucket".try_into().unwrap(), + "X-RateLimit-Remaining".try_into().unwrap(), + "X-RateLimit-Reset-After".try_into().unwrap(), + ]) + .allow_origin(Any); + Router::new() .route("/", get(root::root)) .route("/categories", get(categories::categories)) .route("/search", get(search::search)) .route("/trending", get(trending::trending)) + .layer(cors) } From 01ded209c62208fc906d6aab9b08c04e860e10ef Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Sun, 25 Jan 2026 20:32:22 +0000 Subject: [PATCH 071/211] feat: repository architecture for files crate w. added tests (#498) --- .mise/tasks/test | 3 + Cargo.lock | 805 +++++++++++++----- Cargo.toml | 36 +- crates/core/config/src/lib.rs | 17 +- crates/core/files/Cargo.toml | 15 +- .../src/implementation/encryption_impl.rs | 75 ++ .../files/src/implementation/media_impl.rs | 294 +++++++ crates/core/files/src/implementation/mod.rs | 7 + .../core/files/src/implementation/s3_impl.rs | 118 +++ crates/core/files/src/lib.rs | 393 +++------ .../src/repositories/encryption_repository.rs | 6 + .../repositories/file_storage_repository.rs | 22 + .../src/repositories/media_repository.rs | 30 + crates/core/files/src/repositories/mod.rs | 7 + crates/core/files/tests/assets/anim-icos.apng | Bin 0 -> 991744 bytes crates/core/files/tests/assets/anim-icos.gif | Bin 0 -> 384187 bytes crates/core/files/tests/assets/anim-icos.jxl | Bin 0 -> 341449 bytes crates/core/files/tests/assets/anim-icos.webp | Bin 0 -> 391206 bytes crates/core/files/tests/assets/corrupted.png | Bin 0 -> 4476 bytes crates/core/files/tests/assets/dice.jxl | Bin 0 -> 46893 bytes crates/core/files/tests/assets/dice.webp | Bin 0 -> 65172 bytes crates/core/files/tests/assets/test.jpeg | Bin 0 -> 3060 bytes crates/core/files/tests/assets/test.png | Bin 0 -> 4492 bytes crates/core/files/tests/integration_test.rs | 31 + crates/core/files/tests/s3_test.rs | 42 + rust-toolchain.toml | 2 +- 26 files changed, 1438 insertions(+), 465 deletions(-) create mode 100644 crates/core/files/src/implementation/encryption_impl.rs create mode 100644 crates/core/files/src/implementation/media_impl.rs create mode 100644 crates/core/files/src/implementation/mod.rs create mode 100644 crates/core/files/src/implementation/s3_impl.rs create mode 100644 crates/core/files/src/repositories/encryption_repository.rs create mode 100644 crates/core/files/src/repositories/file_storage_repository.rs create mode 100644 crates/core/files/src/repositories/media_repository.rs create mode 100644 crates/core/files/src/repositories/mod.rs create mode 100644 crates/core/files/tests/assets/anim-icos.apng create mode 100644 crates/core/files/tests/assets/anim-icos.gif create mode 100644 crates/core/files/tests/assets/anim-icos.jxl create mode 100644 crates/core/files/tests/assets/anim-icos.webp create mode 100644 crates/core/files/tests/assets/corrupted.png create mode 100644 crates/core/files/tests/assets/dice.jxl create mode 100644 crates/core/files/tests/assets/dice.webp create mode 100644 crates/core/files/tests/assets/test.jpeg create mode 100644 crates/core/files/tests/assets/test.png create mode 100644 crates/core/files/tests/integration_test.rs create mode 100644 crates/core/files/tests/s3_test.rs diff --git a/.mise/tasks/test b/.mise/tasks/test index 9f59fb4ca..848ad35db 100755 --- a/.mise/tasks/test +++ b/.mise/tasks/test @@ -2,4 +2,7 @@ #MISE description="Test project" set -e +: "${TEST_DB:=REFERENCE}" +export TEST_DB + cargo nextest run diff --git a/Cargo.lock b/Cargo.lock index f68169500..958eb6954 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -85,6 +85,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "aligned" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee4508988c62edf04abd8d92897fca0c2995d907ce1dfeaf369dac3716a40685" +dependencies = [ + "as-slice", +] + [[package]] name = "aligned-vec" version = "0.6.4" @@ -94,6 +103,21 @@ dependencies = [ "equator", ] +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + [[package]] name = "allocator-api2" version = "0.2.21" @@ -122,7 +146,7 @@ dependencies = [ "bytes 1.10.1", "serde", "serde_bytes_ng", - "tokio 1.47.1", + "tokio 1.49.0", ] [[package]] @@ -178,6 +202,15 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +[[package]] +name = "as-slice" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "516b6b4f0e40d50dcda9365d53964ec74560ad4284da2e7fc97122cd83174516" +dependencies = [ + "stable_deref_trait", +] + [[package]] name = "async-attributes" version = "1.1.2" @@ -239,7 +272,7 @@ dependencies = [ "futures-lite 2.6.1", "once_cell", "tokio 0.2.25", - "tokio 1.47.1", + "tokio 1.49.0", ] [[package]] @@ -496,6 +529,26 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +[[package]] +name = "av-scenechange" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f321d77c20e19b92c39e7471cf986812cbb46659d2af674adc4331ef3f18394" +dependencies = [ + "aligned", + "anyhow", + "arg_enum_proc_macro", + "arrayvec", + "log", + "num-rational", + "num-traits", + "pastey", + "rayon", + "thiserror 2.0.18", + "v_frame", + "y4m", +] + [[package]] name = "av1-grain" version = "0.2.4" @@ -543,7 +596,7 @@ dependencies = [ "http 1.3.1", "ring", "time", - "tokio 1.47.1", + "tokio 1.49.0", "tracing", "url", "zeroize", @@ -746,7 +799,7 @@ checksum = "1e190749ea56f8c42bf15dd76c65e14f8f765233e6df9b0506d9d934ebef867c" dependencies = [ "futures-util", "pin-project-lite 0.2.16", - "tokio 1.47.1", + "tokio 1.49.0", ] [[package]] @@ -825,7 +878,7 @@ dependencies = [ "rustls 0.23.32", "rustls-native-certs 0.8.1", "rustls-pki-types", - "tokio 1.47.1", + "tokio 1.49.0", "tokio-rustls 0.26.3", "tower", "tracing", @@ -879,7 +932,7 @@ dependencies = [ "http-body 1.0.1", "pin-project-lite 0.2.16", "pin-utils", - "tokio 1.47.1", + "tokio 1.49.0", "tracing", ] @@ -895,7 +948,7 @@ dependencies = [ "http 0.2.12", "http 1.3.1", "pin-project-lite 0.2.16", - "tokio 1.47.1", + "tokio 1.49.0", "tracing", "zeroize", ] @@ -922,7 +975,7 @@ dependencies = [ "ryu", "serde", "time", - "tokio 1.47.1", + "tokio 1.49.0", "tokio-util", ] @@ -978,7 +1031,7 @@ dependencies = [ "serde_path_to_error", "serde_urlencoded", "sync_wrapper 1.0.2", - "tokio 1.47.1", + "tokio 1.49.0", "tower", "tower-layer", "tower-service", @@ -1056,7 +1109,7 @@ dependencies = [ "futures-util", "tempfile", "thiserror 1.0.69", - "tokio 1.47.1", + "tokio 1.49.0", "uuid", ] @@ -1214,9 +1267,12 @@ checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" [[package]] name = "bitstream-io" -version = "2.6.0" +version = "4.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6099cdc01846bc367c4e7dd630dc5966dccf36b652fae7a74e17b640411a91b2" +checksum = "60d4bd9d1db2c6bdf285e223a7fa369d5ce98ec767dec949c6ca62863ce61757" +dependencies = [ + "core2", +] [[package]] name = "bitvec" @@ -1263,6 +1319,16 @@ dependencies = [ "piper", ] +[[package]] +name = "brotli-decompressor" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + [[package]] name = "bson" version = "2.15.0" @@ -1288,9 +1354,9 @@ dependencies = [ [[package]] name = "built" -version = "0.7.7" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ed6191a7e78c36abdb16ab65341eefd73d64d303fffccdbb00d51e4205967b" +checksum = "f4ad8f11f288f48ca24471bbd51ac257aaeaaa07adae295591266b792902ae64" [[package]] name = "bumpalo" @@ -1352,7 +1418,7 @@ dependencies = [ "instant", "once_cell", "thiserror 1.0.69", - "tokio 1.47.1", + "tokio 1.49.0", ] [[package]] @@ -1412,16 +1478,6 @@ dependencies = [ "uuid", ] -[[package]] -name = "cfg-expr" -version = "0.15.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" -dependencies = [ - "smallvec", - "target-lexicon", -] - [[package]] name = "cfg-if" version = "1.0.3" @@ -1508,7 +1564,7 @@ dependencies = [ "futures-core", "memchr", "pin-project-lite 0.2.16", - "tokio 1.47.1", + "tokio 1.49.0", "tokio-util", ] @@ -1630,6 +1686,15 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "core2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" +dependencies = [ + "memchr", +] + [[package]] name = "core_maths" version = "0.1.1" @@ -2016,7 +2081,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72ff1266be84e4e04a81e2d1cbb998cb271b374fb73ce780245ef96c037c50cd" dependencies = [ "crossbeam-queue", - "tokio 1.47.1", + "tokio 1.49.0", ] [[package]] @@ -2473,9 +2538,9 @@ dependencies = [ [[package]] name = "exr" -version = "1.73.0" +version = "1.74.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83197f59927b46c04a183a619b7c29df34e63e63c7869320862268c0ef687e0" +checksum = "4300e043a56aa2cb633c01af81ca8f699a321879a7854d3896a0ba89056363be" dependencies = [ "bit_field", "half", @@ -2714,7 +2779,7 @@ dependencies = [ "redis-protocol", "semver", "socket2 0.5.10", - "tokio 1.47.1", + "tokio 1.49.0", "tokio-stream", "tokio-util", "url", @@ -2833,7 +2898,7 @@ checksum = "45ec6fe3675af967e67c5536c0b9d44e34e6c52f86bedc4ea49c5317b8e94d06" dependencies = [ "futures-channel", "futures-task", - "tokio 1.47.1", + "tokio 1.49.0", ] [[package]] @@ -3007,6 +3072,16 @@ dependencies = [ "weezl", ] +[[package]] +name = "gif" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5df2ba84018d80c213569363bdcd0c64e6933c67fe4c1d60ecf822971a3c35e" +dependencies = [ + "color_quant", + "weezl", +] + [[package]] name = "gimli" version = "0.31.1" @@ -3080,7 +3155,7 @@ dependencies = [ "http 0.2.12", "indexmap 2.13.0", "slab", - "tokio 1.47.1", + "tokio 1.49.0", "tokio-util", "tracing", ] @@ -3099,7 +3174,7 @@ dependencies = [ "http 1.3.1", "indexmap 2.13.0", "slab", - "tokio 1.47.1", + "tokio 1.49.0", "tokio-util", "tracing", ] @@ -3251,7 +3326,7 @@ dependencies = [ "rand 0.8.5", "thiserror 1.0.69", "tinyvec", - "tokio 1.47.1", + "tokio 1.49.0", "tracing", "url", ] @@ -3273,7 +3348,7 @@ dependencies = [ "resolv-conf", "smallvec", "thiserror 1.0.69", - "tokio 1.47.1", + "tokio 1.49.0", "tracing", ] @@ -3439,7 +3514,7 @@ dependencies = [ "itoa", "pin-project-lite 0.2.16", "socket2 0.5.10", - "tokio 1.47.1", + "tokio 1.49.0", "tower-service", "tracing", "want", @@ -3464,7 +3539,7 @@ dependencies = [ "pin-project-lite 0.2.16", "pin-utils", "smallvec", - "tokio 1.47.1", + "tokio 1.49.0", "want", ] @@ -3480,7 +3555,7 @@ dependencies = [ "log", "rustls 0.21.12", "rustls-native-certs 0.6.3", - "tokio 1.47.1", + "tokio 1.49.0", "tokio-rustls 0.24.1", ] @@ -3496,7 +3571,7 @@ dependencies = [ "hyper-util", "rustls 0.22.4", "rustls-pki-types", - "tokio 1.47.1", + "tokio 1.49.0", "tokio-rustls 0.25.0", "tower-service", "webpki-roots 0.26.11", @@ -3514,7 +3589,7 @@ dependencies = [ "rustls 0.23.32", "rustls-native-certs 0.8.1", "rustls-pki-types", - "tokio 1.47.1", + "tokio 1.49.0", "tokio-rustls 0.26.3", "tower-service", ] @@ -3528,7 +3603,7 @@ dependencies = [ "bytes 1.10.1", "hyper 0.14.32", "native-tls", - "tokio 1.47.1", + "tokio 1.49.0", "tokio-native-tls", ] @@ -3543,7 +3618,7 @@ dependencies = [ "hyper 1.7.0", "hyper-util", "native-tls", - "tokio 1.47.1", + "tokio 1.49.0", "tokio-native-tls", "tower-service", ] @@ -3568,7 +3643,7 @@ dependencies = [ "pin-project-lite 0.2.16", "socket2 0.6.0", "system-configuration 0.6.1", - "tokio 1.47.1", + "tokio 1.49.0", "tower-service", "tracing", "windows-registry", @@ -3750,15 +3825,15 @@ checksum = "cd62e6b5e86ea8eeeb8db1de02880a6abc01a397b2ebb64b5d74ac255318f5cb" [[package]] name = "image" -version = "0.25.8" +version = "0.25.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "529feb3e6769d234375c4cf1ee2ce713682b8e76538cb13f9fc23e1400a591e7" +checksum = "e6506c6c10786659413faa717ceebcb8f70731c0a60cbae39795fdf114519c1a" dependencies = [ "bytemuck", "byteorder-lite", "color_quant", "exr", - "gif", + "gif 0.14.1", "image-webp 0.2.4", "moxcms", "num-traits", @@ -3768,8 +3843,8 @@ dependencies = [ "rayon", "rgb", "tiff", - "zune-core", - "zune-jpeg", + "zune-core 0.5.1", + "zune-jpeg 0.5.11", ] [[package]] @@ -3877,17 +3952,6 @@ dependencies = [ "syn 2.0.106", ] -[[package]] -name = "io-uring" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" -dependencies = [ - "bitflags 2.9.4", - "cfg-if", - "libc", -] - [[package]] name = "ipconfig" version = "0.3.2" @@ -3995,6 +4059,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.15" @@ -4080,13 +4153,32 @@ dependencies = [ "tracing", ] +[[package]] +name = "jxl-bitstream" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b480e752277e29eb4054f69546887a9b84656fe78c08f54ba5850ced98a378fe" +dependencies = [ + "tracing", +] + [[package]] name = "jxl-coding" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da5b5093904e940bc11ef50e872c7bdf7b6e88653f012b925f8479daf212b5c9" dependencies = [ - "jxl-bitstream", + "jxl-bitstream 0.4.1", + "tracing", +] + +[[package]] +name = "jxl-coding" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd972bcd125e776f1eb241ac50e39f956095a1c2770c64736c968f8946bd9a3c" +dependencies = [ + "jxl-bitstream 1.1.0", "tracing", ] @@ -4096,10 +4188,25 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cb1c31e10054079df585633fc14fb9e4c96565c58c05b983c502e2472b57fa0" dependencies = [ - "jxl-bitstream", - "jxl-coding", - "jxl-grid", - "jxl-threadpool", + "jxl-bitstream 0.4.1", + "jxl-coding 0.4.1", + "jxl-grid 0.4.2", + "jxl-threadpool 0.1.2", + "tracing", +] + +[[package]] +name = "jxl-color" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f316b1358c1711755b3ee8e8cb5c4a1dad12e796233088a7a513440782de80b2" +dependencies = [ + "jxl-bitstream 1.1.0", + "jxl-coding 1.0.1", + "jxl-grid 0.6.1", + "jxl-image 0.13.0", + "jxl-oxide-common", + "jxl-threadpool 1.0.0", "tracing", ] @@ -4109,13 +4216,30 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e35b289aa0f24044167d83a1c29ae2b99210c5082ab7e3e90dacbcae818aa0a2" dependencies = [ - "jxl-bitstream", - "jxl-coding", - "jxl-grid", - "jxl-image", - "jxl-modular", - "jxl-threadpool", - "jxl-vardct", + "jxl-bitstream 0.4.1", + "jxl-coding 0.4.1", + "jxl-grid 0.4.2", + "jxl-image 0.9.0", + "jxl-modular 0.7.1", + "jxl-threadpool 0.1.2", + "jxl-vardct 0.7.0", + "tracing", +] + +[[package]] +name = "jxl-frame" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d967c6fd669c7c01060b5022d8835fa82fd46b06ffc98b549f17600a097c2b3" +dependencies = [ + "jxl-bitstream 1.1.0", + "jxl-coding 1.0.1", + "jxl-grid 0.6.1", + "jxl-image 0.13.0", + "jxl-modular 0.11.2", + "jxl-oxide-common", + "jxl-threadpool 1.0.0", + "jxl-vardct 0.11.1", "tracing", ] @@ -4128,15 +4252,54 @@ dependencies = [ "tracing", ] +[[package]] +name = "jxl-grid" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0e0ef92d5d60e76bf41098e57e985f523185e08fad54268da448637feca6989" +dependencies = [ + "tracing", +] + [[package]] name = "jxl-image" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b31b17ed3bd0e3b65e7b06628f5930e009dda6cd17638cf5159a20a3feedec6" dependencies = [ - "jxl-bitstream", - "jxl-color", - "jxl-grid", + "jxl-bitstream 0.4.1", + "jxl-color 0.7.1", + "jxl-grid 0.4.2", + "tracing", +] + +[[package]] +name = "jxl-image" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f752d62577c702a94dbbce4045caf08cb58639e8a4d56464b40ecf33ffe565" +dependencies = [ + "jxl-bitstream 1.1.0", + "jxl-grid 0.6.1", + "jxl-oxide-common", + "tracing", +] + +[[package]] +name = "jxl-jbr" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e35d032bcec660647828527ff42c6f5776d2fd44b8357f9f6d9ac6dc07218e46" +dependencies = [ + "brotli-decompressor", + "jxl-bitstream 1.1.0", + "jxl-frame 0.13.3", + "jxl-grid 0.6.1", + "jxl-image 0.13.0", + "jxl-modular 0.11.2", + "jxl-oxide-common", + "jxl-threadpool 1.0.0", + "jxl-vardct 0.11.1", "tracing", ] @@ -4146,10 +4309,24 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da3b9fb8f46e63a14ecedefbd0f873b04162aaf8a09676b630c31bc8dadc4638" dependencies = [ - "jxl-bitstream", - "jxl-coding", - "jxl-grid", - "jxl-threadpool", + "jxl-bitstream 0.4.1", + "jxl-coding 0.4.1", + "jxl-grid 0.4.2", + "jxl-threadpool 0.1.2", + "tracing", +] + +[[package]] +name = "jxl-modular" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da758b2f989aafd9eeb39489fe43d7be5a3a0d2ad61cf1bad705eb6990a6053c" +dependencies = [ + "jxl-bitstream 1.1.0", + "jxl-coding 1.0.1", + "jxl-grid 0.6.1", + "jxl-oxide-common", + "jxl-threadpool 1.0.0", "tracing", ] @@ -4159,31 +4336,81 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ba1ee3895e6c62b131994807b1ee6d179013613a86c01c203369af8d1e8d2f0" dependencies = [ - "jxl-bitstream", - "jxl-color", - "jxl-frame", - "jxl-grid", - "jxl-image", - "jxl-render", - "jxl-threadpool", + "jxl-bitstream 0.4.1", + "jxl-color 0.7.1", + "jxl-frame 0.9.0", + "jxl-grid 0.4.2", + "jxl-image 0.9.0", + "jxl-render 0.8.2", + "jxl-threadpool 0.1.2", + "tracing", +] + +[[package]] +name = "jxl-oxide" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee8ecd2678ed70c1eda42b811ccb2e25ab836edeb18e7f1178c1f917ed36b772" +dependencies = [ + "brotli-decompressor", + "bytemuck", + "image", + "jxl-bitstream 1.1.0", + "jxl-color 0.11.0", + "jxl-frame 0.13.3", + "jxl-grid 0.6.1", + "jxl-image 0.13.0", + "jxl-jbr", + "jxl-oxide-common", + "jxl-render 0.12.3", + "jxl-threadpool 1.0.0", "tracing", ] +[[package]] +name = "jxl-oxide-common" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62394c5021b3a9e7e0dbb2d639d555d019090c9946c39f6d3b09d390db4157b" +dependencies = [ + "jxl-bitstream 1.1.0", +] + [[package]] name = "jxl-render" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "203a79b3025b86f875cc97a6f39e1fcc6314f915b2f6b69f767fca45fd482a11" dependencies = [ - "jxl-bitstream", - "jxl-coding", - "jxl-color", - "jxl-frame", - "jxl-grid", - "jxl-image", - "jxl-modular", - "jxl-threadpool", - "jxl-vardct", + "jxl-bitstream 0.4.1", + "jxl-coding 0.4.1", + "jxl-color 0.7.1", + "jxl-frame 0.9.0", + "jxl-grid 0.4.2", + "jxl-image 0.9.0", + "jxl-modular 0.7.1", + "jxl-threadpool 0.1.2", + "jxl-vardct 0.7.0", + "tracing", +] + +[[package]] +name = "jxl-render" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa0c3100918bd3c41bb0f8ce1f4f1664e48f3032ff8eeab0d6a2cfc3276f462d" +dependencies = [ + "bytemuck", + "jxl-bitstream 1.1.0", + "jxl-coding 1.0.1", + "jxl-color 0.11.0", + "jxl-frame 0.13.3", + "jxl-grid 0.6.1", + "jxl-image 0.13.0", + "jxl-modular 0.11.2", + "jxl-oxide-common", + "jxl-threadpool 1.0.0", + "jxl-vardct 0.11.1", "tracing", ] @@ -4198,17 +4425,43 @@ dependencies = [ "tracing", ] +[[package]] +name = "jxl-threadpool" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25f15eb830aa77a7f21148d72e153562a26bfe570139bd4922eab1908dd499d3" +dependencies = [ + "rayon", + "rayon-core", + "tracing", +] + [[package]] name = "jxl-vardct" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16af82a1ad770887cad720bfd3cc6a6d023faf377036989a24cf2c6538b649e0" dependencies = [ - "jxl-bitstream", - "jxl-coding", - "jxl-grid", - "jxl-modular", - "jxl-threadpool", + "jxl-bitstream 0.4.1", + "jxl-coding 0.4.1", + "jxl-grid 0.4.2", + "jxl-modular 0.7.1", + "jxl-threadpool 0.1.2", + "tracing", +] + +[[package]] +name = "jxl-vardct" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce72a18c6d3a47172ab6c479be2bdb56f22066b5d7092663f03b4490820b4511" +dependencies = [ + "jxl-bitstream 1.1.0", + "jxl-coding 1.0.1", + "jxl-grid 0.6.1", + "jxl-modular 0.11.2", + "jxl-oxide-common", + "jxl-threadpool 1.0.0", "tracing", ] @@ -4290,7 +4543,7 @@ dependencies = [ "once_cell", "quoted_printable", "socket2 0.4.10", - "tokio 1.47.1", + "tokio 1.49.0", ] [[package]] @@ -4418,7 +4671,7 @@ dependencies = [ "log", "parking_lot", "pbjson-types", - "prost", + "prost 0.12.6", "rand 0.9.2", "reqwest 0.11.27", "scopeguard", @@ -4440,11 +4693,11 @@ dependencies = [ "parking_lot", "pbjson", "pbjson-types", - "prost", + "prost 0.12.6", "prost-types", "serde", "thiserror 1.0.69", - "tokio 1.47.1", + "tokio 1.49.0", ] [[package]] @@ -4453,7 +4706,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ae53eb874eb86e96e8ccffc31b5a00926d46174cbcb1c24ce4e57b1fcc5c8f6" dependencies = [ - "tokio 1.47.1", + "tokio 1.49.0", "tokio-stream", ] @@ -4463,7 +4716,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "532e84c6cdc5fe774f2b5d9912597b5f3bea561927a48296d03e24549d21c3f6" dependencies = [ - "tokio 1.47.1", + "tokio 1.49.0", "tokio-stream", ] @@ -4796,7 +5049,7 @@ dependencies = [ "log", "metrics", "thiserror 1.0.69", - "tokio 1.47.1", + "tokio 1.49.0", "tracing", "tracing-subscriber", ] @@ -4893,7 +5146,7 @@ dependencies = [ "strsim 0.11.1", "take_mut", "thiserror 1.0.69", - "tokio 1.47.1", + "tokio 1.49.0", "tokio-rustls 0.26.3", "tokio-util", "typed-builder", @@ -4937,7 +5190,7 @@ dependencies = [ "memchr", "mime", "spin", - "tokio 1.47.1", + "tokio 1.49.0", "tokio-util", "version_check", ] @@ -5231,6 +5484,90 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "opentelemetry" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b84bcd6ae87133e903af7ef497404dda70c60d0ea14895fc8a5e6722754fc2a0" +dependencies = [ + "futures-core", + "futures-sink", + "js-sys", + "pin-project-lite 0.2.16", + "thiserror 2.0.18", + "tracing", +] + +[[package]] +name = "opentelemetry-appender-tracing" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef6a1ac5ca3accf562b8c306fa8483c85f4390f768185ab775f242f7fe8fdcc2" +dependencies = [ + "opentelemetry", + "tracing", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "opentelemetry-http" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7a6d09a73194e6b66df7c8f1b680f156d916a1a942abf2de06823dd02b7855d" +dependencies = [ + "async-trait", + "bytes 1.10.1", + "http 1.3.1", + "opentelemetry", + "reqwest 0.12.23", +] + +[[package]] +name = "opentelemetry-otlp" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2366db2dca4d2ad033cad11e6ee42844fd727007af5ad04a1730f4cb8163bf" +dependencies = [ + "http 1.3.1", + "opentelemetry", + "opentelemetry-http", + "opentelemetry-proto", + "opentelemetry_sdk", + "prost 0.14.3", + "reqwest 0.12.23", + "thiserror 2.0.18", + "tracing", +] + +[[package]] +name = "opentelemetry-proto" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7175df06de5eaee9909d4805a3d07e28bb752c34cab57fa9cff549da596b30f" +dependencies = [ + "opentelemetry", + "opentelemetry_sdk", + "prost 0.14.3", + "tonic", + "tonic-prost", +] + +[[package]] +name = "opentelemetry_sdk" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ae4f5991976fd48df6d843de219ca6d31b01daaab2dad5af2badeded372bd" +dependencies = [ + "futures-channel", + "futures-executor", + "futures-util", + "opentelemetry", + "percent-encoding", + "rand 0.9.2", + "thiserror 2.0.18", +] + [[package]] name = "ordered-multimap" version = "0.4.3" @@ -5329,6 +5666,12 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +[[package]] +name = "pastey" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35fb2e5f958ec131621fdd531e9fc186ed768cbe395337403ae56c17a74c68ec" + [[package]] name = "pathdiff" version = "0.2.3" @@ -5353,7 +5696,7 @@ checksum = "2580e33f2292d34be285c5bc3dba5259542b083cfad6037b6d70345f24dcb735" dependencies = [ "heck 0.4.1", "itertools 0.11.0", - "prost", + "prost 0.12.6", "prost-types", ] @@ -5367,7 +5710,7 @@ dependencies = [ "chrono", "pbjson", "pbjson-build", - "prost", + "prost 0.12.6", "prost-build", "serde", ] @@ -5456,7 +5799,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21e0a3a33733faeaf8651dfee72dd0f388f0c8e5ad496a3478fa5a922f49cfa8" dependencies = [ "memchr", - "thiserror 2.0.16", + "thiserror 2.0.18", "ucd-trie", ] @@ -5950,7 +6293,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" dependencies = [ "bytes 1.10.1", - "prost-derive", + "prost-derive 0.12.6", +] + +[[package]] +name = "prost" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568" +dependencies = [ + "bytes 1.10.1", + "prost-derive 0.14.3", ] [[package]] @@ -5967,7 +6320,7 @@ dependencies = [ "once_cell", "petgraph", "prettyplease", - "prost", + "prost 0.12.6", "prost-types", "regex", "syn 2.0.106", @@ -5987,13 +6340,26 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "prost-derive" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" +dependencies = [ + "anyhow", + "itertools 0.14.0", + "proc-macro2", + "quote 1.0.40", + "syn 2.0.106", +] + [[package]] name = "prost-types" version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0" dependencies = [ - "prost", + "prost 0.12.6", ] [[package]] @@ -6242,19 +6608,21 @@ dependencies = [ [[package]] name = "rav1e" -version = "0.7.1" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9" +checksum = "43b6dd56e85d9483277cde964fd1bdb0428de4fec5ebba7540995639a21cb32b" dependencies = [ + "aligned-vec", "arbitrary", "arg_enum_proc_macro", "arrayvec", + "av-scenechange", "av1-grain", "bitstream-io", "built", "cfg-if", "interpolate_name", - "itertools 0.12.1", + "itertools 0.14.0", "libc", "libfuzzer-sys", "log", @@ -6263,23 +6631,21 @@ dependencies = [ "noop_proc_macro", "num-derive", "num-traits", - "once_cell", "paste", "profiling", - "rand 0.8.5", - "rand_chacha 0.3.1", + "rand 0.9.2", + "rand_chacha 0.9.0", "simd_helpers", - "system-deps", - "thiserror 1.0.69", + "thiserror 2.0.18", "v_frame", "wasm-bindgen", ] [[package]] name = "ravif" -version = "0.11.20" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5825c26fddd16ab9f515930d49028a630efec172e903483c94796cfe31893e6b" +checksum = "ef69c1990ceef18a116855938e74793a5f7496ee907562bd0857b6ac734ab285" dependencies = [ "avif-serialize", "imgref", @@ -6335,7 +6701,7 @@ dependencies = [ "ryu", "sha1_smol", "socket2 0.4.10", - "tokio 1.47.1", + "tokio 1.49.0", "tokio-util", "url", ] @@ -6464,7 +6830,7 @@ dependencies = [ "serde_urlencoded", "sync_wrapper 0.1.2", "system-configuration 0.5.1", - "tokio 1.47.1", + "tokio 1.49.0", "tokio-native-tls", "tower-service", "url", @@ -6483,7 +6849,9 @@ dependencies = [ "base64 0.22.1", "bytes 1.10.1", "encoding_rs", + "futures-channel", "futures-core", + "futures-util", "h2 0.4.12", "http 1.3.1", "http-body 1.0.1", @@ -6503,7 +6871,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "sync_wrapper 1.0.2", - "tokio 1.47.1", + "tokio 1.49.0", "tokio-native-tls", "tower", "tower-http 0.6.6", @@ -6526,7 +6894,7 @@ version = "0.44.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a325d5e8d1cebddd070b13f44cec8071594ab67d1012797c121f27a669b7958" dependencies = [ - "gif", + "gif 0.13.3", "image-webp 0.1.3", "log", "pico-args", @@ -6534,7 +6902,7 @@ dependencies = [ "svgtypes", "tiny-skia", "usvg", - "zune-jpeg", + "zune-jpeg 0.4.21", ] [[package]] @@ -6548,11 +6916,15 @@ dependencies = [ "image", "imagesize", "infer", - "jxl-oxide", + "jxl-oxide 0.8.1", "kamadak-exif", "lazy_static", "moka", "nanoid", + "opentelemetry", + "opentelemetry-appender-tracing", + "opentelemetry-otlp", + "opentelemetry_sdk", "revolt-config", "revolt-database", "revolt-files", @@ -6565,7 +6937,7 @@ dependencies = [ "simdutf8", "strum_macros", "tempfile", - "tokio 1.47.1", + "tokio 1.49.0", "tower-http 0.5.2", "tracing", "tracing-subscriber", @@ -6612,7 +6984,7 @@ version = "0.9.4" dependencies = [ "indexmap 2.13.0", "lru 0.16.3", - "tokio 1.47.1", + "tokio 1.49.0", ] [[package]] @@ -6641,7 +7013,7 @@ dependencies = [ "revolt-database", "revolt-files", "revolt-result", - "tokio 1.47.1", + "tokio 1.49.0", ] [[package]] @@ -6749,21 +7121,26 @@ name = "revolt-files" version = "0.9.4" dependencies = [ "aes-gcm", + "anyhow", + "async-trait", "aws-config", "aws-sdk-s3", "base64 0.22.1", "ffprobe", "image", "imagesize", - "jxl-oxide", + "jxl-oxide 0.12.5", "resvg", "revolt-config", "revolt-result", "tempfile", + "thiserror 2.0.18", "tiny-skia", + "tokio 1.49.0", "tracing", "typenum", "usvg", + "uuid", "webp", ] @@ -6783,7 +7160,7 @@ dependencies = [ "revolt-result", "serde", "serde_json", - "tokio 1.47.1", + "tokio 1.49.0", "tower-http 0.5.2", "tracing", "utoipa", @@ -6811,7 +7188,7 @@ dependencies = [ "serde", "serde_json", "tempfile", - "tokio 1.47.1", + "tokio 1.49.0", "tracing", "tracing-subscriber", "utoipa", @@ -6894,7 +7271,7 @@ dependencies = [ "revolt_optional_struct", "serde", "serde_json", - "tokio 1.47.1", + "tokio 1.49.0", "ulid 1.2.1", "web-push", ] @@ -6981,7 +7358,7 @@ dependencies = [ "serde", "serde_json", "thiserror 1.0.69", - "tokio 1.47.1", + "tokio 1.49.0", ] [[package]] @@ -7137,7 +7514,7 @@ dependencies = [ "state", "tempfile", "time", - "tokio 1.47.1", + "tokio 1.49.0", "tokio-stream", "tokio-util", "ubyte", @@ -7228,7 +7605,7 @@ dependencies = [ "stable-pattern", "state", "time", - "tokio 1.47.1", + "tokio 1.49.0", "uncased", ] @@ -7719,7 +8096,7 @@ dependencies = [ "sentry-debug-images", "sentry-panic", "sentry-tracing", - "tokio 1.47.1", + "tokio 1.49.0", "ureq", ] @@ -7856,7 +8233,7 @@ dependencies = [ "rand 0.9.2", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.18", "time", "url", "uuid", @@ -8468,19 +8845,6 @@ dependencies = [ "libc", ] -[[package]] -name = "system-deps" -version = "6.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" -dependencies = [ - "cfg-expr", - "heck 0.5.0", - "pkg-config", - "toml 0.8.23", - "version-compare", -] - [[package]] name = "tagptr" version = "0.2.0" @@ -8499,12 +8863,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" -[[package]] -name = "target-lexicon" -version = "0.12.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" - [[package]] name = "tempfile" version = "3.22.0" @@ -8549,11 +8907,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.16" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl 2.0.16", + "thiserror-impl 2.0.18", ] [[package]] @@ -8569,9 +8927,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.16" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote 1.0.40", @@ -8598,7 +8956,7 @@ dependencies = [ "half", "quick-error 2.0.1", "weezl", - "zune-jpeg", + "zune-jpeg 0.4.21", ] [[package]] @@ -8707,29 +9065,26 @@ dependencies = [ [[package]] name = "tokio" -version = "1.47.1" +version = "1.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" +checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" dependencies = [ - "backtrace", "bytes 1.10.1", - "io-uring", "libc", "mio", "parking_lot", "pin-project-lite 0.2.16", "signal-hook-registry", - "slab", "socket2 0.6.0", "tokio-macros", - "windows-sys 0.59.0", + "windows-sys 0.61.0", ] [[package]] name = "tokio-macros" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote 1.0.40", @@ -8743,7 +9098,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ "native-tls", - "tokio 1.47.1", + "tokio 1.49.0", ] [[package]] @@ -8753,7 +9108,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ "rustls 0.21.12", - "tokio 1.47.1", + "tokio 1.49.0", ] [[package]] @@ -8764,7 +9119,7 @@ checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" dependencies = [ "rustls 0.22.4", "rustls-pki-types", - "tokio 1.47.1", + "tokio 1.49.0", ] [[package]] @@ -8774,7 +9129,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05f63835928ca123f1bef57abbcd23bb2ba0ac9ae1235f1e65bda0d06e7786bd" dependencies = [ "rustls 0.23.32", - "tokio 1.47.1", + "tokio 1.49.0", ] [[package]] @@ -8785,7 +9140,7 @@ checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" dependencies = [ "futures-core", "pin-project-lite 0.2.16", - "tokio 1.47.1", + "tokio 1.49.0", ] [[package]] @@ -8799,7 +9154,7 @@ dependencies = [ "futures-io", "futures-sink", "pin-project-lite 0.2.16", - "tokio 1.47.1", + "tokio 1.49.0", ] [[package]] @@ -8863,6 +9218,38 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" +[[package]] +name = "tonic" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb7613188ce9f7df5bfe185db26c5814347d110db17920415cf2fbcad85e7203" +dependencies = [ + "async-trait", + "base64 0.22.1", + "bytes 1.10.1", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "percent-encoding", + "pin-project", + "sync_wrapper 1.0.2", + "tokio-stream", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tonic-prost" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66bd50ad6ce1252d87ef024b3d64fe4c3cf54a86fb9ef4c631fdd0ded7aeaa67" +dependencies = [ + "bytes 1.10.1", + "prost 0.14.3", + "tonic", +] + [[package]] name = "totp-lite" version = "2.0.1" @@ -8885,7 +9272,7 @@ dependencies = [ "futures-util", "pin-project-lite 0.2.16", "sync_wrapper 1.0.2", - "tokio 1.47.1", + "tokio 1.49.0", "tower-layer", "tower-service", "tracing", @@ -8905,6 +9292,7 @@ dependencies = [ "pin-project-lite 0.2.16", "tower-layer", "tower-service", + "tracing", ] [[package]] @@ -8939,9 +9327,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.41" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "log", "pin-project-lite 0.2.16", @@ -8951,9 +9339,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote 1.0.40", @@ -8962,9 +9350,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.34" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", "valuable", @@ -8993,9 +9381,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.20" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" +checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" dependencies = [ "matchers", "nu-ansi-term", @@ -9361,13 +9749,13 @@ dependencies = [ [[package]] name = "uuid" -version = "1.18.1" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" +checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" dependencies = [ "getrandom 0.3.3", "js-sys", - "serde", + "serde_core", "wasm-bindgen", ] @@ -9475,12 +9863,6 @@ dependencies = [ "time", ] -[[package]] -name = "version-compare" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" - [[package]] name = "version_check" version = "0.9.5" @@ -10177,6 +10559,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9" +[[package]] +name = "y4m" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5a4b21e1a62b67a2970e6831bc091d7b87e119e7f9791aef9702e3bef04448" + [[package]] name = "yaml-rust" version = "0.4.5" @@ -10241,7 +10629,7 @@ dependencies = [ "serde", "serde_json", "time", - "tokio 1.47.1", + "tokio 1.49.0", "tower-service", "url", ] @@ -10332,6 +10720,12 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" +[[package]] +name = "zune-core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb8a0807f7c01457d0379ba880ba6322660448ddebc890ce29bb64da71fb40f9" + [[package]] name = "zune-inflate" version = "0.2.54" @@ -10347,5 +10741,14 @@ version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29ce2c8a9384ad323cf564b67da86e21d3cfdff87908bc1223ed5c99bc792713" dependencies = [ - "zune-core", + "zune-core 0.4.12", +] + +[[package]] +name = "zune-jpeg" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2959ca473aae96a14ecedf501d20b3608d2825ba280d5adb57d651721885b0c2" +dependencies = [ + "zune-core 0.5.1", ] diff --git a/Cargo.toml b/Cargo.toml index 5c320e633..10989fb15 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,9 +14,37 @@ redis23 = { package = "redis", version = "0.23.3", git = "https://github.com/rev #authifier = { package = "authifier", version = "1.0.10", path = "../authifier/crates/authifier" } #rocket_authifier = { package = "rocket_authifier", version = "1.0.10", path = "../authifier/crates/rocket_authifier" } -# I'm 99% sure this is overloading the GitHub worker -# hence builds have been failing since, let's just -# disable it for now. In the future, we could use this -# if we were rolling our own CI (that is now). [profile.release] lto = true + +[workspace.dependencies] +# Async +async-trait = "0.1.89" +tokio = { version = "1.49.0", features = ["macros", "rt"] } + +# Error Handling +anyhow = "1.0.100" +thiserror = "2.0.18" + +# Other Utilities +uuid = { version = "1.19.0", features = ["v4"] } + +# Axum (HTTP server) +axum-macros = "0.4.1" +axum_typed_multipart = "0.12.1" +axum = { version = "0.7.5", features = ["multipart"] } +tower-http = { version = "0.5.2", features = ["cors", "trace"] } + +# Image Processing +jxl-oxide = { version = "0.12.5", features = ["image"] } +image = "0.25.9" + +# OpenTelemetry +tracing = "0.1.44" +tracing-subscriber = { version = "0.3.22", features = [ + "env-filter", +] } # consider https://crates.io/crates/better-tracing +opentelemetry = { version = "0.31.0", features = ["logs"] } +opentelemetry_sdk = { version = "0.31.0", features = ["logs"] } +opentelemetry-otlp = { version = "0.31.0", features = ["logs"] } +opentelemetry-appender-tracing = { version = "0.31.1" } diff --git a/crates/core/config/src/lib.rs b/crates/core/config/src/lib.rs index 46b087765..35c93b5a8 100644 --- a/crates/core/config/src/lib.rs +++ b/crates/core/config/src/lib.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::{collections::HashMap, path::Path}; use cached::proc_macro::cached; use config::{Config, File, FileFormat}; @@ -94,10 +94,19 @@ static CONFIG_BUILDER: Lazy> = Lazy::new(|| { } } - for path in CONFIG_SEARCH_PATHS { - if std::path::Path::new(path).exists() { - builder = builder.add_source(File::new(path, FileFormat::Toml)); + let cwd = std::env::current_dir().unwrap(); + let mut cwd: Option<&Path> = Some(&cwd); + + while let Some(path) = cwd { + for config_path in CONFIG_SEARCH_PATHS { + let config_path = path.join(config_path); + if config_path.exists() { + builder = builder + .add_source(File::new(config_path.to_str().unwrap(), FileFormat::Toml)); + } } + + cwd = path.parent(); } builder.build().unwrap() diff --git a/crates/core/files/Cargo.toml b/crates/core/files/Cargo.toml index f807345d1..f34469e8f 100644 --- a/crates/core/files/Cargo.toml +++ b/crates/core/files/Cargo.toml @@ -8,7 +8,13 @@ description = "Revolt Backend: S3 and encryption subroutines" repository = "https://github.com/stoatchat/stoatchat" [dependencies] -tracing = "0.1" +anyhow = { workspace = true } +thiserror = { workspace = true } + +tracing = { workspace = true } + +tokio = { workspace = true } +async-trait = { workspace = true } ffprobe = "0.4.0" imagesize = "0.13.0" @@ -27,8 +33,8 @@ revolt-config = { version = "0.9.4", path = "../config", features = [ revolt-result = { version = "0.9.4", path = "../result" } # image processing -jxl-oxide = "0.8.1" -image = { version = "0.25.2" } +jxl-oxide = { workspace = true } +image = { workspace = true } # svg rendering usvg = "0.44.0" @@ -37,3 +43,6 @@ tiny-skia = "0.11.4" # encoding webp = "0.3.0" + +[dev-dependencies] +uuid = { workspace = true } diff --git a/crates/core/files/src/implementation/encryption_impl.rs b/crates/core/files/src/implementation/encryption_impl.rs new file mode 100644 index 000000000..25da9cfd4 --- /dev/null +++ b/crates/core/files/src/implementation/encryption_impl.rs @@ -0,0 +1,75 @@ +use aes_gcm::{ + aead::{Aead, AeadCore, AeadMutInPlace, OsRng}, + Aes256Gcm, Key, KeyInit, Nonce, +}; +use base64::{prelude::BASE64_STANDARD, Engine}; + +use crate::EncryptionRepository; + +pub struct EncryptionKey { + key: String, +} + +impl EncryptionKey { + pub async fn from_config() -> EncryptionKey { + EncryptionKey::new(revolt_config::config().await.files.encryption_key) + } + + pub fn new(key: String) -> EncryptionKey { + EncryptionKey { key } + } + + fn create_cipher(&self) -> Aes256Gcm { + let key = &BASE64_STANDARD + .decode(self.key.clone()) + .expect("valid base64 string")[..]; + let key: &Key = key.into(); + Aes256Gcm::new(key) + } +} + +impl EncryptionRepository for EncryptionKey { + fn decrypt_buffer(&self, mut buf: Vec, iv: &str) -> anyhow::Result> { + let iv = &BASE64_STANDARD.decode(iv).unwrap()[..]; + let iv: &Nonce = iv.into(); + + self.create_cipher() + .decrypt_in_place(iv, b"", &mut buf) + .map_err(|error| { + tracing::error!("{}", error); + anyhow::anyhow!("EncryptionRepository: decryption failed") + })?; + + Ok(buf) + } + + fn encrypt_buffer(&self, buf: &[u8]) -> anyhow::Result<(Vec, String)> { + let iv = Aes256Gcm::generate_nonce(&mut OsRng); + + let buf = self.create_cipher().encrypt(&iv, buf).map_err(|error| { + tracing::error!("{}", error); + anyhow::anyhow!("EncryptionRepository: encryption failed") + })?; + + Ok((buf, BASE64_STANDARD.encode(iv))) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_encrypt_and_decrypt() { + let encryption = + EncryptionKey::new("XkbJ8gBzrouQ+15Ri23xCC81+aZE26Z6+gXzglFxOD4=".to_string()); + + let buf: Vec = vec![67]; + let (ciphertext, iv) = encryption.encrypt_buffer(&buf[..]).unwrap(); + assert_eq!(ciphertext.len(), 17); + + let plaintext = encryption.decrypt_buffer(ciphertext, &iv).unwrap(); + assert_eq!(plaintext.len(), 1); + assert_eq!(plaintext[0], 67); + } +} diff --git a/crates/core/files/src/implementation/media_impl.rs b/crates/core/files/src/implementation/media_impl.rs new file mode 100644 index 000000000..bd39534ab --- /dev/null +++ b/crates/core/files/src/implementation/media_impl.rs @@ -0,0 +1,294 @@ +use anyhow::Result; +use image::{DynamicImage, ImageBuffer, ImageReader}; +use jxl_oxide::integration::JxlDecoder; +use revolt_config::report_internal_error; +use std::io::{BufRead, Read, Seek}; +use tempfile::NamedTempFile; +use tiny_skia::Pixmap; + +use crate::{MediaError, MediaRepository}; + +pub struct MediaImpl { + config: revolt_config::Files, +} + +impl MediaImpl { + pub async fn from_config() -> MediaImpl { + MediaImpl { + config: revolt_config::config().await.files, + } + } + + pub fn new(config: revolt_config::Files) -> MediaImpl { + MediaImpl { config } + } +} + +impl MediaRepository for MediaImpl { + fn image_size(&self, f: &NamedTempFile) -> Option<(usize, usize)> { + if let Ok(size) = imagesize::size(f.path()) + .inspect_err(|err| tracing::error!("Failed to generate image size! {err:?}")) + { + Some((size.width, size.height)) + } else { + None + } + } + + fn image_size_vec(&self, v: &[u8], mime: &str) -> Option<(usize, usize)> { + match mime { + "image/svg+xml" => { + let tree = + report_internal_error!(usvg::Tree::from_data(v, &Default::default())).ok()?; + + let size = tree.size(); + Some((size.width() as usize, size.height() as usize)) + } + _ => { + if let Ok(size) = imagesize::blob_size(v) + .inspect_err(|err| tracing::error!("Failed to generate image size! {err:?}")) + { + Some((size.width, size.height)) + } else { + None + } + } + } + } + + fn decode_image( + &self, + reader: &mut R, + mime: &str, + ) -> Result { + match mime { + "image/jxl" => { + let decoder = + JxlDecoder::new(reader).map_err(|e| MediaError::from(anyhow::anyhow!(e)))?; + + DynamicImage::from_decoder(decoder) + .map_err(|e| MediaError::from(anyhow::anyhow!(e))) + } + "image/svg+xml" => { + let mut buf = Vec::new(); + reader + .read_to_end(&mut buf) + .map_err(|e| MediaError::from(anyhow::anyhow!(e)))?; + + let tree: usvg::Tree = usvg::Tree::from_data(&buf, &Default::default()) + .map_err(|e| MediaError::from(anyhow::anyhow!(e)))?; + + let size = tree.size(); + let mut pixmap = Pixmap::new(size.width() as u32, size.height() as u32) + .ok_or_else(|| MediaError::ImageProcessingFailed { + cause: "failed to create Pixmap, likely zero sized".to_string(), + })?; + + let mut pixmap_mut = pixmap.as_mut(); + resvg::render(&tree, Default::default(), &mut pixmap_mut); + + Ok(DynamicImage::ImageRgba8( + ImageBuffer::from_vec( + size.width() as u32, + size.height() as u32, + pixmap.data().to_vec(), + ) + .ok_or_else(|| MediaError::ImageProcessingFailed { + cause: "buffer is not big enough".to_string(), + })?, + )) + } + _ => { + let image: ImageReader<&mut R> = image::ImageReader::new(reader) + .with_guessed_format() + .map_err(|e| MediaError::from(anyhow::anyhow!(e)))?; + + let image: Result = image + .decode() + .map_err(|e| MediaError::from(anyhow::anyhow!(e))); + + image + } + } + } + + fn is_valid_image(&self, reader: &mut R, mime: &str) -> bool { + match mime { + "image/jxl" => jxl_oxide::JxlImage::builder() + .read(reader) + .inspect_err(|err| tracing::error!("Failed to read JXL! {err:?}")) + .is_ok(), + _ => !matches!( + image::ImageReader::new(reader) + .with_guessed_format() + .inspect_err(|err| tracing::error!("Failed to read image! {err:?}")) + .map(|f| f.decode()), + Err(_) | Ok(Err(_)) + ), + } + } + + fn create_thumbnail(&self, image: DynamicImage, tag: &str) -> Vec { + let [w, h] = self.config.preview.get(tag).unwrap(); + + let image = image.thumbnail(image.width().min(*w as u32), image.height().min(*h as u32)); + + let encoder = webp::Encoder::from_image(&image).expect("Could not create encoder."); + if self.config.webp_quality != 100.0 { + encoder.encode(self.config.webp_quality).to_vec() + } else { + encoder.encode_lossless().to_vec() + } + } + + fn video_size(&self, f: &NamedTempFile) -> Option<(i64, i64)> { + if let Ok(data) = ffprobe::ffprobe(f.path()) + .inspect_err(|err| tracing::error!("Failed to ffprobe file! {err:?}")) + { + for stream in data.streams { + if let (Some(w), Some(h)) = (stream.width, stream.height) { + return Some((w, h)); + } + } + + None + } else { + None + } + } +} + +#[cfg(test)] +mod tests { + use std::io::Cursor; + + use crate::{MediaImpl, MediaRepository}; + + #[tokio::test] + async fn asset_test_jpeg() { + let media = MediaImpl::from_config().await; + let buf = include_bytes!("../../tests/assets/test.jpeg"); + assert_eq!(media.image_size_vec(buf, "image/jpeg"), Some((655, 582))); + + let mut reader = Cursor::new(buf); + let image = media.decode_image(&mut reader, "image/jpeg").unwrap(); + media.create_thumbnail(image, "attachments"); + } + + #[tokio::test] + async fn asset_test_jpeg_extra_bytes() { + let media = MediaImpl::from_config().await; + let buf = [ + &include_bytes!("../../tests/assets/test.jpeg")[..], + &[0u8; 16], + ] + .concat(); + assert_eq!(media.image_size_vec(&buf, "image/jpeg"), Some((655, 582))); + + let mut reader = Cursor::new(buf); + let image = media.decode_image(&mut reader, "image/jpeg").unwrap(); + media.create_thumbnail(image, "emojis"); + } + + #[tokio::test] + async fn asset_test_png() { + let media = MediaImpl::from_config().await; + let buf = include_bytes!("../../tests/assets/test.png"); + assert_eq!(media.image_size_vec(buf, "image/png"), Some((900, 900))); + + let mut reader = Cursor::new(buf); + let image = media.decode_image(&mut reader, "image/png").unwrap(); + media.create_thumbnail(image, "emojis"); + } + + #[tokio::test] + async fn asset_test_png_extra_bytes() { + let media = MediaImpl::from_config().await; + let buf = [ + &include_bytes!("../../tests/assets/test.png")[..], + &[0u8; 16], + ] + .concat(); + assert_eq!(media.image_size_vec(&buf, "image/png"), Some((900, 900))); + + let mut reader = Cursor::new(buf); + let image = media.decode_image(&mut reader, "image/png").unwrap(); + media.create_thumbnail(image, "emojis"); + } + + #[tokio::test] + async fn asset_test_corrupted_png() { + let media = MediaImpl::from_config().await; + let buf = include_bytes!("../../tests/assets/corrupted.png"); + assert_eq!(media.image_size_vec(buf, "image/png"), Some((900, 900))); + + let mut reader = Cursor::new(buf); + media.decode_image(&mut reader, "image/png").unwrap_err(); + } + + #[tokio::test] + async fn asset_test_animated_png() { + let media = MediaImpl::from_config().await; + let buf = include_bytes!("../../tests/assets/anim-icos.apng"); + assert_eq!(media.image_size_vec(buf, "image/png"), Some((128, 128))); + + let mut reader = Cursor::new(buf); + let image = media.decode_image(&mut reader, "image/png").unwrap(); + media.create_thumbnail(image, "attachments"); + } + + #[tokio::test] + async fn asset_test_jxl() { + let media = MediaImpl::from_config().await; + let buf = include_bytes!("../../tests/assets/dice.jxl"); + assert_eq!(media.image_size_vec(buf, "image/jxl"), Some((800, 600))); + + let mut reader = Cursor::new(buf); + let image = media.decode_image(&mut reader, "image/jxl").unwrap(); + media.create_thumbnail(image, "attachments"); + } + + #[tokio::test] + async fn asset_test_animated_jxl() { + let media = MediaImpl::from_config().await; + let buf = include_bytes!("../../tests/assets/anim-icos.jxl"); + assert_eq!(media.image_size_vec(buf, "image/jxl"), Some((128, 128))); + + let mut reader = Cursor::new(buf); + let image = media.decode_image(&mut reader, "image/jxl").unwrap(); + media.create_thumbnail(image, "attachments"); + } + + #[tokio::test] + async fn asset_test_webp() { + let media = MediaImpl::from_config().await; + let buf = include_bytes!("../../tests/assets/dice.webp"); + assert_eq!(media.image_size_vec(buf, "image/webp"), Some((800, 600))); + + let mut reader = Cursor::new(buf); + let image = media.decode_image(&mut reader, "image/webp").unwrap(); + media.create_thumbnail(image, "attachments"); + } + + #[tokio::test] + async fn asset_test_animated_webp() { + let media = MediaImpl::from_config().await; + let buf = include_bytes!("../../tests/assets/anim-icos.webp"); + assert_eq!(media.image_size_vec(buf, "image/webp"), Some((128, 128))); + + let mut reader = Cursor::new(buf); + let image = media.decode_image(&mut reader, "image/webp").unwrap(); + media.create_thumbnail(image, "attachments"); + } + + #[tokio::test] + async fn asset_test_animated_gif() { + let media = MediaImpl::from_config().await; + let buf = include_bytes!("../../tests/assets/anim-icos.gif"); + assert_eq!(media.image_size_vec(buf, "image/gif"), Some((128, 128))); + + let mut reader = Cursor::new(buf); + let image = media.decode_image(&mut reader, "image/gif").unwrap(); + media.create_thumbnail(image, "attachments"); + } +} diff --git a/crates/core/files/src/implementation/mod.rs b/crates/core/files/src/implementation/mod.rs new file mode 100644 index 000000000..fa96ac22d --- /dev/null +++ b/crates/core/files/src/implementation/mod.rs @@ -0,0 +1,7 @@ +mod encryption_impl; +mod media_impl; +mod s3_impl; + +pub use encryption_impl::EncryptionKey; +pub use media_impl::MediaImpl; +pub use s3_impl::S3Storage; diff --git a/crates/core/files/src/implementation/s3_impl.rs b/crates/core/files/src/implementation/s3_impl.rs new file mode 100644 index 000000000..c27d62012 --- /dev/null +++ b/crates/core/files/src/implementation/s3_impl.rs @@ -0,0 +1,118 @@ +use std::io::Write; + +use anyhow::Context; +use aws_sdk_s3::{ + config::{Credentials, Region}, + Client, Config, +}; +use revolt_config::FilesS3; + +use crate::{EncryptionRepository, FileStorageRepository}; + +pub struct S3Storage { + client: Client, + encryption: ER, +} + +impl S3Storage { + pub async fn from_config(encryption: ER) -> S3Storage { + S3Storage::new(encryption, revolt_config::config().await.files.s3) + } + + pub fn new(encryption: ER, s3_config: FilesS3) -> S3Storage { + let provider_name = "my-creds"; + let creds = Credentials::new( + s3_config.access_key_id, + s3_config.secret_access_key, + None, + None, + provider_name, + ); + + let config = Config::builder() + .region(Region::new(s3_config.region)) + .endpoint_url(s3_config.endpoint) + .force_path_style(s3_config.path_style_buckets) + .credentials_provider(creds) + .build(); + + S3Storage { + client: Client::from_conf(config), + encryption, + } + } +} + +#[async_trait::async_trait] +impl FileStorageRepository for S3Storage { + async fn create_bucket(&self, bucket_id: &str) -> anyhow::Result<()> { + self.client + .create_bucket() + .bucket(bucket_id) + .send() + .await + .with_context(|| format!("failed to create bucket {bucket_id}"))?; + + Ok(()) + } + + async fn fetch_and_decrypt_file( + &self, + bucket_id: &str, + path: &str, + iv: &str, + ) -> anyhow::Result> { + let mut object = self + .client + .get_object() + .bucket(bucket_id) + .key(path) + .send() + .await + .with_context(|| format!("failed to get object at {path} in {bucket_id}"))?; + + let mut buf = vec![]; + while let Some(bytes) = object.body.next().await { + let data = bytes?; + buf.write_all(&data)?; + } + + if iv.is_empty() { + Ok(buf) + } else { + self.encryption.decrypt_buffer(buf, iv) + } + } + + async fn encrypt_and_upload_file( + &self, + bucket_id: &str, + path: &str, + buf: &[u8], + ) -> anyhow::Result { + let (buf, iv) = self.encryption.encrypt_buffer(buf)?; + + self.client + .put_object() + .bucket(bucket_id) + .key(path) + .body(buf.into()) + .send() + .await + .with_context(|| format!("failed to put object at {path} in {bucket_id}"))?; + + Ok(iv) + } + + async fn delete_file(&self, bucket_id: &str, path: &str) -> anyhow::Result<()> { + self.client + .delete_object() + .bucket(bucket_id) + .key(path) + .send() + .await + .with_context(|| format!("failed to delete object at {path} in {bucket_id}"))?; + + Ok(()) + } +} diff --git a/crates/core/files/src/lib.rs b/crates/core/files/src/lib.rs index f9db78102..b1c0982d7 100644 --- a/crates/core/files/src/lib.rs +++ b/crates/core/files/src/lib.rs @@ -1,293 +1,182 @@ -use std::io::{BufRead, Read, Seek, Write}; +mod implementation; +mod repositories; -use aes_gcm::{ - aead::{AeadCore, AeadMutInPlace, OsRng}, - Aes256Gcm, Key, KeyInit, Nonce, -}; -use image::{DynamicImage, ImageBuffer}; -use revolt_config::{config, report_internal_error, FilesS3}; -use revolt_result::{create_error, Result}; +pub use implementation::*; +pub use repositories::*; -use aws_sdk_s3::{ - config::{Credentials, Region}, - Client, Config, -}; +use std::io::{BufRead, Read, Seek}; + +use image::DynamicImage; +use revolt_config::{report_internal_error, Files, FilesLimit, FilesS3}; +use revolt_result::Result; -use base64::prelude::*; use tempfile::NamedTempFile; -use tiny_skia::Pixmap; -/// Size of the authentication tag in the buffer pub const AUTHENTICATION_TAG_SIZE_BYTES: usize = 16; -/// Create an S3 client -pub fn create_client(s3_config: FilesS3) -> Client { - let provider_name = "my-creds"; - let creds = Credentials::new( - s3_config.access_key_id, - s3_config.secret_access_key, - None, - None, - provider_name, - ); - - let config = Config::builder() - .region(Region::new(s3_config.region)) - .endpoint_url(s3_config.endpoint) - .force_path_style(s3_config.path_style_buckets) - .credentials_provider(creds) - .build(); - - Client::from_conf(config) -} - -/// Create an AES-256-GCM cipher -pub fn create_cipher(key: &str) -> Aes256Gcm { - let key = &BASE64_STANDARD.decode(key).expect("valid base64 string")[..]; - let key: &Key = key.into(); - Aes256Gcm::new(key) -} - /// Fetch a file from S3 (and decrypt it) -pub async fn fetch_from_s3(bucket_id: &str, path: &str, nonce: &str) -> Result> { - let config = config().await; - let client = create_client(config.files.s3); - - // Send a request for the file - let mut obj = - report_internal_error!(client.get_object().bucket(bucket_id).key(path).send().await)?; - - // Read the file from remote - let mut buf = vec![]; - while let Some(bytes) = obj.body.next().await { - let data = report_internal_error!(bytes)?; - report_internal_error!(buf.write_all(&data))?; - // is there a more efficient way to do this? - // we just want the Vec - } - - // File is not encrypted - if nonce.is_empty() { - return Ok(buf); - } - - // Recover nonce as bytes - let nonce = &BASE64_STANDARD.decode(nonce).unwrap()[..]; - let nonce: &Nonce = nonce.into(); - - // Decrypt the file - create_cipher(&config.files.encryption_key) - .decrypt_in_place(nonce, b"", &mut buf) - .map_err(|_| create_error!(InternalError))?; - - // Remove the authentication tag bytes that were added during encryption - buf.truncate(buf.len() - AUTHENTICATION_TAG_SIZE_BYTES); - - Ok(buf) +pub async fn fetch_from_s3(bucket_id: &str, path: &str, iv: &str) -> Result> { + let encryption = implementation::EncryptionKey::from_config().await; + let storage = implementation::S3Storage::from_config(encryption).await; + report_internal_error!(storage.fetch_and_decrypt_file(bucket_id, path, iv).await) } /// Encrypt and upload a file to S3 (returning its nonce/IV) pub async fn upload_to_s3(bucket_id: &str, path: &str, buf: &[u8]) -> Result { - let config = config().await; - let client = create_client(config.files.s3); - - // Generate a nonce - let nonce = Aes256Gcm::generate_nonce(&mut OsRng); - - // Extend the buffer for in-place encryption - let mut buf = [buf, &[0; AUTHENTICATION_TAG_SIZE_BYTES]].concat(); - - // Encrypt the file in place - create_cipher(&config.files.encryption_key) - .encrypt_in_place(&nonce, b"", &mut buf) - .map_err(|_| create_error!(InternalError))?; - - // Upload the file to remote - report_internal_error!( - client - .put_object() - .bucket(bucket_id) - .key(path) - .body(buf.into()) - .send() - .await - )?; - - Ok(BASE64_STANDARD.encode(nonce)) + let encryption = implementation::EncryptionKey::from_config().await; + let storage = implementation::S3Storage::from_config(encryption).await; + report_internal_error!(storage.encrypt_and_upload_file(bucket_id, path, buf).await) } /// Delete a file from S3 by path pub async fn delete_from_s3(bucket_id: &str, path: &str) -> Result<()> { - let config = config().await; - let client = create_client(config.files.s3); - - report_internal_error!( - client - .delete_object() - .bucket(bucket_id) - .key(path) - .send() - .await - )?; - - Ok(()) + let encryption = implementation::EncryptionKey::from_config().await; + let storage = implementation::S3Storage::from_config(encryption).await; + report_internal_error!(storage.delete_file(bucket_id, path).await) } /// Determine size of image at temp file pub fn image_size(f: &NamedTempFile) -> Option<(usize, usize)> { - if let Ok(size) = imagesize::size(f.path()) - .inspect_err(|err| tracing::error!("Failed to generate image size! {err:?}")) - { - Some((size.width, size.height)) - } else { - None - } + let media = MediaImpl::new(Files { + blocked_mime_types: Default::default(), + clamd_host: Default::default(), + encryption_key: Default::default(), + limit: FilesLimit { + max_mega_pixels: 0, + max_pixel_side: 0, + min_file_size: 0, + min_resolution: [0, 0], + }, + preview: Default::default(), + s3: FilesS3 { + access_key_id: Default::default(), + default_bucket: Default::default(), + endpoint: Default::default(), + path_style_buckets: Default::default(), + region: Default::default(), + secret_access_key: Default::default(), + }, + scan_mime_types: Default::default(), + webp_quality: Default::default(), + }); + + media.image_size(f) } /// Determine size of image with buffer pub fn image_size_vec(v: &[u8], mime: &str) -> Option<(usize, usize)> { - match mime { - "image/svg+xml" => { - let tree = - report_internal_error!(usvg::Tree::from_data(v, &Default::default())).ok()?; - - let size = tree.size(); - Some((size.width() as usize, size.height() as usize)) - } - _ => { - if let Ok(size) = imagesize::blob_size(v) - .inspect_err(|err| tracing::error!("Failed to generate image size! {err:?}")) - { - Some((size.width, size.height)) - } else { - None - } - } - } + let media = MediaImpl::new(Files { + blocked_mime_types: Default::default(), + clamd_host: Default::default(), + encryption_key: Default::default(), + limit: FilesLimit { + max_mega_pixels: 0, + max_pixel_side: 0, + min_file_size: 0, + min_resolution: [0, 0], + }, + preview: Default::default(), + s3: FilesS3 { + access_key_id: Default::default(), + default_bucket: Default::default(), + endpoint: Default::default(), + path_style_buckets: Default::default(), + region: Default::default(), + secret_access_key: Default::default(), + }, + scan_mime_types: Default::default(), + webp_quality: Default::default(), + }); + + media.image_size_vec(v, mime) } /// Determine size of video at temp file pub fn video_size(f: &NamedTempFile) -> Option<(i64, i64)> { - if let Ok(data) = ffprobe::ffprobe(f.path()) - .inspect_err(|err| tracing::error!("Failed to ffprobe file! {err:?}")) - { - // Use first valid stream - for stream in data.streams { - if let (Some(w), Some(h)) = (stream.width, stream.height) { - return Some((w, h)); - } - } - - None - } else { - None - } + let media = MediaImpl::new(Files { + blocked_mime_types: Default::default(), + clamd_host: Default::default(), + encryption_key: Default::default(), + limit: FilesLimit { + max_mega_pixels: 0, + max_pixel_side: 0, + min_file_size: 0, + min_resolution: [0, 0], + }, + preview: Default::default(), + s3: FilesS3 { + access_key_id: Default::default(), + default_bucket: Default::default(), + endpoint: Default::default(), + path_style_buckets: Default::default(), + region: Default::default(), + secret_access_key: Default::default(), + }, + scan_mime_types: Default::default(), + webp_quality: Default::default(), + }); + + media.video_size(f) } /// Decode image from reader pub fn decode_image(reader: &mut R, mime: &str) -> Result { - match mime { - // Read image using jxl-oxide crate - "image/jxl" => { - let jxl_image = report_internal_error!(jxl_oxide::JxlImage::builder().read(reader))?; - if let Ok(frame) = jxl_image.render_frame(0) { - match frame.color_channels().len() { - 3 => Ok(DynamicImage::ImageRgb8( - DynamicImage::ImageRgb32F( - ImageBuffer::from_vec( - jxl_image.width(), - jxl_image.height(), - frame.image().buf().to_vec(), - ) - .ok_or_else(|| create_error!(ImageProcessingFailed))?, - ) - .to_rgb8(), - )), - 4 => Ok(DynamicImage::ImageRgba8( - DynamicImage::ImageRgba32F( - ImageBuffer::from_vec( - jxl_image.width(), - jxl_image.height(), - frame.image().buf().to_vec(), - ) - .ok_or_else(|| create_error!(ImageProcessingFailed))?, - ) - .to_rgba8(), - )), - _ => Err(create_error!(ImageProcessingFailed)), - } - } else { - Err(create_error!(ImageProcessingFailed)) - } - } - // Read image using resvg - "image/svg+xml" => { - // usvg doesn't support Read trait so copy to buffer - let mut buf = Vec::new(); - report_internal_error!(reader.read_to_end(&mut buf))?; - - let tree = report_internal_error!(usvg::Tree::from_data(&buf, &Default::default()))?; - let size = tree.size(); - let mut pixmap = Pixmap::new(size.width() as u32, size.height() as u32) - .ok_or_else(|| create_error!(ImageProcessingFailed))?; - - let mut pixmap_mut = pixmap.as_mut(); - resvg::render(&tree, Default::default(), &mut pixmap_mut); - - Ok(DynamicImage::ImageRgba8( - ImageBuffer::from_vec( - size.width() as u32, - size.height() as u32, - pixmap.data().to_vec(), - ) - .ok_or_else(|| create_error!(ImageProcessingFailed))?, - )) - } - // Check if we can read using image-rs crate - _ => report_internal_error!(report_internal_error!( - image::ImageReader::new(reader).with_guessed_format() - )? - .decode()), - } + let media = MediaImpl::new(Files { + blocked_mime_types: Default::default(), + clamd_host: Default::default(), + encryption_key: Default::default(), + limit: FilesLimit { + max_mega_pixels: 0, + max_pixel_side: 0, + min_file_size: 0, + min_resolution: [0, 0], + }, + preview: Default::default(), + s3: FilesS3 { + access_key_id: Default::default(), + default_bucket: Default::default(), + endpoint: Default::default(), + path_style_buckets: Default::default(), + region: Default::default(), + secret_access_key: Default::default(), + }, + scan_mime_types: Default::default(), + webp_quality: Default::default(), + }); + + report_internal_error!(media.decode_image(reader, mime)) } /// Check whether given reader has a valid image pub fn is_valid_image(reader: &mut R, mime: &str) -> bool { - match mime { - // Check if we can read using jxl-oxide crate - "image/jxl" => jxl_oxide::JxlImage::builder() - .read(reader) - .inspect_err(|err| tracing::error!("Failed to read JXL! {err:?}")) - .is_ok(), - // Check if we can read using image-rs crate - _ => !matches!( - image::ImageReader::new(reader) - .with_guessed_format() - .inspect_err(|err| tracing::error!("Failed to read image! {err:?}")) - .map(|f| f.decode()), - Err(_) | Ok(Err(_)) - ), - } + let media = MediaImpl::new(Files { + blocked_mime_types: Default::default(), + clamd_host: Default::default(), + encryption_key: Default::default(), + limit: FilesLimit { + max_mega_pixels: 0, + max_pixel_side: 0, + min_file_size: 0, + min_resolution: [0, 0], + }, + preview: Default::default(), + s3: FilesS3 { + access_key_id: Default::default(), + default_bucket: Default::default(), + endpoint: Default::default(), + path_style_buckets: Default::default(), + region: Default::default(), + secret_access_key: Default::default(), + }, + scan_mime_types: Default::default(), + webp_quality: Default::default(), + }); + + media.is_valid_image(reader, mime) } /// Create thumbnail from given image pub async fn create_thumbnail(image: DynamicImage, tag: &str) -> Vec { - // Load configuration - let config = config().await; - let [w, h] = config.files.preview.get(tag).unwrap(); - - // Create thumbnail - //.resize(width as u32, height as u32, image::imageops::FilterType::Gaussian) - // resize is about 2.5x slower, - // thumbnail doesn't have terrible quality - // so we use thumbnail - let image = image.thumbnail(image.width().min(*w as u32), image.height().min(*h as u32)); - - // Encode it into WEBP - let encoder = webp::Encoder::from_image(&image).expect("Could not create encoder."); - if config.files.webp_quality != 100.0 { - encoder.encode(config.files.webp_quality).to_vec() - } else { - encoder.encode_lossless().to_vec() - } + let media = MediaImpl::from_config().await; + media.create_thumbnail(image, tag) } diff --git a/crates/core/files/src/repositories/encryption_repository.rs b/crates/core/files/src/repositories/encryption_repository.rs new file mode 100644 index 000000000..98e2a4988 --- /dev/null +++ b/crates/core/files/src/repositories/encryption_repository.rs @@ -0,0 +1,6 @@ +use anyhow::Result; + +pub trait EncryptionRepository: Send + Sync + 'static { + fn decrypt_buffer(&self, buf: Vec, iv: &str) -> anyhow::Result>; + fn encrypt_buffer(&self, buf: &[u8]) -> Result<(Vec, String)>; +} diff --git a/crates/core/files/src/repositories/file_storage_repository.rs b/crates/core/files/src/repositories/file_storage_repository.rs new file mode 100644 index 000000000..af97be808 --- /dev/null +++ b/crates/core/files/src/repositories/file_storage_repository.rs @@ -0,0 +1,22 @@ +use anyhow::Result; + +#[async_trait::async_trait] +pub trait FileStorageRepository: Send + Sync + 'static { + async fn create_bucket(&self, bucket_id: &str) -> anyhow::Result<()>; + + async fn fetch_and_decrypt_file( + &self, + bucket_id: &str, + path: &str, + iv: &str, + ) -> Result>; + + async fn encrypt_and_upload_file( + &self, + bucket_id: &str, + path: &str, + buf: &[u8], + ) -> Result; + + async fn delete_file(&self, bucket_id: &str, path: &str) -> Result<()>; +} diff --git a/crates/core/files/src/repositories/media_repository.rs b/crates/core/files/src/repositories/media_repository.rs new file mode 100644 index 000000000..4cc4fecac --- /dev/null +++ b/crates/core/files/src/repositories/media_repository.rs @@ -0,0 +1,30 @@ +use anyhow::Result; +use image::DynamicImage; +use std::io::{BufRead, Read, Seek}; +use tempfile::NamedTempFile; +use thiserror::Error; + +pub trait MediaRepository: Send + Sync + 'static { + fn image_size(&self, f: &NamedTempFile) -> Option<(usize, usize)>; + fn image_size_vec(&self, v: &[u8], mime: &str) -> Option<(usize, usize)>; + + fn decode_image( + &self, + reader: &mut R, + mime: &str, + ) -> Result; + + fn is_valid_image(&self, reader: &mut R, mime: &str) -> bool; + + fn create_thumbnail(&self, image: DynamicImage, tag: &str) -> Vec; + + fn video_size(&self, f: &NamedTempFile) -> Option<(i64, i64)>; +} + +#[derive(Debug, Error)] +pub enum MediaError { + #[error("image processing failed because {cause}")] + ImageProcessingFailed { cause: String }, + #[error(transparent)] + Unknown(#[from] anyhow::Error), +} diff --git a/crates/core/files/src/repositories/mod.rs b/crates/core/files/src/repositories/mod.rs new file mode 100644 index 000000000..cb0749e72 --- /dev/null +++ b/crates/core/files/src/repositories/mod.rs @@ -0,0 +1,7 @@ +mod encryption_repository; +mod file_storage_repository; +mod media_repository; + +pub use encryption_repository::EncryptionRepository; +pub use file_storage_repository::FileStorageRepository; +pub use media_repository::{MediaError, MediaRepository}; diff --git a/crates/core/files/tests/assets/anim-icos.apng b/crates/core/files/tests/assets/anim-icos.apng new file mode 100644 index 0000000000000000000000000000000000000000..b50cbe36475e268cba60346ec879fdc58c280eb1 GIT binary patch literal 991744 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%0Df_vGN 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

DIdsC>dOW15SG2^lcn`=h+`1pu9x3}=~T2Q>a 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%0AY>RtkCC-(kL({N4076%Hw#31|if$ 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ü` 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

s5j%C^C4EokUp$JE&@-JAnP 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

bLw_Ot);| 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

DS^d%Ei?mU4tBVKC4v8zYTO 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

q%wn=~5Fz9j?} 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

m7o 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

$S^uz-ffK@%AS@Rh21 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

E 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

y>gG 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%0AGAxi|*6_^q3c-IPzd|ch4 zbJG==xv{qDbAa2wNQ}UH##|Oh!<)6!B|$cJ-R=0OFh1N!)(ZXWt=U~pDT(rHTa&~_ zB_^pvQ2GS+1hDvLTlVF1+V1hZGcA*D6HlD;sAYiQ)MQh%hkCX)FPx= zE^#FiF#Cah(*{~0XW-x;Tq!eupjPHQz&c$YdGd$)>FyKgLf*p{_P!=76ma~hf<%E8 zl^phbhaG*I1V)8Mk-LE6z@Zl7xj3uY>vXqSEcYYg)vtgBGCWcO2*n?@x-Sfc0q<)> zLIU=18SR~O?-&*s0B0wW(b6RP6i30`!xvcf!pn*x2HQUk_2^2eI+XDVM+xq@c|sOKbbF{7 z?dF@1djQet%Q+tA+v?pLl$5n`L%lm`u4p~uA?jDMGUT5n6C=a^kRg#TAX-AP9Kq9Q1<~~tYfQORTBNAE*x2(qR z(wWn^;Q>i19v#*ne}gmqOCAqUW8Z_K(G6zjLN#yfrwV8hQ6SXOX7^!d1vzBhzP~Jm zV_Pnlt(gCexJbi5nl0)>W)@$r=prMpOsE*;?b7Y2$BpI!x;qNJtw@0O*h(<2yMF~} z8+|@#jB`IJyUr!wf(Px@f10Z$uaU^$3+7okFieoEk)xSXUS+o6ZL`khJuRM?4`J!b zl5n|&c)X!@60}s~G~)xRG#HN{8`}M{9tsz5kE|1Nc$04iVUve)B~`7CxUaJg79v@G}Cl-DXsF51}R5I3wqYPa2kjN%m?EUtG=w~X{xmn-IYt3WccX;z3=f-%~s|pnP zZ4O)5wz-XJz%MP_*-u}%Pa@}kl_mgIm|Fdg+JVtdKH@r3J8H0|bk#j(a^gU7ko5+z zsrtEWvm$yr9}>?yZw`_EsTnJ`yB88!BU;kU3tE*4MzYWN`O0_&4#C2q;m*IvI{m}u z6Nv>i0(YYp?F_+=$5oJHm2Tmd8-j%S^ibx0YggF;3%H4X=_1RBCk6#T;AgWSUl|g; zQ&TGJl{bi(SgCUmM3fN_>?+f-_EqqNZpUrvbBH z!J@*Es=oW`?zIjyJ?W>9ec%51!zs77AY^eauoPYF@W?Qgc?OJscp@K_|4xHIZY^da z^uFbHa5szAd1%N_>)1V&NNk6t9aZs|1lW=MIZCx8uxmE|10s{vK}&Pp9T{(Y$@%o# zAz_`!iYN`;p8;OA*9U$&P%d?7cU`J47*kD2?0%z%$=Z~_p_=jpW9zYvGDHH9qFteK z;ylhcuTY5mQ_y=!Hl2GjP`WALBP6weHJiRt4A&Tfq`F#d>cJxZ!wo&BGYY9gsrrO`Hbgd{32W_J*Ng$caX;0@X^kI~^kMrK1F*w%)x@F7 zHJ{Qo^w-2iMNH^@a2>KPTb4&m28`hL2*Yy#>Y--e&fKKwt-%kIyh+wgTpzbu4NRcL z1OSev`M<6eUL(X@!Mm1%wEqSBgbNwa#|oZN#Jja$UtWj)R|2=LS;c$-+ri;K%scF| z@smZg(6)BqNB9?)t&w4(bb@OW0}6w9N}hyEYcGu?YE;N6LVB55P{f6Z7JwrTW@HF; zMzDz$-Z&=yr5zlh&gD$|t+o6tn()?t-AM{s&jSD2)(pY`rT{M3MBOTJnUn681?I*E zMiAo146LluZKQ>dSV4f=F-%bq=SOg%^KnA@VkmQE5vK#7u$RLFDog-3;-E4_XBjv_ zfUuYruOQ)IBam!?7a4I9mlPL&-D(q55Q62o8>&XGEu@99+-x}qCs=vKhT=~&G|f`H zHGzm!h%g2IQtblM@NudDso^phP-E5GQ%V)h`K*QStinYEKa#*5jo2?f=zUr|+K6Y7 zxSE*Cg^L^xaeWrbDG9v&w5{Z}Oe60}F&`qg#wqZA8e325{1yD#AAu1je2d@KP8`B0 z$@&_Un*kiJB0kdaVG8zT#uj8tPN|S0t~Af>9~gK-wZO*)ml(^Rsla#o{9;-<#sHPY zVTXqr%IW}#;&n+Zg+2O1xS7Nz7`~WlgT4exud0z^3jg>6u!e@(t2Xe=u!R;cimKoW z+fG*O@I|238T2Kcx$g8aQXs$lpT^yh!A{!X$+n#wQEGw^e~WL5exOMu9h|EPKDU;-{367(H;LW9sr-qc>E0j+_SgxPwXX? zv(*6Y10+_{=J!@<{<;nRw2)HZ&HE$~Ceei<0HG}V@<^emiSMrf0*q+AKe+fTX812P z6}K5-T*ZH4lW?8)b!y=T5_@IZe!+ylVSVv6c#I8a{i}VJO4>FcNRV)zZcFiqfCmb! z!pdLXEqzD=Zvo^2332JW$^b9qqB~mJKDdup0o)+@vDQPw8OVhXthC`m1(Bkb)Q|_b zqG=vn~whKRk*U#UoKE97NHdECde_{d?KW-#UQ<6b#vt~ma~;-m zLv$jHLR#LOKsCYu6@EUQ&#h~4CW;LzloPXX#KkF+IGG5q{hu;z`9|~}NxV{{+>qmY z!=|kkiT}D;WpSrJ4r2HkaH*m(ZCT@(%h2c{KvZRc+z4)tL=sO)K6|^jMoW^I(o-~8 zPjP`ZCtcy~r%np5qJt!2vI@7T>$?E{RrU5KHfi`n{FSM*N%_;rc=QXh*mGLK!RGuO9#Q2XT_MI-eCLB@;0w zJdWX?;o99N;5@4!n!sW#VE8gV!Ood9>Ht6knLpXPsX56C!exQ84Dex__!2EpXBgdV zkl{#Kh2k`4CD^T}lGO;`0F>D9fpF>mH{w}Tjwb;(7{Q2h_-d{JZ8dOk%u*v7XMpxD z7x)cP;zIvgDs9xaF_|`U3(=A5HyB@xfV`v3s#bV&?*^Ef*(nqj{ECE z`ELpS&kAV;weRU)S6e@xHP~=Y5c8`7tpJe!LtKz>SDm2WG;WPGejiQjy7tYAMeDha zcQ?U}R(#jmDLHC$%d_E^fm7~_fiUAqZi?r3%M~TTYvB+G8~>vTy`+YQYyyg#IbYo52ylj@Y4#r5C8_7p&rNljvKT_oYPwhM*LEw9P0QAVr&I;!-m2gVFL8YXMZe zpLjhhGXT!Gc~2qQ6T|#4pZ_|!ehagpkOt2)q=^OcRoC`%$vh!A(1QC@9rYe}7g{9m zsM9ZApG}#Ma3igc*+wUid&_KRI=C4i#wDGon);0e0i{1Jx($60$1s9$H|UkY1Ga+} zP9!dxE&wWg3;V;3QMXSqz>5GP&nAsa#yDF+ZRGWFijB7viZwRS7>V~N{-bYxXQy4c zE8aiXyqcB9NhXh!}aVBIj$662&w>_|z1SXIod?j*% zcr2Ml3|fU7DKT!rxzU>KB0#8u93CI8wlyUg;1?*c(EVQSE9|rU0mUr zlL(v^(-i!>T5?pyyR0CNs-WQtLT41a97pD@BO+CIKC178Q{YG|exDi^r>>s&D^_d) zUbu=ElZ9S3@FLs(iUA8f6_je@Ruw#j716r>K$~QwN$>|N)dRxH_x%kFo;HSPG@!#R zg1rZUNT6r93OZ%V?724Q^p=;(QG#{q2!_Cv40?&?-{6ERDrC=_smaE*J;3hgeB_f2 zd_G=$n&^dA=MK2=N0aY%ns`PlB>M$QwMpjE-ZG=8%mmk3#qDY!?I6sv@_UDITLpku z5#pEvB&nBlueJ>XS|IQjObWPw_9zqnGg# z*x=5GjZn zem_Y#_p1-7L>%XMFq_aXygp?QNpjV|bOv@b31x(6f=c{~fG(K^hpA5?D*pOoZWRW> zQzL>9gW+oQcP=lc#L?DVC4Ab)@xSGkzdbM=$emQ9|n8M31Bn&|shqypIJ{Hd1Ba-DvZofNp|xA;lNtU~00;$$-IIDCmE}I}mh|Qa|6YqXkkRnA zjN8lDaU>>kenmpi_NgO$;kOUm#^K$v%Iufhp;hnQ;V{EMue;-^;`%Xmx&Le&Q1fIP z6>E6&hI_FQNNw&TFE7t1lzdSkA`$X6_ zF}CjKD~WDt%hT$2{kr&DXlHrn$q5SwKG*pBS4=ye*_ZP$GpBG|9CzLEb}Dl#sY_hI zK(j2`y$jO6&KZ+CHoY;ri7gtVFDgDZ-EQTJ+?qbep^?d7A2nV5^;l(P`h}M_T^+B@ zuD7ZTlq~1Q{e-qApV)-Ys{SqfZSx7}c$ zIc_-+(cEWjj=#NgW?)2C$>Tj$Ij-X$s@e`EB-v;3?c}aG;Os+xx9u6IwLNznbQ@n= zI5Nk^J21!dVf_x5#^W#d2d~QjD(%+zHSmC+evQ=@z3pqQ{Oh9m`1k$2T9z-WQm`Jdw3W*4n=*wS!jk?nUcF`L*`)i{gy;LPw}vqe)0v2z_N8b4 zjM)zQr0RA>$2ToE#0(0a7cBnvx1u7yzar{x&I@qG%BP;Jh$&iiQ`Wve+<}a_y*#up zN*YV&dmrSTS9cW8`YLbu{t%1F+tJa@t-pjQv1ocsMcwsYxkWVtRY{3i8ho73hcr0B zQ&aCaZiQ=38zN*ul~sr3vPP*XI)uL?Pc9Cb)~G( zJo$DIY4B?_weO%M%=p*@{^sh4lA3j+C%E`Q;?Tf1FBGyxSi-e<$bQrJb8vj^o5Mj0Gxnfl$mYmt6k(nKT(D? zjhL4M3%1G%@!1MVXnBlXi4t-zQjD#3ZAFzvO=@tR>yg+#=X(~2dwDDI@QZQ1qCiD~ zO*-F?1WTR=ci&>@6PQG+O=pdB_v zL=B3F`-G5$Rf8)owP8_FQR4!|wE|NFkzd(QdFmt5pZ zCNsb1e(t-qGRCz+PH1}Tk*kE_W~Y{!qBX!_Tz4LTbtV9 zJ}IZHSY)zN#K$1@#FVj@V1}jMV|H*f*RBKO|F=pRRMC!x&+%Xw(Nf3K8g|TRd^0`y zzAnD>jvf4^!6N8pQpBYK?ur{7c0Oo_SAxDgulK4Gk5u7+4o%tTVa4`}b9jz*P0P7Yi26ijnIc2=jDn=VfpR7oUID&FAmy8N0=+$D9U?h*c=YKIoaeWnN zGxI5SOcph3QXqV4=FWOs=VjJ1Ln(?3SZ|i8oZg$Nr9FS0gwYu5jXhe|Mg?DJ03(Ck z0%qXu`GRnXebsn&dT8bzw7ZL~?q^QzaxG$jt{Ra^5x;V_q)PTreT;}` zVuR?DT(P;Fx`oacz)7<{N1j%enZO=Pp8~kP}v=$!E4k@dC@kL z@2G+JK5UuZ)O4SZK&yz-*}Q0b#^`DPqSIPt>>S|im7TzpB7n&)ZFe5O_zrjMJGTAP zBkZT$h@*7@u#qZZ#};%S-biRmZfCL|qwsh-3?j!R`zs8c?z-Q4rL?~5Ym?Z5W1-Hp z?(Ddf8WZwSo;n$+SG0FWbI)9QW;ts(J9%Tgm9?TWuF;Ku|2EU21M?UiBL|A8vlDh} ztKD-uT>ivj0`>uvP43gCP%{W(nC;}m0b_WRzu=gG8{e&1^IsW_=e#SmZIawdZ=J~@ zu*wNzqIo)(HJo4_ZSO2$#EeLN!+ysa{DHf_5buMAqXct@N;o9m@xyd1HyCr6T8tHm z1bT34DrJ`sM31iZ(F1{(+b#Xt@Wbzt70V)Uo5n}TkIAOx%jNa(29m0a#>!St_FPyj z2LU{=d}(kTT&2^DUE$reXmrwp&r$0{qy;PMK?83m0N8k$=$tD7?8B~4b-KH6M*w9P zM@d7hb&8d%-G#JuVM>*@RO0DAYm5s;AMG+@%F-4+Hnj&2SFhak^CkR9?e*XeQjwlY z+R!a8pfM7Xwc&z&K-bhc-3|pNcgKT(YK-n=wa;KXnwlFwHTa%doDEuMe64X?0HTSh zQ3b7ECY)mH7%iG>d>87{I4>C^X1ESA_Nu%aVN~(?ax{&KcnAv0tV`W&ZQE!-Vzm8& z234Y=MA)2FWr4zFun(VM>{8|pucM=yPx@R}Z9gv^qw;GwZOL%@yI;6fAg zrw^Ju3|u8rCE=Q!ROa&Tk`E}CG^(3_n=}ej#a_^h2|#i#gG(Y(6q+`~SlFf!^0+H# zlY$xHc|ns6%1p6p(kdh=*T5F3to3S-5s;qwV>-2-WX$j?jof?54v7lqfRlUS6=6yN zS&GZli@ek@#gL9jq$CoUU1}w54=7c^VL+5bJw8=6s+KcWbgNhQGH8`6-H1-2#@Btg zm}dMTERDGmP;DGy%X5{hy{?S&MPHtQ#pdmG4h-8`rY7ot#1w7PP2HVVMvc`_=X6ii z+&0DdCWt=A;bD!L@i7qq7~ZFf#3tHeP79i#pI~}HgN6vy1XiNyRfKw#U^>OW8#+Y9 z{(P}!st9p&P|X`sFEy!sh8e}FjJ)RSb4R54o~oIB*R4#9d4wvT1~xFpvQ))e_pvKe zfwbV$o+1U$7Y)T){itKo1LsAA>feOxaT`_N0144<*gSQLsN2d^BIl`oc*XKG?8jtX zYO2)Q44zLamCGR5FnRRp@wg4vjKtKEY)_BP!|KptU{0@6*a@aa#{=EI3vfV#P>HEb z4n8ih_)>J0SM}|LND|<8ySNQ>(OAV2DZ@iHIg$!7bSMb|v=%ecB1&>7rh^;-0OfbQ z>lwFiNN+Rd(qsi%A5LD6L2oV@rY>CFChAttMj5Fhh0X&YMihDRkf#YoYZ33-uI8R; zS8g*lrb7Xr;mvd45F8SQ!E=pzjUH%e1mqM#7zrJPE|5nT311uV~SV5mWj?%g&r+B@tUCCg@ zOa6bq)cpvV?7x2Q_zpk!)kLSFbw#an z#QDQ(ob|agX$i-7N9UiTcB{ZG)85_h$Z-~OMd^N`(7dhts-BytP09T**TQ+_-KNhE znD+PE?-42l%<18b~TbvX34@2N!R zjl>xP8fmh@xvy5a(=)}ln~X~cq-MAU8|;2y+43Z%K`Te#_(EVrQ5|}olo#@^mPXltWlj@Gz`GmO1jyIVGeWumDcuCxO zodkyBVsMZ+%B*o?Mw~N8Oi2Os8U*&-;j>9i{QygzeV`$v00n7d< zm$K&BnNF9??mzoK;z^n(MfQcypM8}UQ*wXDfFZ)icK{6fJKf@jxCD6DE_%(YM;P>( zbYke1;gUp~73VBr;bX&S;yH(>LAq&Jckt^9XH!H3W$7#0u*Wmw<9!CuP;7baCgg1> zaqwHay)-grNW#KiS7ly>a!0HZ$Ia`7B!Ufw*)dMLFJ!RBCm14*wB=!S9nqDX=+yIU z#gvUaUh+vqG$k2ISTW}IiA@T%RW^ZFi4f~m;&8z56wn)}FU1*G!sdW*u@Q!Mztd=5 z#_)ZOYNyen0_N&4b-~T~HwIQkaTLB!K^4#lh%Q&M`ZlvsB&DJA-eKh6ylxK?Y|GD z##Omib4@~U&dXN$OPV$ z@nVM*tXixce;!<&!SitXQ>60TNmX+TrIt_R*9fVx`MWvF3PYQFRB*TOJEtaF`Wx)J zpsp(Diw4K_ag&Z2v@>y!t-18%z4&xRwxQo*HBR%|q(Wp`$yTPuaoYMv!KugGT%<&! z6xUR30!da1(c##fp>j^YkC%2|53+6NM@s7*kI?wU&eK(R_bPmY%#G`OreZuzySz*v z$DU0fXd_kWCszCK1i6uDmVIQZB=pM&XN)z(87waI%$HY?yg^}D8zZ8_;*L_AF;j}G zgVx`Ro_c_AZ8UURT_Lo1m83dp?Sz6sP z9kq0bQmVbgtXP|P?iq`+iTX^ZlCbWv?(aB48q0{nJKgi6z~CXJa8+)UoLOHPT0DD~ z#piZzYJbJq_ik2K#0qwOf#TsO0vV(_f;%wI)Y0M+#;w(awdhRPRC5O2JfeJd!3>w0 z1`?WvRQ|?y6+Xo}TO$Dnj8J9PUQbKmb?UGipS9U0cZZpjg!N|ZPporwm`W@8@va4P zr3|+|XjV86>)5hG66j)NnIxjUQbCY{$7Kdb6QvzfmFe*OehhaJxRrL1xzJFG>xfKc zEru>a{SwcVUWq!)qlM;E?EeX@43@jwLFQ6sJ^ukyQ zSrlA3qIAx^mr>&Mw~a@NVhs9@!~EF5zJEsIQ_`-nr(owpPGyWM7p|)}{%Y$M%kaT1 z__n;OHX+3Tb9Wv1#sL}SS+Eqk?b{7I3JO45id?wG5GyFX2TyfsWQ+zg zI5XWCoW8yI_S{`lQ|my4`&4+M7*;b%xJL`V@hQ=EM|*`?!TpaO>opV4nYmNEJQys4 z*>0NK%p8Y7^qyYjcRLD6n$y7gQ{3Y75v*R(n`u`jLhN|ZpT)ia<8+vYpT7`Gh<9T( z0^ zj$)w2$%3*q@qCA2*f4>U!Cir8u^*dTiD~tvv&40R!}|8{kw|UEX2||=F~!i<373`O zHY;;Gh%j+kl4rl=7l3K4Ud))D9qlL}R$MU04YsslTtObRCR4c0Ps%K|&$^a@8@>>%!>7R~g_VRf~g_uH8|5 z1AJ^Xz!pKlCO)zkJ$Fb`G&KfaRO@M#cZQk=MdQ!$nWTm%ixk=)1hHQ;Vo>0C9 z74F~%X;Vj78&3a<%%k^ViRHgA1-s1!fDCchuzn$hEk@oQIk?e|J=VmSupPcc#lUph zTMH`*RHS47sn6Z6Me#7~^KLHF#D5C_TS$T4jQoOW3R0PN82OWl(MlHYCKweau11dt z8^9o30KZ#5&$H-m5tH`6|6%5C9rXhIOp5^u{%#j{n-Q4V3qKd5G&E5>4^1gk!5~Dh z|31G#2Kg4WE+Y^MB{@sm)Oj=$VJM|#0vAMVn$bv-0W?X_kHd2e0(x)Mo305{ z>>M2WMagi2=6Z6Nl%db%juNwf^l+bMC-7~B$`W4_CVHL%imy0!)@ghk2 zM;Qvu0D?^wNIy)+o2$*j{v*hCjNRq6qQ*@1>EN5R=ztc0;LKn2$U`}jDFbcv$c0=X zyp()QFyvGj4WDdU!uo0|bNW#@!;?9kPQJ^joqD7cV_(Rvw3DH_?B z3_V9;br@5j-`3wXp2jm=N#;EhR}co#lcxwW<{LDDGY0_H3^A9lg*algRae;xke&vn zg?CZCF~OPwwvKRV|HR*B=uhLWY1+~ydO-_-(7h2mBXhHXJD#HdH!xqv3@s2`umPCw zHqmXAFDOt0KvPJxlH9Yhoa14lr=*;zI<&$J58ySWUXUxrU$u+vZP-;K1~*Qm*#dA6 z&TARGNg~)7-EpYlO!^?`xuJG2 z^PLU+UE1wZnm@sT{YwwFnbB9?yY`A%G|fN<0FVqpuYu`D@#)?}1IZl}L*ppkEQ;+w z(nI4_y#{ESZhK>v@OKR6yuy9~q?IyuXc3nMusviLS1$OwrH&p=Z@LDAkuVLGj7=hb zm!nq*rjr58HXjZUvl4UpT7bQc;>Kz7lta8AfJrx5E?TpvP~dI~jnWHu>)~GQTIndZ zrCo!umW0b2FlJ$DW+~Ftq7SFZlValuR~5Ej&wFJ8 z8!+LN7Z44Z(5u;WfhC^6s!iRspEMZ*~aob zW)K`P^R*-x$p(Vuf-5KxyzDGMasvSr>SskbfHIpbFm7Fza8MG;OzTH$3QhOL(A=< z1giiJbdU3SsA9v0vk5kBvoX+855yB79bVaDfO5o)ZFl%LKrizDi1E@^@wVX{3lh|7 zIrN-*qfH4@F4(w?yF{<17y7Sl;1=tFU_J0k#%-nj5az?#W~i&H?YxK`i8M_&LvdPQ zEm@N#W^MsW=aPaQB#4pR#{@Koj;k1mKC}T2=c+oNjT*T>z45(V7R8k7|%*B_2?KGVwPqZLu;Pntz~{N!U1OVMeOAk zV#EGh<*s;lE5L}CG3a5~l}Slf`i{xR@^VZfO*7gi=1h|_m15wdh~X#)c3uh^Cq~xk z7*zmU0B~NI*`IB0rbMtJWy1Oe$O1ioq5;^f2mX?CdoT{I4VsAev<`JQlQ?A;gc)*J3S)mzq&Pj{c5AHj&K57f!Quz+|KUDbqdLzcV@fe#>unkPPq&$=cTkrpXP^ zX+|h{bJL%Kw2cp-(=2B_;Gu(m=x5G0c0_;AK0k7aak(d&xEys^@Z7w+1wZ~mCVZf8 zN&y%PFLzwtBe+TKqv4|iq%hBL$Wp&#*(M$}87nZ*lOTA5nZ{tR0pzd6%Y~cuY3B{U zLJH0XJ%E@6w1VXiv#^0+MFygUGJeA4o^7O%&{ejW>p5EJpT|rD=TtTbXozjuX!5-+ z^qXYlDZt2Xee!rGBNi6_W<#YV>7U?dRR-qG!R#faRlkVt&POqK0i=r_zl2V z5wf3yaggTM+D+`sv_Qtp;tqZHu>wsD<^qdg9}U$kfz|%s=!{EggFVzR9L4*Iu1LtaUuijtocBb3NqAN;{d?vb zd-hT}Yi2HUk>7Ee)Pf)U@>&MhVuG-LIJJ8Cj+iy}7Genq|JL%po}@7~^zzp~_4qL4 z1`KN%ZnWP+{&WfnZ~DcummHe1I+AQqcl>QA>35+ zdH)t{y`KB2>h)Hga23WsDCfk`2&egV4c4<#i1?%*&Y*bhiNR6;iwOE}uQ^-W=%=eM z1dSN6hqrSko@zCQh9>M6O4qT*8&R&aLpV8i#-gjUcF{&ZGQbY!T$S}?%>N)7KlQLX z!1*Li<`CA=(0N{U4Q1Owoz(f`_MYuPk7uW zXrFfA>D%3`CX_HDxd5cKNM*viM<93R&w}x3<`9xv!4`kUqaQ7xrupPn6W4xwnY73s+ePm`3(%lOv%h}4fDK&#qnxm zTo`hC%s{5*YAK<7cUX>9P;stsNrebFdyDKm%&?`r2KHMsKVOYY>j@j}0@(|09Eu0V>lbULck7pw zdpObXhxg%T%UvS!hIGHIwhXuMGy)YT1D*FZupDSe;7*A1`gVuhZ)%J!>fUGDxq|r+ zN0{#>DG&E`Y^=(4SJdwgMagUXxZ<=ujs%y)RD}UbtJ$`;? z*VF@L$o}}-Hza$!6GhoI(_*zImyEVuc$w{ct)glHb6tO5Toa-EDK23*(TW`VU`VUOY)C* zyN<;#9lJfIu^VFK9V4YVpdo{(&GV0cS`#F`SIUYke7^UP-Qmv&W3mfLSteV)QdVxN zX}aMu`O>?=mqYlvewUPp-W*rXf_we8b7MbG%AXlrPWui#KWAy@`HNIrw+x7%+IS~M zMO7x3+>3d(8P^|X$b&7u@SJ>yVpK!_;JeDznex68=^0au$aVbbOQ#m{%$}T(Ws}_b zn@KakvfM0oFP&59HD*{Mt;u5KcU!nwrahMp?25lMAT0E{=G}~KV~E{E7jt98q%LTQ zK1#S=s}##>G!c{sBd1n1;b7w^fEi7EmsL&-iACjR&yEe#pGrKg&zqtVdGMba8RO&z zPC;;|3R?%bECMyVsN!y7jy0`gDck|{=b)4hUGE>-cvvBf7vd)rejSy zR#4`mg&ljFn4Sj^;0HH1PDpz@T&!m#lTFzn<;b{vE%*JJA&US51gjNjRIsPj;-U6n zofb(>~QZ)$kEvkAK>GTMH(9R0RMzb6%B zqZ4?!oj-b2UrNo-eXhGXeb!ok0WmFr|B$P6ou?5<&n0D?KFbGF{9XKPz2r@gf$ z0bliKLVO42OF;6$0cb(06nd*u3)~4Mff@Kmx}yX;>v#+Cr!IQ{H@=r5g4QZS6~tIz zrno92-;EpEEtwH}daI>pVO@xK^w>G?cvH==prTCecjmM(EUeVVX%oXb1-L(7^vZ^u zQ0kVC&s9mIpbahEG3o!zUeGxQ@+#H{2n()5w+Cy!oSK}eWi6u=qoC2m6!qdvDTQ0R z>5g%~*pyrLDs0o%#E(5zS24Sja=lI}lg=s7ER5->6fr`1!JG>Y^_I-|7yMW53g9+r zQ`8Om78dXvqyXc`V(xeU{WGr`NjX*MxFmd*f;Dxx9$qzMuyv?m{QPN*OZ^G94Xp+# z9F{a6ny>L9vEPP9Fyr!G{Y}w7R^}v9-S7OQ4 zF{a~M8qsJFHG3`Nh``8R0^;N~6^yaW;CPy@x)ygc0yf{P%)=odoRk4G=^I*lw@z=q z-tbc+^27UYy*mB-5`EY8pcH@Y!u zjj^F+VxFfgU{Z}tbJ%fJbv|W)NV397Z?Fsm#{U>f{SoMNkJe4OJ3r|LnMDQABEnsG zdO3qH!+=ecESVnW++?sko%w;)&am zM!+Fh2YDWIEBF@YSVxuy#kW^@CVE&abU7!UKd$gUD{(v|iWTP9K+=s-4f}|f$JV87 zBYQY-@ZYh#qJEBaXFmYwI>x!IGIf{Ut66AO@Uf2fK-A7ZY4O)l$0&PWi&)1F ziuQ9l0A9;g+>dqDl49Jl#wZOKQPAjnh)Xr~gKe-7n3#R}O>r6Q=}T4#im!qIQ)*)v z&ET(e`eGiaz2;$PL--p9M55r1^UE^J6Rg|cdKLc%@W7(Na|%YQsMPC|fgRG*@@!4{ z=RX~1t9%km(&pmrE+kN$K4;&?OC-VlT3{Y)J&L(wV0icGs+`oYDMMJZPw9yVp&u$W zDP_0Lg##Kfsz{@#KnGP) zx7t=uHy|#kE4SX{DlK{&x%nsqDIFu)>yUPN77qOSTf3lN&Ht!$@+wJ}!#P7C3s7bf zN&S0KIewn3L$%R#C8K$F=#nSjbOw4&G1N6}_w3E!^tA%Oo16zzqNi*AORsR?1zJ(a3_GbKv}wlt`&1*-E5r53nq zUj!@JaO0;hiJERzT{7h&w!WHVqC;>=wc2E;;qXI}h_5E-lZHvDUT+1~wXtV~r|tg#c(;UdP$?$$s0?uOj(&uCK* zlv?y8&Ty|qW@=%2=Ud+0I;jkblmnhaiK_-@{?oiG68lE2tReQlo1>9*Gb77@1x+xE zXnxW>3prs^Js7`Q-X2rSWEE>Bkx8AwC(i%%e8zzZf3_8jW-v^4r^1dDE&X?OvSsC( zpVvKn7RW(%EC<5YnKIr!3Ivt`_no1OWCLFSq1L>Bacu(vVXuB{!s?pNBikL|Qt+-% z?Q-o8tU&2~IvjlI-fxc3`5pYwt3%*6;5z7+OX7J!o?Sg0<&9M8Wsw zG_cXp2;=n$%P-Zd9bTIC8h@ZO_u0BPWtMdbuWGZn%|LumRnYgOm1hO~@<^qHGF72* zY3jRoH-Zlkagz%#xySeioV(ZII{aT_tYcr({agHk1BP3HCkIPz;7Um#S{rFQA$qSz zoBYoPsO?pPAfPs?E25=mnUMRUZFOSEg=hL(_K#{;H=NCDdaCf+;1zu{FqhV7;HR>) z?;hV#ULH3NsQp)P0UlH1W82qjrS`wyoAq-95j-K@(YiajdTK&%i8AQsH<5*{Syz2~ z*zbM5BM+sn@weoi5p11CWaKV_y+&(pv4PZ}o9J)(%?9@eg%Ese^=@YY^Q7poz@ zA9h%VJYaA6c}^0~H+)V;j?;?Xd*E32<_Dk7N^>*IEjF99kkS4>r`?jePB$%T^o_(E zQ!t5i;QMq-wsm-Zro_|k(yEz03uv~335YYf+?$2>5^TZ;O|ee7PFK(Rgb#stgO1Jn zm_M<<$?~ebdubzL@#n@{J3L3{^w*i3IgJJ%6M4Qa>&6D7LmA5mE6_I;|#$M9=A!ws^DZECki48k0P zMA(rUE8I=7XCzV~)2KSBXB22)cUrFQ?iHL)oU2=cBbzr#*TF(yRTmODrrnDNzWyLzxk zFzC*7HmO6K#Txs=^={ks3db*j*z_-MSz;WNbktPmTp9p>Zj82=DPt`9QqS>57e}cx zwk5RnyWKFvOgI2AT+GpoBjI2$C#qKx->;8}Z|3Klx5+jRM8Rcoww?xU_XT(>G(Ya` zdpCi)FV~`J=vw4mQs~|mWxwK?Qe1>5mUNng&-F0v94HGOttByE6UaO8t|U6q!_Hua zU1quoH?|G5{T08$X~0|^h8ozJ0lxY$0j1f&=yV6XyHey+6Ks~6+=xn!3&{ssqi#cOPD7FG%NV?0_igP;0 zExo?c>*Xm@V+G>?Aq^e2-~>0?*?SYEZa>M&7DPm^Wh$^8~n$y`%h+T6(IOYwgm?ze`&L9D2f>Q7O zS|T(Nam!ei%(QF|R+nd)dmeUvjh+~_c^XgK5HeItOiJq*uTnpCJHy(s6j`m6x)T

To>)To}@fZLZ3hkLqk6$gc&&{#O~9u9Tkq{wlcS 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

-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 literal 0 HcmV?d00001 diff --git a/crates/core/files/tests/assets/anim-icos.jxl b/crates/core/files/tests/assets/anim-icos.jxl new file mode 100644 index 0000000000000000000000000000000000000000..bf3d1e44547c23a56310ec31edcd91672732d5fd GIT binary patch literal 341449 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

)`ljRW4=aigRn2 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

!B^XVQgGJ`4%6q7sR-Bl@R; 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­YXD@h^}_=lR1(Ri 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

diff --git a/crates/core/database/templates/suspension.txt b/crates/core/database/templates/suspension.txt index d247eae33..293f8a0c2 100644 --- a/crates/core/database/templates/suspension.txt +++ b/crates/core/database/templates/suspension.txt @@ -3,7 +3,7 @@ Your account has been suspended, for one or more reasons: You will be able to use your account again in {{duration}} days. -Further violations may result in a permanent ban depending on severity, please abide by the Acceptable Usage Policy (https://revolt.chat/aup). +Further violations may result in a permanent ban depending on severity, please abide by the Community Guidelines (https://stoat.chat/legal/community-guidelines). Ban evasion is prohibited and will be dealt with accordingly. diff --git a/crates/core/database/templates/suspension.whitelabel.txt b/crates/core/database/templates/suspension.whitelabel.txt index 45d9aa560..bd82145d4 100644 --- a/crates/core/database/templates/suspension.whitelabel.txt +++ b/crates/core/database/templates/suspension.whitelabel.txt @@ -3,6 +3,6 @@ Your account has been suspended, for one or more reasons: This email is intended for {{email}} -This email has no association with Revolt or Revolt Platforms Ltd. +This email has no association with Stoat or Revolt Platforms Ltd. Learn more about third party instances here: -https://developers.revolt.chat/faq.html +https://developers.stoat.chat/faq/ diff --git a/crates/core/database/templates/verify.whitelabel.txt b/crates/core/database/templates/verify.whitelabel.txt index 547128b94..16f1c4b13 100644 --- a/crates/core/database/templates/verify.whitelabel.txt +++ b/crates/core/database/templates/verify.whitelabel.txt @@ -7,4 +7,4 @@ This email is intended for {{email}} This email has no association with Stoat or Revolt Platforms Ltd. Learn more about third party instances here: -https://developers.revolt.chat/faq.html +https://developers.stoat.chat/faq/ diff --git a/docs/docs/developers/endpoints.md b/docs/docs/developers/endpoints.md index b22c64e2f..a89b4d3ee 100644 --- a/docs/docs/developers/endpoints.md +++ b/docs/docs/developers/endpoints.md @@ -8,16 +8,12 @@ sidebar_position: 1 You can connect to the API on the following URLs: -| URL | Release | Description | -| ----------------------------- | :--------: | --------------------------- | -| `https://api.revolt.chat` | Production | Primary API endpoint | -| `https://app.revolt.chat/api` | Production | API endpoint for old client | -| `https://revolt.chat/api` | Staging | API endpoint for new client | +| URL | Release | Description | +| ----------------------------- | :--------: | ---------------------------------- | +| `https://api.stoat.chat` | Production | Primary API endpoint | You can connect to the events server on the following URLs: -| URL | Release | Description | -| ------------------------------ | :--------: | ------------------------------ | -| `wss://ws.revolt.chat` | Production | Primary events endpoint | -| `wss://app.revolt.chat/events` | Production | Events endpoint for old client | -| `wss://revolt.chat/events` | Staging | Events endpoint for new client | +| URL | Release | Description | +| ------------------------------ | :--------: | ------------------------------------- | +| `wss://events.stoat.chat` | Production | Primary events endpoint | diff --git a/docs/docs/developers/legacy-plugin-api.md b/docs/docs/developers/legacy-plugin-api.md index ac5c58fce..d2c452c8f 100644 --- a/docs/docs/developers/legacy-plugin-api.md +++ b/docs/docs/developers/legacy-plugin-api.md @@ -10,7 +10,7 @@ The Plugin API is very powerful. **Tread carefully.** **Zero guarantees or sandboxes are provided.** Your code is run as-is. ::: -This document details the very experimental plugin API available in [Revite](https://github.com/revoltchat/revite). +This document details the very experimental plugin API available in [Revite](https://github.com/stoatchat/for-legacy-web). This is more or less a proof of concept but can be used to achieve some simple client modifications. diff --git a/docs/docs/developing/backend/new_features.md b/docs/docs/developing/backend/new_features.md index c95171807..029e1325b 100644 --- a/docs/docs/developing/backend/new_features.md +++ b/docs/docs/developing/backend/new_features.md @@ -4,12 +4,12 @@ New API features must be documented where appropriate, this document aims to cov Before writing new API features, generally a good idea to: -- Consult with other developers in the [Revolt Developers space](https://rvlt.gg/API) +- Consult with other developers in the [Stoat Developers space](https://stt.gg/API) - If it's a relatively big feature, also [write an RFC](https://github.com/revoltchat/rfcs) When your feature is ready to release, ensure to: - Update backend documentation (what you're reading now!) if applicable -- Update the [developers documentation](https://github.com/revoltchat/wiki) if applicable +- Update the [developers documentation](https://github.com/stoatchat/developer-wiki) if applicable - Update the Feature Matrix (or ask someone that can to do so) - Ensure it is properly listed in the backend release changelog From b0b728fb0dbc9ee28360301de1c3ea501bbbff1d Mon Sep 17 00:00:00 2001 From: Tom Date: Tue, 10 Mar 2026 15:00:06 -0700 Subject: [PATCH 103/211] fix: redis_url vs redis_uri in config (#666) --- crates/core/config/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/core/config/src/lib.rs b/crates/core/config/src/lib.rs index 8b68ad4fc..7e26fb20f 100644 --- a/crates/core/config/src/lib.rs +++ b/crates/core/config/src/lib.rs @@ -449,7 +449,7 @@ pub async fn config() -> Settings { let mut config = read().await.try_deserialize::().unwrap(); // inject REDIS_URI for redis-kiss library - if std::env::var("REDIS_URL").is_err() { + if std::env::var("REDIS_URI").is_err() { std::env::set_var("REDIS_URI", config.database.redis.clone()); } From 49c628958070e4f0a5edc764d3b48158589219d9 Mon Sep 17 00:00:00 2001 From: Angelo Kontaxis Date: Tue, 10 Mar 2026 22:14:32 +0000 Subject: [PATCH 104/211] fix: store server id in redis and in room metadata to be able to delete voice state in all scenarios (#656) * fix: store server id in redis values and in room metadata to be able to fully delete voice state in all scenarios * fix: undo logging change --- crates/bonfire/src/events/impl.rs | 6 +- .../src/models/server_members/model.rs | 17 +- crates/core/database/src/voice/mod.rs | 232 ++++++++++++------ .../core/database/src/voice/voice_client.rs | 6 + crates/daemons/voice-ingress/src/api.rs | 55 +++-- crates/delta/src/routes/bots/delete.rs | 8 +- .../src/routes/channels/channel_delete.rs | 17 +- .../delta/src/routes/channels/channel_edit.rs | 4 +- .../routes/channels/group_remove_member.rs | 10 +- .../delta/src/routes/channels/voice_join.rs | 25 +- .../src/routes/channels/voice_stop_ring.rs | 16 +- crates/delta/src/routes/servers/ban_create.rs | 17 +- .../delta/src/routes/servers/member_edit.rs | 25 +- .../delta/src/routes/servers/member_remove.rs | 17 +- .../delta/src/routes/servers/server_delete.rs | 21 +- 15 files changed, 322 insertions(+), 154 deletions(-) diff --git a/crates/bonfire/src/events/impl.rs b/crates/bonfire/src/events/impl.rs index 0fbe16249..c6d07d2f3 100644 --- a/crates/bonfire/src/events/impl.rs +++ b/crates/bonfire/src/events/impl.rs @@ -4,7 +4,7 @@ use futures::future::join_all; use revolt_database::{ events::client::{EventV1, ReadyPayloadFields}, util::permissions::DatabasePermissionQuery, - voice::get_channel_voice_state, + voice::{get_channel_voice_state, UserVoiceChannel}, Channel, Database, Member, MemberCompositeKey, Presence, RelationshipStatus, }; use revolt_models::v0; @@ -167,7 +167,9 @@ impl State { | Channel::TextChannel { voice: Some(_), .. } ) }) { - if let Ok(Some(voice_state)) = get_channel_voice_state(channel).await { + if let Ok(Some(voice_state)) = + get_channel_voice_state(&UserVoiceChannel::from_channel(channel)).await + { if let Some(server) = channel.server() { let set = voice_state_server_members .entry(server.to_string()) diff --git a/crates/core/database/src/models/server_members/model.rs b/crates/core/database/src/models/server_members/model.rs index 0062a2708..e242c62f5 100644 --- a/crates/core/database/src/models/server_members/model.rs +++ b/crates/core/database/src/models/server_members/model.rs @@ -3,8 +3,8 @@ use revolt_permissions::{calculate_channel_permissions, ChannelPermission}; use revolt_result::{create_error, Result}; use crate::{ - events::client::EventV1, util::permissions::DatabasePermissionQuery, Channel, - Database, File, Server, SystemMessage, User, + events::client::EventV1, util::permissions::DatabasePermissionQuery, Channel, Database, File, + Server, SystemMessage, User, }; fn default_true() -> bool { @@ -45,7 +45,6 @@ auto_derived_partial!( /// Whether the member is server-wide voice deafened #[serde(skip_serializing_if = "is_true", default = "default_true")] pub can_receive: bool, - // This value only exists in the database, not the models. // If it is not-None, the database layer should return None to member fetching queries. // pub pending_deletion_at: Option @@ -153,7 +152,11 @@ impl Member { #[cfg(feature = "voice")] for channel in &channels { - if let Ok(Some(voice_state)) = crate::voice::get_channel_voice_state(channel).await { + if let Ok(Some(voice_state)) = crate::voice::get_channel_voice_state( + &crate::voice::UserVoiceChannel::from_channel(channel), + ) + .await + { voice_states.push(voice_state) } } @@ -175,7 +178,7 @@ impl Member { .map(|channel| channel.into()) .collect(), emojis: emojis.into_iter().map(|emoji| emoji.into()).collect(), - voice_states + voice_states, } .private(user.id.clone()) .await; @@ -225,14 +228,14 @@ impl Member { pub fn remove_field(&mut self, field: &FieldsMember) { match field { - FieldsMember::JoinedAt => {}, + FieldsMember::JoinedAt => {} FieldsMember::Avatar => self.avatar = None, FieldsMember::Nickname => self.nickname = None, FieldsMember::Roles => self.roles.clear(), FieldsMember::Timeout => self.timeout = None, FieldsMember::CanReceive => self.can_receive = true, FieldsMember::CanPublish => self.can_publish = true, - FieldsMember::VoiceChannel => {}, + FieldsMember::VoiceChannel => {} } } diff --git a/crates/core/database/src/voice/mod.rs b/crates/core/database/src/voice/mod.rs index 1705beceb..836de92ad 100644 --- a/crates/core/database/src/voice/mod.rs +++ b/crates/core/database/src/voice/mod.rs @@ -1,3 +1,5 @@ +use std::fmt::{Display, Write}; + use crate::{ events::client::EventV1, models::{Channel, User}, @@ -6,7 +8,11 @@ use crate::{ }; use iso8601_timestamp::{Duration, Timestamp}; use livekit_protocol::ParticipantPermission; -use redis_kiss::{get_connection as _get_connection, redis::Pipeline, AsyncCommands, Conn}; +use redis_kiss::{ + get_connection as _get_connection, + redis::{FromRedisValue, Pipeline, RedisError, RedisWrite, ToRedisArgs, Value}, + AsyncCommands, Conn, +}; use revolt_config::FeaturesLimits; use revolt_models::v0::{self, PartialUserVoiceState, UserVoiceState}; use revolt_permissions::{calculate_channel_permissions, ChannelPermission, PermissionValue}; @@ -21,13 +27,13 @@ async fn get_connection() -> Result { .map_err(|_| create_error!(InternalError)) } -pub async fn raise_if_in_voice(user: &User, channel_id: &str) -> Result<()> { +pub async fn raise_if_in_voice(user: &User, channel: &UserVoiceChannel) -> Result<()> { let mut conn = get_connection().await?; if user.bot.is_some() { // bots can be in as many voice channels as it wants so we just check if its already connected to the one its trying to connect to if conn - .sismember(format!("vc:{}", &user.id), channel_id) + .sismember(format!("vc:{}", &user.id), channel) .await .to_internal_error()? { @@ -45,31 +51,31 @@ pub async fn raise_if_in_voice(user: &User, channel_id: &str) -> Result<()> { Ok(()) } -pub async fn set_channel_node(channel: &str, node: &str) -> Result<()> { +pub async fn set_channel_node(channel_id: &str, node: &str) -> Result<()> { get_connection() .await? - .set(format!("node:{channel}"), node) + .set(format!("node:{channel_id}"), node) .await .to_internal_error() } -pub async fn get_channel_node(channel: &str) -> Result> { +pub async fn get_channel_node(channel_id: &str) -> Result> { get_connection() .await? - .get(format!("node:{channel}")) + .get(format!("node:{channel_id}")) .await .to_internal_error() } -pub async fn delete_channel_node(channel: &str) -> Result<()> { +pub async fn delete_channel_node(channel_id: &str) -> Result<()> { get_connection() .await? - .del(format!("node:{channel}")) + .del(format!("node:{channel_id}")) .await .to_internal_error() } -pub async fn get_user_voice_channels(user_id: &str) -> Result> { +pub async fn get_user_voice_channels(user_id: &str) -> Result> { get_connection() .await? .smembers(format!("vc:{user_id}")) @@ -78,14 +84,14 @@ pub async fn get_user_voice_channels(user_id: &str) -> Result> { } pub async fn set_user_moved_from_voice( - old_channel: &str, - new_channel: &str, + old_channel_id: &str, + new_channel: &UserVoiceChannel, user_id: &str, ) -> Result<()> { get_connection() .await? .set_ex( - format!("moved_from:{user_id}:{old_channel}"), + format!("moved_from:{user_id}:{old_channel_id}"), new_channel, 10, ) @@ -102,18 +108,25 @@ pub async fn get_user_moved_from_voice(channel_id: &str, user_id: &str) -> Resul } pub async fn set_user_moved_to_voice( - new_channel: &str, - old_channel: &str, + new_channel_id: &str, + old_channel: &UserVoiceChannel, user_id: &str, ) -> Result<()> { get_connection() .await? - .set_ex(format!("moved_to:{user_id}:{new_channel}"), old_channel, 10) + .set_ex( + format!("moved_to:{user_id}:{new_channel_id}"), + old_channel, + 10, + ) .await .to_internal_error() } -pub async fn get_user_moved_to_voice(channel_id: &str, user_id: &str) -> Result> { +pub async fn get_user_moved_to_voice( + channel_id: &str, + user_id: &str, +) -> Result> { get_connection() .await? .get_del(format!("moved_to:{user_id}:{channel_id}")) @@ -121,10 +134,10 @@ pub async fn get_user_moved_to_voice(channel_id: &str, user_id: &str) -> Result< .to_internal_error() } -pub async fn is_in_voice_channel(user_id: &str, channel_id: &str) -> Result { +pub async fn is_in_voice_channel(user_id: &str, channel: &UserVoiceChannel) -> Result { get_connection() .await? - .sismember(format!("vc:{user_id}"), channel_id) + .sismember(format!("vc:{user_id}"), channel) .await .to_internal_error() } @@ -158,12 +171,15 @@ pub fn get_allowed_sources( } pub async fn create_voice_state( - channel_id: &str, - server_id: Option<&str>, + channel: &UserVoiceChannel, user_id: &str, joined_at: Timestamp, ) -> Result { - let unique_key = format!("{}:{}", &user_id, server_id.unwrap_or(channel_id)); + let unique_key = format!( + "{}:{}", + &user_id, + channel.server_id.as_ref().unwrap_or(&channel.id) + ); let voice_state = UserVoiceState { joined_at, @@ -175,9 +191,9 @@ pub async fn create_voice_state( }; Pipeline::new() - .sadd(format!("vc_members:{channel_id}"), user_id) - .sadd(format!("vc:{user_id}"), channel_id) - .set(&unique_key, channel_id) + .sadd(format!("vc_members:{}", &channel.id), user_id) + .sadd(format!("vc:{user_id}"), channel) + .set(&unique_key, &channel.id) .set( format!("joined_at:{unique_key}"), joined_at @@ -204,16 +220,16 @@ pub async fn create_voice_state( Ok(voice_state) } -pub async fn delete_voice_state( - channel_id: &str, - server_id: Option<&str>, - user_id: &str, -) -> Result<()> { - let unique_key = format!("{}:{}", &user_id, server_id.unwrap_or(channel_id)); +pub async fn delete_voice_state(channel: &UserVoiceChannel, user_id: &str) -> Result<()> { + let unique_key = format!( + "{}:{}", + &user_id, + channel.server_id.as_ref().unwrap_or(&channel.id) + ); Pipeline::new() - .srem(format!("vc_members:{channel_id}"), user_id) - .srem(format!("vc:{user_id}"), channel_id) + .srem(format!("vc_members:{}", &channel.id), user_id) + .srem(format!("vc:{user_id}"), channel) .del(&[ format!("joined_at:{unique_key}"), format!("is_publishing:{unique_key}"), @@ -228,20 +244,19 @@ pub async fn delete_voice_state( } pub async fn delete_channel_voice_state( - channel_id: &str, - server_id: Option<&str>, + channel: &UserVoiceChannel, user_ids: &[String], ) -> Result<()> { - let parent_id = server_id.unwrap_or(channel_id); + let parent_id = channel.server_id.as_ref().unwrap_or(&channel.id); let mut pipeline = Pipeline::new(); - pipeline.del(format!("vc_members:{channel_id}")); - pipeline.del(format!("node:{channel_id}")); + pipeline.del(format!("vc_members:{}", &channel.id)); + pipeline.del(format!("node:{}", &channel.id)); for user_id in user_ids { let unique_key = format!("{user_id}:{parent_id}"); - pipeline.srem(format!("vc:{user_id}"), channel_id).del(&[ + pipeline.srem(format!("vc:{user_id}"), channel).del(&[ format!("joined_at:{unique_key}"), format!("is_publishing:{unique_key}"), format!("is_receiving:{unique_key}"), @@ -258,8 +273,7 @@ pub async fn delete_channel_voice_state( } pub async fn update_voice_state_tracks( - channel_id: &str, - server_id: Option<&str>, + channel: &UserVoiceChannel, user_id: &str, added: bool, track: i32, @@ -284,18 +298,21 @@ pub async fn update_voice_state_tracks( _ => unreachable!(), }; - update_voice_state(channel_id, server_id, user_id, &partial).await?; + update_voice_state(channel, user_id, &partial).await?; Ok(partial) } pub async fn update_voice_state( - channel_id: &str, - server_id: Option<&str>, + channel: &UserVoiceChannel, user_id: &str, partial: &PartialUserVoiceState, ) -> Result<()> { - let unique_key = format!("{}:{}", &user_id, server_id.unwrap_or(channel_id)); + let unique_key = format!( + "{}:{}", + &user_id, + channel.server_id.as_ref().unwrap_or(&channel.id) + ); let mut pipeline = Pipeline::new(); @@ -321,21 +338,24 @@ pub async fn update_voice_state( .to_internal_error() } -pub async fn get_voice_channel_members(channel_id: &str) -> Result>> { +pub async fn get_voice_channel_members(channel: &UserVoiceChannel) -> Result>> { get_connection() .await? - .smembers::<_, Option>>(format!("vc_members:{channel_id}")) + .smembers::<_, Option>>(format!("vc_members:{}", &channel.id)) .await .to_internal_error() .map(|opt| opt.and_then(|v| if v.is_empty() { None } else { Some(v) })) } pub async fn get_voice_state( - channel_id: &str, - server_id: Option<&str>, + channel: &UserVoiceChannel, user_id: &str, ) -> Result> { - let unique_key = format!("{}:{}", user_id, server_id.unwrap_or(channel_id)); + let unique_key = format!( + "{}:{}", + &user_id, + channel.server_id.as_ref().unwrap_or(&channel.id) + ); let (joined_at, is_publishing, is_receiving, screensharing, camera) = get_connection() .await? @@ -376,21 +396,21 @@ pub async fn get_voice_state( } } -pub async fn get_channel_voice_state(channel: &Channel) -> Result> { - let members = get_voice_channel_members(channel.id()).await?; - - let server = channel.server(); +pub async fn get_channel_voice_state( + channel: &UserVoiceChannel, +) -> Result> { + let members = get_voice_channel_members(channel).await?; if let Some(members) = members { let mut participants = Vec::with_capacity(members.len()); for user_id in members { - if let Some(voice_state) = get_voice_state(channel.id(), server, &user_id).await? { + if let Some(voice_state) = get_voice_state(channel, &user_id).await? { participants.push(voice_state); } else { log::info!("Voice state not found but member in voice channel members, removing."); - delete_voice_state(channel.id(), server, &user_id).await?; + delete_voice_state(channel, &user_id).await?; } } @@ -398,7 +418,7 @@ pub async fn get_channel_voice_state(channel: &Channel) -> Result Result Result<()> { +pub async fn move_user(user: &str, from_channel_id: &str, to_channel_id: &str) -> Result<()> { get_connection() .await? .smove( - format!("vc-members-{from}"), - format!("vc-members-{to}"), + format!("vc_members:{from_channel_id}"), + format!("vc_members:{to_channel_id}"), user, ) .await @@ -425,11 +445,13 @@ pub async fn sync_voice_permissions( server: Option<&Server>, role_id: Option<&str>, ) -> Result<()> { + let user_voice_channel = UserVoiceChannel::from_channel(channel); + let Some(node) = get_channel_node(channel.id()).await? else { return Ok(()); }; - for user_id in get_voice_channel_members(channel.id()) + for user_id in get_voice_channel_members(&user_voice_channel) .await? .iter() .flatten() @@ -469,7 +491,9 @@ pub async fn sync_user_voice_permissions( .as_ref() .is_none_or(|member| member.roles.iter().any(|r| r == role_id)) }) { - let Some(voice_state) = get_voice_state(channel_id, server_id, &user.id).await? else { + let user_voice_channel = UserVoiceChannel::from_channel(channel); + + let Some(voice_state) = get_voice_state(&user_voice_channel, &user.id).await? else { return Ok(()); }; @@ -500,7 +524,7 @@ pub async fn sync_user_voice_permissions( update_event.screensharing = voice_state.screensharing.then_some(can_video); update_event.is_publishing = voice_state.is_publishing.then_some(can_speak); - update_voice_state(channel_id, server_id, &user.id, &update_event).await?; + update_voice_state(&user_voice_channel, &user.id, &update_event).await?; voice_client .update_permissions( @@ -579,46 +603,94 @@ pub async fn get_call_notification_recipients( } pub async fn remove_user_from_voice_channels( - db: &Database, voice_client: &VoiceClient, user_id: &str, ) -> Result<()> { - for channel_id in get_user_voice_channels(user_id).await? { - remove_user_from_voice_channel(db, voice_client, &channel_id, user_id).await?; + for channel in get_user_voice_channels(user_id).await? { + remove_user_from_voice_channel(voice_client, &channel, user_id).await?; } Ok(()) } pub async fn remove_user_from_voice_channel( - db: &Database, voice_client: &VoiceClient, - channel_id: &str, + channel: &UserVoiceChannel, user_id: &str, ) -> Result<()> { - if let Some(node) = get_channel_node(channel_id).await? { - let _ = voice_client.remove_user(&node, user_id, channel_id).await; + if let Some(node) = get_channel_node(&channel.id).await? { + let _ = voice_client.remove_user(&node, user_id, &channel.id).await; } - let channel = Reference::from_unchecked(channel_id).as_channel(db).await?; - - delete_voice_state(channel_id, channel.server(), user_id).await?; + delete_voice_state(channel, user_id).await?; Ok(()) } pub async fn delete_voice_channel( voice_client: &VoiceClient, - channel_id: &str, - server_id: Option<&str>, + channel: &UserVoiceChannel, ) -> Result<()> { - if let Some(users) = get_voice_channel_members(channel_id).await? { - let node = get_channel_node(channel_id).await?.unwrap(); - - voice_client.delete_room(&node, channel_id).await?; + if let Some(users) = get_voice_channel_members(channel).await? { + let node = get_channel_node(&channel.id).await?.unwrap(); + voice_client.delete_room(&node, &channel.id).await?; - delete_channel_voice_state(channel_id, server_id, &users).await?; + delete_channel_voice_state(channel, &users).await?; }; Ok(()) } + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct RoomMetadata { + pub server: Option, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct UserVoiceChannel { + pub id: String, + pub server_id: Option, +} + +impl UserVoiceChannel { + pub fn from_string(input: String) -> Self { + let mut parts = input.splitn(2, '-'); + + Self { + id: parts.next().unwrap().to_string(), + server_id: parts.next().map(ToString::to_string), + } + } + + pub fn from_channel(channel: &Channel) -> Self { + Self { + id: channel.id().to_string(), + server_id: channel.server().map(ToString::to_string), + } + } +} + +impl Display for UserVoiceChannel { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(&self.id)?; + + if let Some(server_id) = &self.server_id { + f.write_char('-')?; + f.write_str(server_id)? + }; + + Ok(()) + } +} + +impl ToRedisArgs for UserVoiceChannel { + fn write_redis_args(&self, out: &mut W) { + out.write_arg_fmt(self); + } +} + +impl FromRedisValue for UserVoiceChannel { + fn from_redis_value(v: &Value) -> Result { + String::from_redis_value(v).map(UserVoiceChannel::from_string) + } +} diff --git a/crates/core/database/src/voice/voice_client.rs b/crates/core/database/src/voice/voice_client.rs index 967f3fefc..94d1f22bb 100644 --- a/crates/core/database/src/voice/voice_client.rs +++ b/crates/core/database/src/voice/voice_client.rs @@ -1,5 +1,6 @@ use crate::{ models::{Channel, User}, + voice::RoomMetadata, Database, }; use livekit_api::{ @@ -102,11 +103,16 @@ impl VoiceClient { pub async fn create_room(&self, node: &str, channel: &Channel) -> Result { let room = self.get_node(node)?; + let metadata = RoomMetadata { + server: channel.server().map(|id| id.to_string()), + }; + room.client .create_room( channel.id(), CreateRoomOptions { empty_timeout: 5 * 60, // 5 minutes, + metadata: serde_json::to_string(&metadata).to_internal_error()?, ..Default::default() }, ) diff --git a/crates/daemons/voice-ingress/src/api.rs b/crates/daemons/voice-ingress/src/api.rs index 56e5b2f73..dbe8934e6 100644 --- a/crates/daemons/voice-ingress/src/api.rs +++ b/crates/daemons/voice-ingress/src/api.rs @@ -5,8 +5,9 @@ use revolt_database::{ iso8601_timestamp::{Duration, Timestamp}, util::reference::Reference, voice::{ - create_voice_state, delete_channel_node, delete_voice_state, get_user_moved_from_voice, - get_user_moved_to_voice, get_voice_channel_members, update_voice_state_tracks, VoiceClient, + create_voice_state, delete_channel_voice_state, delete_voice_state, + get_user_moved_from_voice, get_user_moved_to_voice, update_voice_state_tracks, + RoomMetadata, UserVoiceChannel, VoiceClient, }, Database, AMQP, }; @@ -50,27 +51,34 @@ pub async fn ingress( let channel_id = event.room.as_ref().map(|r| &r.name); let user_id = event.participant.as_ref().map(|r| &r.identity); + let room_metadata = if let Some(room) = event.room.as_ref() { + Some(serde_json::from_str::(&room.metadata).to_internal_error()?) + } else { + None + }; match event.event.as_str() { // User joined a channel "participant_joined" => { let channel_id = channel_id.to_internal_error()?; let user_id = user_id.to_internal_error()?; - - let channel = Reference::from_unchecked(channel_id).as_channel(db).await?; + let server_id = room_metadata.to_internal_error()?.server; + let channel = UserVoiceChannel { + id: channel_id.clone(), + server_id: server_id.clone(), + }; let joined_at = Timestamp::UNIX_EPOCH .checked_add(Duration::seconds(event.created_at)) .unwrap(); - let voice_state = - create_voice_state(channel_id, channel.server(), user_id, joined_at).await?; + let voice_state = create_voice_state(&channel, user_id, joined_at).await?; // Only publish one event when a user is moved from one channel to another. if let Some(moved_from) = get_user_moved_to_voice(channel_id, user_id).await? { EventV1::VoiceChannelMove { user: user_id.to_string(), - from: moved_from, + from: moved_from.id, to: channel_id.to_string(), state: voice_state, } @@ -135,10 +143,13 @@ pub async fn ingress( "participant_left" => { let channel_id = channel_id.to_internal_error()?; let user_id = user_id.to_internal_error()?; + let server_id = room_metadata.to_internal_error()?.server; + let channel = UserVoiceChannel { + id: channel_id.clone(), + server_id: server_id.clone(), + }; - let channel = Reference::from_unchecked(channel_id).as_channel(db).await?; - - delete_voice_state(channel_id, channel.server(), user_id).await?; + delete_voice_state(&channel, user_id).await?; // Dont send leave event when a user is moved if get_user_moved_from_voice(channel_id, user_id) @@ -159,8 +170,6 @@ pub async fn ingress( // let members = get_voice_channel_members(channel_id).await?; // if members.is_none_or(|m| m.is_empty()) { - // delete_channel_node(channel_id).await?; - // // // The channel is empty so send out an "end" message for ringing // if let Err(e) = amqp // .dm_call_updated(user_id, channel_id, None, true, None) @@ -204,8 +213,11 @@ pub async fn ingress( let channel_id = channel_id.to_internal_error()?; let user_id = user_id.to_internal_error()?; let track = event.track.as_ref().to_internal_error()?; - - let channel = Reference::from_unchecked(channel_id).as_channel(db).await?; + let server_id = room_metadata.to_internal_error()?.server; + let channel = UserVoiceChannel { + id: channel_id.clone(), + server_id: server_id.clone(), + }; let user = Reference::from_unchecked(user_id).as_user(db).await?; @@ -245,15 +257,14 @@ pub async fn ingress( log::debug!("Removing user {user_id} from channel {channel_id} {event:?} due to forbidden track."); let _ = voice_client.remove_user(node, user_id, channel_id).await; - delete_voice_state(channel_id, channel.server(), user_id).await?; + delete_voice_state(&channel, user_id).await?; return Ok(EmptyResponse); }; }; let partial = update_voice_state_tracks( - channel_id, - channel.server(), + &channel, user_id, event.event == "track_published" || event.event == "track_unmuted", // to avoid duplicating this entire case twice track.source, @@ -268,6 +279,16 @@ pub async fn ingress( .p(channel_id.clone()) .await; } + "room_finished" => { + let channel_id = channel_id.to_internal_error()?; + let server_id = room_metadata.to_internal_error()?.server; + let channel = UserVoiceChannel { + id: channel_id.clone(), + server_id: server_id.clone(), + }; + + delete_channel_voice_state(&channel, &[]).await?; + } _ => {} }; diff --git a/crates/delta/src/routes/bots/delete.rs b/crates/delta/src/routes/bots/delete.rs index 73a001569..11132f278 100644 --- a/crates/delta/src/routes/bots/delete.rs +++ b/crates/delta/src/routes/bots/delete.rs @@ -1,4 +1,8 @@ -use revolt_database::{Database, User, util::reference::Reference, voice::{VoiceClient, remove_user_from_voice_channels}}; +use revolt_database::{ + util::reference::Reference, + voice::{remove_user_from_voice_channels, VoiceClient}, + Database, User, +}; use revolt_result::{create_error, Result}; use rocket::State; use rocket_empty::EmptyResponse; @@ -21,7 +25,7 @@ pub async fn delete_bot( bot.delete(db).await?; - remove_user_from_voice_channels(db, voice_client, &bot.id).await?; + remove_user_from_voice_channels(voice_client, &bot.id).await?; Ok(EmptyResponse) } diff --git a/crates/delta/src/routes/channels/channel_delete.rs b/crates/delta/src/routes/channels/channel_delete.rs index f6cc8b75a..82ed41373 100644 --- a/crates/delta/src/routes/channels/channel_delete.rs +++ b/crates/delta/src/routes/channels/channel_delete.rs @@ -1,7 +1,10 @@ use revolt_database::{ - AMQP, Channel, Database, PartialChannel, User, util::{permissions::DatabasePermissionQuery, reference::Reference}, voice::{ - VoiceClient, delete_voice_channel, is_in_voice_channel, remove_user_from_voice_channel - } + util::{permissions::DatabasePermissionQuery, reference::Reference}, + voice::{ + delete_voice_channel, is_in_voice_channel, remove_user_from_voice_channel, + UserVoiceChannel, VoiceClient, + }, + Channel, Database, PartialChannel, User, AMQP, }; use revolt_models::v0; use revolt_permissions::{calculate_channel_permissions, ChannelPermission}; @@ -54,15 +57,17 @@ pub async fn delete( ) .await?; - if is_in_voice_channel(&user.id, channel.id()).await? { - remove_user_from_voice_channel(db, voice_client, channel.id(), &user.id).await?; + let user_voice_channel = UserVoiceChannel::from_channel(&channel); + + if is_in_voice_channel(&user.id, &user_voice_channel).await? { + remove_user_from_voice_channel(voice_client, &user_voice_channel, &user.id).await?; }; } Channel::TextChannel { .. } => { permissions.throw_if_lacking_channel_permission(ChannelPermission::ManageChannel)?; channel.delete(db).await?; - delete_voice_channel(voice_client, channel.id(), channel.server()).await?; + delete_voice_channel(voice_client, &UserVoiceChannel::from_channel(&channel)).await?; } }; diff --git a/crates/delta/src/routes/channels/channel_edit.rs b/crates/delta/src/routes/channels/channel_edit.rs index 64b3b06a4..e60664e01 100644 --- a/crates/delta/src/routes/channels/channel_edit.rs +++ b/crates/delta/src/routes/channels/channel_edit.rs @@ -1,6 +1,6 @@ use revolt_database::{ util::{permissions::DatabasePermissionQuery, reference::Reference}, - voice::{delete_voice_channel, VoiceClient}, + voice::{delete_voice_channel, UserVoiceChannel, VoiceClient}, Channel, Database, File, PartialChannel, SystemMessage, User, AMQP, }; use revolt_models::v0; @@ -260,7 +260,7 @@ pub async fn edit( .await?; if channel.voice().is_none() { - delete_voice_channel(voice_client, channel.id(), channel.server()).await?; + delete_voice_channel(voice_client, &UserVoiceChannel::from_channel(&channel)).await?; } Ok(Json(channel.into())) diff --git a/crates/delta/src/routes/channels/group_remove_member.rs b/crates/delta/src/routes/channels/group_remove_member.rs index 995991f9a..083bb44ed 100644 --- a/crates/delta/src/routes/channels/group_remove_member.rs +++ b/crates/delta/src/routes/channels/group_remove_member.rs @@ -1,7 +1,5 @@ use revolt_database::{ - util::reference::Reference, - voice::{is_in_voice_channel, remove_user_from_voice_channel, VoiceClient}, - Channel, Database, User, AMQP, + AMQP, Channel, Database, User, util::reference::Reference, voice::{UserVoiceChannel, VoiceClient, is_in_voice_channel, remove_user_from_voice_channel} }; use revolt_permissions::ChannelPermission; use revolt_result::{create_error, Result}; @@ -54,8 +52,10 @@ pub async fn remove_member( return Err(create_error!(InvalidOperation)); }; - if is_in_voice_channel(&member.id, channel.id()).await? { - remove_user_from_voice_channel(db, voice_client, channel.id(), &member.id).await?; + let user_voice_channel = UserVoiceChannel::from_channel(&channel); + + if is_in_voice_channel(member.id, &user_voice_channel).await? { + remove_user_from_voice_channel(voice_client, &user_voice_channel, member.id).await?; }; Ok(EmptyResponse) diff --git a/crates/delta/src/routes/channels/voice_join.rs b/crates/delta/src/routes/channels/voice_join.rs index fe585f6f7..0d8aecddd 100644 --- a/crates/delta/src/routes/channels/voice_join.rs +++ b/crates/delta/src/routes/channels/voice_join.rs @@ -3,7 +3,8 @@ use revolt_database::{ util::{permissions::perms, reference::Reference}, voice::{ delete_voice_state, get_channel_node, get_user_voice_channels, get_voice_channel_members, - raise_if_in_voice, set_call_notification_recipients, set_channel_node, VoiceClient, + raise_if_in_voice, set_call_notification_recipients, set_channel_node, UserVoiceChannel, + VoiceClient, }, Database, User, }; @@ -50,7 +51,9 @@ pub async fn call( let current_permissions = calculate_channel_permissions(&mut permissions).await; current_permissions.throw_if_lacking_channel_permission(ChannelPermission::Connect)?; - if get_voice_channel_members(channel.id()) + let user_voice_channel = UserVoiceChannel::from_channel(&channel); + + if get_voice_channel_members(&user_voice_channel) .await? .zip(voice_info.max_users) .is_some_and(|(ms, max_users)| ms.len() >= max_users) @@ -79,22 +82,18 @@ pub async fn call( // Finds and disconnects any existing voice connections by the user, // should only ever loop once but just to cover our backs. - for channel_id in get_user_voice_channels(&user.id).await? { - if let Some(node) = get_channel_node(&channel_id).await? { + for previous_channel in get_user_voice_channels(&user.id).await? { + if let Some(node) = get_channel_node(&previous_channel.id).await? { // if this errors its just a mismatching state - ignore and proceed to still delete our state - let _ = voice_client.remove_user(&node, &user.id, &channel_id).await; + let _ = voice_client + .remove_user(&node, &user.id, &previous_channel.id) + .await; }; - let channel = Reference::from_unchecked(&channel_id) - .as_channel(db) - .await; - - if channel.is_ok() { - delete_voice_state(&channel_id, channel.unwrap().server(), &user.id).await?; - } + delete_voice_state(&previous_channel, &user.id).await?; } } else { - raise_if_in_voice(&user, channel.id()).await?; + raise_if_in_voice(&user, &user_voice_channel).await?; } let token = voice_client diff --git a/crates/delta/src/routes/channels/voice_stop_ring.rs b/crates/delta/src/routes/channels/voice_stop_ring.rs index f8db8fc44..768b861a3 100644 --- a/crates/delta/src/routes/channels/voice_stop_ring.rs +++ b/crates/delta/src/routes/channels/voice_stop_ring.rs @@ -1,6 +1,6 @@ use revolt_database::{ util::reference::Reference, - voice::{get_voice_state, VoiceClient}, + voice::{get_voice_state, UserVoiceChannel, VoiceClient}, Channel, Database, User, AMQP, }; use revolt_result::{create_error, Result, ToRevoltError}; @@ -32,9 +32,15 @@ pub async fn stop_ring( return Err(create_error!(NoEffect)); } - if get_voice_state(channel.id(), None, &user.id) - .await? - .is_none() + if get_voice_state( + &UserVoiceChannel { + id: channel.id().to_string(), + server_id: None, + }, + &user.id, + ) + .await? + .is_none() { return Err(create_error!(NotConnected)); } @@ -46,7 +52,7 @@ pub async fn stop_ring( _ => return Err(create_error!(NoEffect)), }; - if members.iter().any(|m| &target_user.id == m) { + if members.iter().any(|m| target_user.id == m) { if let Err(e) = amqp .dm_call_updated( &user.id, diff --git a/crates/delta/src/routes/servers/ban_create.rs b/crates/delta/src/routes/servers/ban_create.rs index 17589dad2..4ff103299 100644 --- a/crates/delta/src/routes/servers/ban_create.rs +++ b/crates/delta/src/routes/servers/ban_create.rs @@ -1,6 +1,9 @@ use revolt_database::{ util::{permissions::DatabasePermissionQuery, reference::Reference}, - voice::{get_user_voice_channel_in_server, remove_user_from_voice_channel, VoiceClient}, + voice::{ + get_user_voice_channel_in_server, remove_user_from_voice_channel, UserVoiceChannel, + VoiceClient, + }, Database, RemovalIntention, ServerBan, User, }; use revolt_models::v0; @@ -58,8 +61,16 @@ pub async fn ban( .await?; // If the member is in a voice channel while banned kick them from the voice channel - if let Some(channel_id) = get_user_voice_channel_in_server(&target.id, &server.id).await? { - remove_user_from_voice_channel(db, voice_client, &channel_id, &target.id).await?; + if let Some(channel_id) = get_user_voice_channel_in_server(target.id, &server.id).await? { + remove_user_from_voice_channel( + voice_client, + &UserVoiceChannel { + id: channel_id, + server_id: Some(server.id.clone()), + }, + target.id, + ) + .await?; } } diff --git a/crates/delta/src/routes/servers/member_edit.rs b/crates/delta/src/routes/servers/member_edit.rs index ecc1d919d..9c6a1d589 100644 --- a/crates/delta/src/routes/servers/member_edit.rs +++ b/crates/delta/src/routes/servers/member_edit.rs @@ -9,7 +9,7 @@ use revolt_database::{ voice::{ get_channel_node, get_user_voice_channel_in_server, set_channel_node, set_user_moved_from_voice, set_user_moved_to_voice, sync_user_voice_permissions, - VoiceClient, + UserVoiceChannel, VoiceClient, }, Database, File, PartialMember, User, }; @@ -52,7 +52,9 @@ pub async fn edit( let permissions = calculate_server_permissions(&mut query).await; // Fetch target permissions - let mut target_query = DatabasePermissionQuery::new(db, &target_user).server(&server).member(&member); + let mut target_query = DatabasePermissionQuery::new(db, &target_user) + .server(&server) + .member(&member); let target_permissions = calculate_server_permissions(&mut target_query).await; // Check permissions in server @@ -83,7 +85,7 @@ pub async fn edit( } if target_permissions.has_channel_permission(ChannelPermission::TimeoutMembers) { - return Err(create_error!(IsElevated)) + return Err(create_error!(IsElevated)); } } @@ -99,7 +101,7 @@ pub async fn edit( } if data.voice_channel.is_some() && data.remove.contains(&FieldsMember::VoiceChannel) { - return Err(create_error!(InvalidOperation)) + return Err(create_error!(InvalidOperation)); } if data.voice_channel.is_some() || data.remove.contains(&FieldsMember::VoiceChannel) { @@ -217,8 +219,19 @@ pub async fn edit( } }; - set_user_moved_from_voice(&channel, new_voice_channel.id(), &target_user.id).await?; - set_user_moved_to_voice(new_voice_channel.id(), &channel, &target_user.id).await?; + let new_user_voice_channel = UserVoiceChannel::from_channel(&new_voice_channel); + let old_user_voice_channel = UserVoiceChannel { + id: channel.clone(), + server_id: new_user_voice_channel.server_id.clone(), + }; + + set_user_moved_from_voice(&channel, &new_user_voice_channel, &target_user.id).await?; + set_user_moved_to_voice( + new_voice_channel.id(), + &old_user_voice_channel, + &target_user.id, + ) + .await?; let mut query = perms(db, &target_user).channel(&new_voice_channel); let permissions = calculate_channel_permissions(&mut query).await; diff --git a/crates/delta/src/routes/servers/member_remove.rs b/crates/delta/src/routes/servers/member_remove.rs index 510da42ed..de5b02541 100644 --- a/crates/delta/src/routes/servers/member_remove.rs +++ b/crates/delta/src/routes/servers/member_remove.rs @@ -1,6 +1,9 @@ use revolt_database::{ util::{permissions::DatabasePermissionQuery, reference::Reference}, - voice::{get_user_voice_channel_in_server, remove_user_from_voice_channel, VoiceClient}, + voice::{ + get_user_voice_channel_in_server, remove_user_from_voice_channel, UserVoiceChannel, + VoiceClient, + }, Database, RemovalIntention, User, }; use revolt_permissions::{calculate_server_permissions, ChannelPermission}; @@ -46,8 +49,16 @@ pub async fn kick( .remove(db, &server, RemovalIntention::Kick, false) .await?; - if let Some(channel_id) = get_user_voice_channel_in_server(&target.id, &server.id).await? { - remove_user_from_voice_channel(db, voice_client, &channel_id, &target.id).await?; + if let Some(channel_id) = get_user_voice_channel_in_server(target.id, &server.id).await? { + remove_user_from_voice_channel( + voice_client, + &UserVoiceChannel { + id: channel_id, + server_id: Some(server.id.clone()), + }, + target.id, + ) + .await?; }; Ok(EmptyResponse) diff --git a/crates/delta/src/routes/servers/server_delete.rs b/crates/delta/src/routes/servers/server_delete.rs index 475765ca1..b99f172bf 100644 --- a/crates/delta/src/routes/servers/server_delete.rs +++ b/crates/delta/src/routes/servers/server_delete.rs @@ -2,7 +2,7 @@ use revolt_database::{ util::reference::Reference, voice::{ delete_voice_channel, get_user_voice_channel_in_server, remove_user_from_voice_channel, - VoiceClient, + UserVoiceChannel, VoiceClient, }, Database, RemovalIntention, User, }; @@ -29,13 +29,28 @@ pub async fn delete( if server.owner == user.id { for channel_id in &server.channels { - delete_voice_channel(voice_client, channel_id, Some(&server.id)).await?; + delete_voice_channel( + voice_client, + &UserVoiceChannel { + id: channel_id.clone(), + server_id: Some(server.id.clone()), + }, + ) + .await?; } server.delete(db).await } else { if let Some(channel_id) = get_user_voice_channel_in_server(&user.id, &server.id).await? { - remove_user_from_voice_channel(db, voice_client, &channel_id, &user.id).await?; + remove_user_from_voice_channel( + voice_client, + &UserVoiceChannel { + id: channel_id, + server_id: Some(server.id.clone()), + }, + &user.id, + ) + .await?; }; member From 52c0d2f266b76d8975bba2d5e75c62bb30149c45 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 11 Mar 2026 05:15:00 +0700 Subject: [PATCH 105/211] fix: send push notifications for DM and group messages (#660) DMs and group messages never triggered push notifications because the condition only checked for explicit @mentions. DMs don't use mentions, so users were never notified of new direct messages. Signed-off-by: sanasol --- crates/core/database/src/models/messages/model.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/crates/core/database/src/models/messages/model.rs b/crates/core/database/src/models/messages/model.rs index 11bc2eacf..2db57b12e 100644 --- a/crates/core/database/src/models/messages/model.rs +++ b/crates/core/database/src/models/messages/model.rs @@ -687,8 +687,13 @@ impl Message { ) .await?; + let is_dm_or_group = matches!( + channel, + Channel::DirectMessage { .. } | Channel::Group { .. } + ); + if !self.has_suppressed_notifications() - && (self.mentions.is_some() || self.contains_mass_push_mention()) + && (is_dm_or_group || self.mentions.is_some() || self.contains_mass_push_mention()) { // send Push notifications #[cfg(feature = "tasks")] From d56135e0cbc713884c9378832952f7ad490fa315 Mon Sep 17 00:00:00 2001 From: Christopher Hultin Date: Tue, 10 Mar 2026 16:38:41 -0600 Subject: [PATCH 106/211] fix: Check for appropriate permission for removing other users avatar (#657) * Check for appropriate permission for removing other users avatar Signed-off-by: Chris Hultin * limit check for non-self to just removal Signed-off-by: Chris Hultin * else if change Signed-off-by: Chris Hultin --------- Signed-off-by: Chris Hultin --- crates/delta/src/routes/servers/member_edit.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/delta/src/routes/servers/member_edit.rs b/crates/delta/src/routes/servers/member_edit.rs index 9c6a1d589..87b455243 100644 --- a/crates/delta/src/routes/servers/member_edit.rs +++ b/crates/delta/src/routes/servers/member_edit.rs @@ -15,9 +15,7 @@ use revolt_database::{ }; use revolt_models::v0::{self, FieldsMember}; -use revolt_permissions::{ - calculate_channel_permissions, calculate_server_permissions, ChannelPermission, -}; +use revolt_permissions::{calculate_channel_permissions, calculate_server_permissions, ChannelPermission, UserPermission}; use revolt_result::{create_error, Result}; use rocket::{form::validate::Contains, serde::json::Json, State}; use validator::Validate; @@ -69,8 +67,10 @@ pub async fn edit( if data.avatar.is_some() || data.remove.contains(&v0::FieldsMember::Avatar) { if user.id == member.id.user { permissions.throw_if_lacking_channel_permission(ChannelPermission::ChangeAvatar)?; + } else if data.remove.contains(&v0::FieldsMember::Avatar) { + permissions.throw_if_lacking_channel_permission(ChannelPermission::RemoveAvatars)?; } else { - return Err(create_error!(InvalidOperation)); + return Err(create_error!(InvalidOperation)) } } From ab525699bd6663333f0e9fed6d2455e482e6a09f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0spik?= Date: Sat, 14 Mar 2026 10:41:31 +0300 Subject: [PATCH 107/211] fix: add masquerade permission to default direct message settings (#665) Signed-off-by: arsabutispik --- crates/core/permissions/src/models/channel.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/core/permissions/src/models/channel.rs b/crates/core/permissions/src/models/channel.rs index 9e9160263..450fda64c 100644 --- a/crates/core/permissions/src/models/channel.rs +++ b/crates/core/permissions/src/models/channel.rs @@ -141,7 +141,7 @@ pub static DEFAULT_PERMISSION: Lazy = Lazy::new(|| { pub static DEFAULT_PERMISSION_SAVED_MESSAGES: u64 = ChannelPermission::GrantAllSafe as u64; pub static DEFAULT_PERMISSION_DIRECT_MESSAGE: Lazy = Lazy::new(|| { - DEFAULT_PERMISSION.add(ChannelPermission::ManageChannel + ChannelPermission::React) + DEFAULT_PERMISSION.add(ChannelPermission::ManageChannel + ChannelPermission::React + ChannelPermission::Masquerade) }); pub static DEFAULT_PERMISSION_SERVER: Lazy = Lazy::new(|| { From f2fc1ee00c229c2cddd61d62a7a9cfd9b414be32 Mon Sep 17 00:00:00 2001 From: Damocles <106018783+Damocles078@users.noreply.github.com> Date: Sat, 14 Mar 2026 08:53:51 +0100 Subject: [PATCH 108/211] docs: documentation generation (#575) Signed-off-by: Damocles078 --- docs/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/README.md b/docs/README.md index b28211a9b..a31d8713e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -5,13 +5,13 @@ This website is built using [Docusaurus](https://docusaurus.io/), a modern stati ## Installation ```bash -yarn +pnpm install ``` ## Local Development ```bash -yarn start +pnpm start ``` This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. @@ -19,7 +19,7 @@ This command starts a local development server and opens up a browser window. Mo ## Build ```bash -yarn build +pnpm build ``` This command generates static content into the `build` directory and can be served using any static contents hosting service. @@ -29,13 +29,13 @@ This command generates static content into the `build` directory and can be serv Using SSH: ```bash -USE_SSH=true yarn deploy +USE_SSH=true pnpm run deploy ``` Not using SSH: ```bash -GIT_USER= yarn deploy +GIT_USER= pnpm run deploy ``` If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. From dc4438bc3c7b2cad8d442b3cd438afb9ed566a5e Mon Sep 17 00:00:00 2001 From: Tom Date: Sun, 15 Mar 2026 09:04:37 -0700 Subject: [PATCH 109/211] fix: uname is missing from crond (#675) Signed-off-by: IAmTomahawkx --- crates/core/config/src/lib.rs | 4 +++- crates/daemons/crond/Dockerfile | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/core/config/src/lib.rs b/crates/core/config/src/lib.rs index 7e26fb20f..391b97a3d 100644 --- a/crates/core/config/src/lib.rs +++ b/crates/core/config/src/lib.rs @@ -454,7 +454,9 @@ pub async fn config() -> Settings { } // auto-detect production nodes - if config.hosts.api.contains("https") && config.hosts.api.contains("revolt.chat") { + if config.hosts.api.contains("https") + && (config.hosts.api.contains("revolt.chat") | config.hosts.api.contains("stoat.chat")) + { config.production = true; } diff --git a/crates/daemons/crond/Dockerfile b/crates/daemons/crond/Dockerfile index c1bdf80f5..f18524573 100644 --- a/crates/daemons/crond/Dockerfile +++ b/crates/daemons/crond/Dockerfile @@ -5,6 +5,7 @@ FROM debian:12 AS debian # Bundle Stage FROM gcr.io/distroless/cc-debian12:nonroot COPY --from=builder /home/rust/src/target/release/revolt-crond ./ +COPY --from=debian /usr/bin/uname /usr/bin/uname USER nonroot CMD ["./revolt-crond"] \ No newline at end of file From 5701b5c18c513f796af365169ceaea372a22638c Mon Sep 17 00:00:00 2001 From: Tom Date: Sun, 15 Mar 2026 09:15:54 -0700 Subject: [PATCH 110/211] fix: don't use a bitop for OR (#676) * fix: uname is missing from crond Signed-off-by: IAmTomahawkx * fix: don't use a bitop lol, two of us missed that. --------- Signed-off-by: IAmTomahawkx --- crates/core/config/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/core/config/src/lib.rs b/crates/core/config/src/lib.rs index 391b97a3d..5edf24c2d 100644 --- a/crates/core/config/src/lib.rs +++ b/crates/core/config/src/lib.rs @@ -455,7 +455,7 @@ pub async fn config() -> Settings { // auto-detect production nodes if config.hosts.api.contains("https") - && (config.hosts.api.contains("revolt.chat") | config.hosts.api.contains("stoat.chat")) + && (config.hosts.api.contains("revolt.chat") || config.hosts.api.contains("stoat.chat")) { config.production = true; } From 2547fc6cd3533cd9b2342d65c49b955fe036293f Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Sun, 22 Mar 2026 14:02:58 +0000 Subject: [PATCH 111/211] docs: add LLM policy to contrib.md (#683) --- docs/docs/developing/contrib.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/docs/developing/contrib.md b/docs/docs/developing/contrib.md index 39520b513..565f92eae 100644 --- a/docs/docs/developing/contrib.md +++ b/docs/docs/developing/contrib.md @@ -12,14 +12,18 @@ This is the contribution guide for developers wanting to help out with Stoat. - Sign-off your commits ([Git flag](https://git-scm.com/docs/git-commit#Documentation/git-commit.txt---signoff)), [read here about DCO obligations](https://developercertificate.org/). - Sign commits where possible, [learn more about that here](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits). -- Prefer to use [Conventional Commit style](https://www.conventionalcommits.org/en/v1.0.0-beta.2/). +- Prefer using [Conventional Commit style](https://www.conventionalcommits.org/en/v1.0.0-beta.2/). - If present, e.g. `prettier`, `cargo fmt`, use the formatter. - Try to keep each PR bound to a single feature or change, multiple bug fixes may be fine in some cases. This is to avoid your PR getting stuck due to parts of it having conflicts or other issues. ### Merging Pull Requests -All PR titles must use use [Conventional Commit style](https://www.conventionalcommits.org/en/v1.0.0-beta.2/) and will be squash merged! +All PR titles must use use [Conventional Commit style](https://www.conventionalcommits.org/en/v1.0.0-beta.2/) and will be squash merged. + +### Use of generative AI + +Please do not open PRs generated with LLMs. ## What can I help with? From 5191bd16b2a905b8409838e34eb0baca96f08580 Mon Sep 17 00:00:00 2001 From: Nico <53304086+thisguyStan@users.noreply.github.com> Date: Mon, 23 Mar 2026 04:33:01 +0100 Subject: [PATCH 112/211] feat: load config from env vars (#576) Signed-off-by: Nico --- crates/core/config/src/lib.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/core/config/src/lib.rs b/crates/core/config/src/lib.rs index 5edf24c2d..76a6b2e11 100644 --- a/crates/core/config/src/lib.rs +++ b/crates/core/config/src/lib.rs @@ -1,7 +1,7 @@ use std::{collections::HashMap, path::Path}; use cached::proc_macro::cached; -use config::{Config, File, FileFormat}; +use config::{Config, Environment, File, FileFormat}; use futures_locks::RwLock; use once_cell::sync::Lazy; use serde::Deserialize; @@ -109,6 +109,8 @@ static CONFIG_BUILDER: Lazy> = Lazy::new(|| { cwd = path.parent(); } + builder = builder.add_source(Environment::with_prefix("REVOLT").separator("__")); + builder.build().unwrap() }) }); From 3fa0abf47f5f42ddd8ee041fe4c44fbc5ba800c1 Mon Sep 17 00:00:00 2001 From: Erik LaBine Date: Mon, 23 Mar 2026 01:07:22 -0400 Subject: [PATCH 113/211] feat: Detect animation in image files for fetch_preview (#574) * Implement animated metadata TODOs for database and thumbnailing. Signed-off-by: Assisting * Run linter for code changes Signed-off-by: Assisting --------- Signed-off-by: Assisting --- .../database/src/models/file_hashes/model.rs | 3 +- crates/core/database/src/util/bridge/v0.rs | 14 ++- .../files/src/implementation/media_impl.rs | 85 ++++++++++++++++++- crates/core/files/src/lib.rs | 28 ++++++ .../src/repositories/media_repository.rs | 3 + crates/core/models/src/v0/files.rs | 8 +- crates/services/autumn/src/api.rs | 2 +- crates/services/autumn/src/exif.rs | 15 +++- crates/services/autumn/src/metadata.rs | 3 +- 9 files changed, 149 insertions(+), 12 deletions(-) diff --git a/crates/core/database/src/models/file_hashes/model.rs b/crates/core/database/src/models/file_hashes/model.rs index cec7a39db..756ce3d5c 100644 --- a/crates/core/database/src/models/file_hashes/model.rs +++ b/crates/core/database/src/models/file_hashes/model.rs @@ -45,7 +45,8 @@ auto_derived!( Image { width: isize, height: isize, - // animated: bool // TODO: https://docs.rs/image/latest/image/trait.AnimationDecoder.html for APNG support + #[serde(default)] + animated: bool, }, /// File is a video with specific dimensions Video { width: isize, height: isize }, diff --git a/crates/core/database/src/util/bridge/v0.rs b/crates/core/database/src/util/bridge/v0.rs index aafb23135..0b2a55ef8 100644 --- a/crates/core/database/src/util/bridge/v0.rs +++ b/crates/core/database/src/util/bridge/v0.rs @@ -406,9 +406,14 @@ impl From for Metadata { match value { crate::Metadata::File => Metadata::File, crate::Metadata::Text => Metadata::Text, - crate::Metadata::Image { width, height } => Metadata::Image { + crate::Metadata::Image { + width, + height, + animated, + } => Metadata::Image { width: width as usize, height: height as usize, + animated: animated as bool, }, crate::Metadata::Video { width, height } => Metadata::Video { width: width as usize, @@ -424,9 +429,14 @@ impl From for crate::Metadata { match value { Metadata::File => crate::Metadata::File, Metadata::Text => crate::Metadata::Text, - Metadata::Image { width, height } => crate::Metadata::Image { + Metadata::Image { + width, + height, + animated, + } => crate::Metadata::Image { width: width as isize, height: height as isize, + animated, }, Metadata::Video { width, height } => crate::Metadata::Video { width: width as isize, diff --git a/crates/core/files/src/implementation/media_impl.rs b/crates/core/files/src/implementation/media_impl.rs index 0f13be1c8..7a7fad848 100644 --- a/crates/core/files/src/implementation/media_impl.rs +++ b/crates/core/files/src/implementation/media_impl.rs @@ -1,5 +1,5 @@ use anyhow::Result; -use image::{DynamicImage, ImageBuffer, ImageReader}; +use image::{AnimationDecoder, DynamicImage, ImageBuffer, ImageReader}; use jxl_oxide::integration::JxlDecoder; use revolt_config::report_internal_error; use std::io::{BufRead, Read, Seek}; @@ -35,6 +35,31 @@ impl MediaRepository for MediaImpl { } } + fn is_animated(&self, f: &NamedTempFile, mime: &str) -> Option { + match mime { + // Current behaviour is to assume GIFs are animated, this checks for at least 2 frames + "image/gif" => { + let file = std::fs::File::open(f.path()).ok()?; + let reader = std::io::BufReader::new(file); + let decoder = image::codecs::gif::GifDecoder::new(reader).ok()?; + Some(decoder.into_frames().take(2).count() > 1) + } + "image/png" => { + let file = std::fs::File::open(f.path()).ok()?; + let reader = std::io::BufReader::new(file); + let decoder = image::codecs::png::PngDecoder::new(reader).ok()?; + decoder.is_apng().ok() + } + "image/webp" => { + let file = std::fs::File::open(f.path()).ok()?; + let reader = std::io::BufReader::new(file); + let decoder = image::codecs::webp::WebPDecoder::new(reader).ok()?; + Some(decoder.has_animation()) + } + _ => Some(false), + } + } + fn image_size_vec(&self, v: &[u8], mime: &str) -> Option<(usize, usize)> { match mime { "image/svg+xml" => { @@ -171,9 +196,9 @@ impl MediaRepository for MediaImpl { #[cfg(test)] mod tests { - use std::io::Cursor; - use crate::{MediaImpl, MediaRepository}; + use std::io::{Cursor, Write}; + use tempfile::NamedTempFile; #[tokio::test] async fn asset_test_jpeg() { @@ -186,6 +211,15 @@ mod tests { media.create_thumbnail(image, "attachments"); } + #[tokio::test] + async fn asset_test_jpeg_is_not_animated() { + let media = MediaImpl::from_config().await; + let mut f = NamedTempFile::new().unwrap(); + f.write_all(include_bytes!("../../tests/assets/test.jpeg")) + .unwrap(); + assert_eq!(media.is_animated(&f, "image/jpeg"), Some(false)); + } + #[tokio::test] async fn asset_test_jpeg_extra_bytes() { let media = MediaImpl::from_config().await; @@ -212,6 +246,15 @@ mod tests { media.create_thumbnail(image, "emojis"); } + #[tokio::test] + async fn asset_test_png_is_not_animated() { + let media = MediaImpl::from_config().await; + let mut f = NamedTempFile::new().unwrap(); + f.write_all(include_bytes!("../../tests/assets/test.png")) + .unwrap(); + assert_eq!(media.is_animated(&f, "image/png"), Some(false)); + } + #[tokio::test] async fn asset_test_png_extra_bytes() { let media = MediaImpl::from_config().await; @@ -259,6 +302,15 @@ mod tests { media.create_thumbnail(image, "attachments"); } + #[tokio::test] + async fn asset_test_animated_png_is_animated() { + let media = MediaImpl::from_config().await; + let mut f = NamedTempFile::new().unwrap(); + f.write_all(include_bytes!("../../tests/assets/anim-icos.apng")) + .unwrap(); + assert_eq!(media.is_animated(&f, "image/png"), Some(true)); + } + #[tokio::test] async fn asset_test_jxl() { let media = MediaImpl::from_config().await; @@ -292,6 +344,15 @@ mod tests { media.create_thumbnail(image, "attachments"); } + #[tokio::test] + async fn asset_test_webp_is_not_animated() { + let media = MediaImpl::from_config().await; + let mut f = NamedTempFile::new().unwrap(); + f.write_all(include_bytes!("../../tests/assets/dice.webp")) + .unwrap(); + assert_eq!(media.is_animated(&f, "image/webp"), Some(false)); + } + #[tokio::test] async fn asset_test_animated_webp() { let media = MediaImpl::from_config().await; @@ -303,6 +364,15 @@ mod tests { media.create_thumbnail(image, "attachments"); } + #[tokio::test] + async fn asset_test_animated_webp_is_animated() { + let media = MediaImpl::from_config().await; + let mut f = NamedTempFile::new().unwrap(); + f.write_all(include_bytes!("../../tests/assets/anim-icos.webp")) + .unwrap(); + assert_eq!(media.is_animated(&f, "image/webp"), Some(true)); + } + #[tokio::test] async fn asset_test_animated_gif() { let media = MediaImpl::from_config().await; @@ -313,4 +383,13 @@ mod tests { let image = media.decode_image(&mut reader, "image/gif").unwrap(); media.create_thumbnail(image, "attachments"); } + + #[tokio::test] + async fn asset_test_animated_gif_is_animated() { + let media = MediaImpl::from_config().await; + let mut f = NamedTempFile::new().unwrap(); + f.write_all(include_bytes!("../../tests/assets/anim-icos.gif")) + .unwrap(); + assert_eq!(media.is_animated(&f, "image/gif"), Some(true)); + } } diff --git a/crates/core/files/src/lib.rs b/crates/core/files/src/lib.rs index b1c0982d7..0f71f095c 100644 --- a/crates/core/files/src/lib.rs +++ b/crates/core/files/src/lib.rs @@ -91,6 +91,34 @@ pub fn image_size_vec(v: &[u8], mime: &str) -> Option<(usize, usize)> { media.image_size_vec(v, mime) } +/// Check whether an image file contains animation data +pub fn is_animated(f: &NamedTempFile, mime: &str) -> Option { + let media = MediaImpl::new(Files { + blocked_mime_types: Default::default(), + clamd_host: Default::default(), + encryption_key: Default::default(), + limit: FilesLimit { + max_mega_pixels: 0, + max_pixel_side: 0, + min_file_size: 0, + min_resolution: [0, 0], + }, + preview: Default::default(), + s3: FilesS3 { + access_key_id: Default::default(), + default_bucket: Default::default(), + endpoint: Default::default(), + path_style_buckets: Default::default(), + region: Default::default(), + secret_access_key: Default::default(), + }, + scan_mime_types: Default::default(), + webp_quality: Default::default(), + }); + + media.is_animated(f, mime) +} + /// Determine size of video at temp file pub fn video_size(f: &NamedTempFile) -> Option<(i64, i64)> { let media = MediaImpl::new(Files { diff --git a/crates/core/files/src/repositories/media_repository.rs b/crates/core/files/src/repositories/media_repository.rs index 4cc4fecac..6c489d9b3 100644 --- a/crates/core/files/src/repositories/media_repository.rs +++ b/crates/core/files/src/repositories/media_repository.rs @@ -6,6 +6,9 @@ use thiserror::Error; pub trait MediaRepository: Send + Sync + 'static { fn image_size(&self, f: &NamedTempFile) -> Option<(usize, usize)>; + + fn is_animated(&self, f: &NamedTempFile, mime: &str) -> Option; + fn image_size_vec(&self, v: &[u8], mime: &str) -> Option<(usize, usize)>; fn decode_image( diff --git a/crates/core/models/src/v0/files.rs b/crates/core/models/src/v0/files.rs index b996483cb..7ed1e20e8 100644 --- a/crates/core/models/src/v0/files.rs +++ b/crates/core/models/src/v0/files.rs @@ -46,8 +46,12 @@ auto_derived!( File, /// File contains textual data and should be displayed as such Text, - /// File is an image with specific dimensions - Image { width: usize, height: usize }, + /// File is an image with specific dimensions, and may be animated + Image { + width: usize, + height: usize, + animated: bool, + }, /// File is a video with specific dimensions Video { width: usize, height: usize }, /// File is audio diff --git a/crates/services/autumn/src/api.rs b/crates/services/autumn/src/api.rs index d711e5331..4018e72c1 100644 --- a/crates/services/autumn/src/api.rs +++ b/crates/services/autumn/src/api.rs @@ -380,7 +380,7 @@ async fn fetch_preview( let hash = file.as_hash(&db).await?; - let is_animated = hash.content_type == "image/gif"; // TODO: extract this data from files + let is_animated = matches!(hash.metadata, Metadata::Image { animated: true, .. }); // Only process image files and don't process GIFs if not avatar or icon if !matches!(hash.metadata, Metadata::Image { .. }) diff --git a/crates/services/autumn/src/exif.rs b/crates/services/autumn/src/exif.rs index 23be9ac7f..562f975ee 100644 --- a/crates/services/autumn/src/exif.rs +++ b/crates/services/autumn/src/exif.rs @@ -16,7 +16,11 @@ pub async fn strip_metadata( mime: &str, ) -> Result<(Vec, Metadata)> { match &metadata { - Metadata::Image { width, height } => match mime { + Metadata::Image { + width, + height, + animated, + } => match mime { // // little_exif does not appear to parse JPEGs correctly? had 2/2 files fail // "image/jpeg" | "image/png" => { // // use little_exif to strip metadata except for orientation and colour profile @@ -93,7 +97,14 @@ pub async fn strip_metadata( _ => (*width, *height), }; - Ok((bytes, Metadata::Image { width, height })) + Ok(( + bytes, + Metadata::Image { + width, + height, + animated: *animated, + }, + )) } // JXLs store EXIF data but we don't have the ability to write them "image/jxl" => Ok((buf, metadata)), diff --git a/crates/services/autumn/src/metadata.rs b/crates/services/autumn/src/metadata.rs index 72b610e90..3c69cf848 100644 --- a/crates/services/autumn/src/metadata.rs +++ b/crates/services/autumn/src/metadata.rs @@ -1,7 +1,7 @@ use std::io::Cursor; use revolt_database::Metadata; -use revolt_files::{image_size, video_size}; +use revolt_files::{image_size, is_animated, video_size}; use tempfile::NamedTempFile; /// Intersection of what infer can detect and what image-rs supports @@ -26,6 +26,7 @@ pub fn generate_metadata(f: &NamedTempFile, mime_type: &str) -> Metadata { .map(|(width, height)| Metadata::Image { width: width as isize, height: height as isize, + animated: is_animated(f, mime_type).unwrap_or(false), }) .unwrap_or_default() } else if mime_type.starts_with("video/") { From b830631bd25a546844b7bdd30386084bb365e4de Mon Sep 17 00:00:00 2001 From: sinus-x <14353790+sinus-x@users.noreply.github.com> Date: Mon, 23 Mar 2026 06:18:25 +0100 Subject: [PATCH 114/211] fix(docs): Update GitHub links (#647) Updates user-facing links to point to the new organization. Does not update references in source code (user-agent, dependency references), as they should be handled separately. Signed-off-by: sinus-x <14353790+sinus-x@users.noreply.github.com> --- README.md | 4 ++-- crates/delta/src/routes/mod.rs | 2 +- docs/docs/developing/backend/new_features.md | 2 +- docs/docs/help.md | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c80f4595c..86e93039f 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ Rust 1.86.0 or higher. ## Development Guide -Before contributing, make yourself familiar with [our contribution guidelines](https://developers.stoat.chat/developing/contrib/) and the [technical documentation for this project](https://stoatchat.github.io/stoatchat/). +Before contributing, make yourself familiar with [our contribution guidelines](https://developers.stoat.chat/developing/contrib/) and the [technical documentation for this project](https://developers.stoat.chat/). Before getting started, you'll want to install: @@ -212,6 +212,6 @@ TEST_DB=MONGODB cargo nextest run ## License -The Stoat backend is generally licensed under the [GNU Affero General Public License v3.0](https://github.com/stoatchat/stoatchat/blob/master/LICENSE). +The Stoat backend is generally licensed under the [GNU Affero General Public License v3.0](https://github.com/stoatchat/stoatchat/blob/main/LICENSE). **Individual crates may supply their own licenses!** diff --git a/crates/delta/src/routes/mod.rs b/crates/delta/src/routes/mod.rs index 9643a3657..cf1c4ace6 100644 --- a/crates/delta/src/routes/mod.rs +++ b/crates/delta/src/routes/mod.rs @@ -216,7 +216,7 @@ fn custom_openapi_spec() -> OpenApi { }), license: Some(License { name: "AGPLv3".to_owned(), - url: Some("https://github.com/revoltchat/delta/blob/master/LICENSE".to_owned()), + url: Some("https://github.com/stoatchat/stoatchat/blob/main/crates/delta/LICENSE".to_owned()), ..Default::default() }), version: env!("CARGO_PKG_VERSION").to_string(), diff --git a/docs/docs/developing/backend/new_features.md b/docs/docs/developing/backend/new_features.md index 029e1325b..18d43afce 100644 --- a/docs/docs/developing/backend/new_features.md +++ b/docs/docs/developing/backend/new_features.md @@ -10,6 +10,6 @@ Before writing new API features, generally a good idea to: When your feature is ready to release, ensure to: - Update backend documentation (what you're reading now!) if applicable -- Update the [developers documentation](https://github.com/stoatchat/developer-wiki) if applicable +- Update the [developers documentation](https://github.com/stoatchat/stoatchat/tree/main/docs) if applicable - Update the Feature Matrix (or ask someone that can to do so) - Ensure it is properly listed in the backend release changelog diff --git a/docs/docs/help.md b/docs/docs/help.md index ae95dbf78..91887e6be 100644 --- a/docs/docs/help.md +++ b/docs/docs/help.md @@ -13,7 +13,7 @@ We want to hear what you think and appreciate and await your feature suggestions Typically, you can open issues on the relevant [GitHub repositories](https://github.com/stoatchat). - + ### 2. Translate From cf2cedcee15a23dd831b010690d097d9b7c69fd4 Mon Sep 17 00:00:00 2001 From: Tom Date: Mon, 23 Mar 2026 11:51:22 -0700 Subject: [PATCH 115/211] chore: silence git town errors (#687) Signed-off-by: IAmTomahawkx --- .github/workflows/git-town.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/git-town.yml b/.github/workflows/git-town.yml index 060fe1063..1dba2ac7c 100644 --- a/.github/workflows/git-town.yml +++ b/.github/workflows/git-town.yml @@ -17,3 +17,4 @@ jobs: steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: stoatchat/action-git-town@4bc5c942e4603bffa0806b51d5fe5f0bc5deb0ac + continue-on-error: true From edfa97db108c9c81828547f98a1db5315cb5ba4a Mon Sep 17 00:00:00 2001 From: Tom Date: Mon, 23 Mar 2026 12:25:33 -0700 Subject: [PATCH 116/211] feat: Allow restricting server creation to specific users (#685) Signed-off-by: IAmTomahawkx --- crates/core/config/Revolt.toml | 4 +++ crates/core/config/src/lib.rs | 2 ++ crates/core/result/src/axum.rs | 1 + crates/core/result/src/lib.rs | 32 +++++++++---------- crates/core/result/src/rocket.rs | 1 + crates/delta/src/routes/root.rs | 18 +++++++++-- .../delta/src/routes/servers/server_create.rs | 19 +++++++++++ 7 files changed, 57 insertions(+), 20 deletions(-) diff --git a/crates/core/config/Revolt.toml b/crates/core/config/Revolt.toml index a64778c46..4468517fe 100644 --- a/crates/core/config/Revolt.toml +++ b/crates/core/config/Revolt.toml @@ -220,6 +220,10 @@ new_user_hours = 72 # (should be greater than any one file upload limit) body_limit_size = 20_000_000 +# If any userids are entered here, only those users will be able to create servers. +# Leave empty to allow all users to create servers +restrict_server_creation = [] + [features.limits.new_user] # Limits imposed on new users diff --git a/crates/core/config/src/lib.rs b/crates/core/config/src/lib.rs index 76a6b2e11..23f7edf39 100644 --- a/crates/core/config/src/lib.rs +++ b/crates/core/config/src/lib.rs @@ -344,6 +344,8 @@ pub struct GlobalLimits { pub new_user_hours: usize, pub body_limit_size: usize, + + pub restrict_server_creation: Vec, } #[derive(Deserialize, Debug, Clone)] diff --git a/crates/core/result/src/axum.rs b/crates/core/result/src/axum.rs index 3cbf43590..1145009c9 100644 --- a/crates/core/result/src/axum.rs +++ b/crates/core/result/src/axum.rs @@ -37,6 +37,7 @@ impl IntoResponse for Error { ErrorType::AlreadyPinned => StatusCode::BAD_REQUEST, ErrorType::NotPinned => StatusCode::BAD_REQUEST, + ErrorType::CantCreateServers => StatusCode::FORBIDDEN, ErrorType::UnknownServer => StatusCode::NOT_FOUND, ErrorType::InvalidRole => StatusCode::NOT_FOUND, ErrorType::Banned => StatusCode::FORBIDDEN, diff --git a/crates/core/result/src/lib.rs b/crates/core/result/src/lib.rs index a76612124..17093f962 100644 --- a/crates/core/result/src/lib.rs +++ b/crates/core/result/src/lib.rs @@ -1,5 +1,5 @@ -use std::panic::Location; use std::fmt::Display; +use std::panic::Location; #[cfg(feature = "serde")] #[macro_use] @@ -104,6 +104,7 @@ pub enum ErrorType { NotPinned, // ? Server related errors + CantCreateServers, UnknownServer, InvalidRole, Banned, @@ -232,17 +233,16 @@ impl ToRevoltError for Result Result { let loc = Location::caller(); - self - .map_err(|e| { - log::error!("{e:?}"); - #[cfg(feature = "sentry")] - sentry::capture_error(&e); - - Error { - error_type: ErrorType::InternalError, - location: format!("{}:{}:{}", loc.file(), loc.line(), loc.column()) - } - }) + self.map_err(|e| { + log::error!("{e:?}"); + #[cfg(feature = "sentry")] + sentry::capture_error(&e); + + Error { + error_type: ErrorType::InternalError, + location: format!("{}:{}:{}", loc.file(), loc.line(), loc.column()), + } + }) } } @@ -251,11 +251,9 @@ impl ToRevoltError for Option { fn to_internal_error(self) -> Result { let loc = Location::caller(); - self.ok_or_else(|| { - Error { - error_type: ErrorType::InternalError, - location: format!("{}:{}:{}", loc.file(), loc.line(), loc.column()) - } + self.ok_or_else(|| Error { + error_type: ErrorType::InternalError, + location: format!("{}:{}:{}", loc.file(), loc.line(), loc.column()), }) } } diff --git a/crates/core/result/src/rocket.rs b/crates/core/result/src/rocket.rs index 94bed4d2b..744d09cfb 100644 --- a/crates/core/result/src/rocket.rs +++ b/crates/core/result/src/rocket.rs @@ -44,6 +44,7 @@ impl<'r> Responder<'r, 'static> for Error { ErrorType::NotPinned => Status::BadRequest, ErrorType::InvalidFlagValue => Status::BadRequest, + ErrorType::CantCreateServers => Status::Forbidden, ErrorType::UnknownServer => Status::NotFound, ErrorType::InvalidRole => Status::NotFound, ErrorType::Banned => Status::Forbidden, diff --git a/crates/delta/src/routes/root.rs b/crates/delta/src/routes/root.rs index 44b697d4b..6fd37a19b 100644 --- a/crates/delta/src/routes/root.rs +++ b/crates/delta/src/routes/root.rs @@ -1,8 +1,8 @@ -use std::collections::HashMap; use revolt_config::config; use revolt_result::Result; use rocket::serde::json::Json; use serde::Serialize; +use std::collections::HashMap; /// # hCaptcha Configuration #[derive(Serialize, JsonSchema, Debug)] @@ -88,6 +88,10 @@ pub struct GlobalLimits { /// max server channels server_channels: i64, body_limit_size: i64, + + /// restrict server creation to these users. + /// if blank, all users can create servers + pub restrict_server_creation: Vec, } /// # User Limits @@ -125,7 +129,10 @@ impl UserLimits { voice_quality: fl.voice_quality as i64, video: fl.video, video_resolution: [fl.video_resolution[0] as i64, fl.video_resolution[1] as i64], - video_aspect_ratio: [fl.video_aspect_ratio[0] as f64, fl.video_aspect_ratio[1] as f64], + video_aspect_ratio: [ + fl.video_aspect_ratio[0] as f64, + fl.video_aspect_ratio[1] as f64, + ], file_upload_size_limits: fl.file_upload_size_limit, } } @@ -219,10 +226,15 @@ pub async fn root() -> Result> { server_roles: config.features.limits.global.server_roles as i64, server_channels: config.features.limits.global.server_channels as i64, body_limit_size: config.features.limits.global.body_limit_size as i64, + restrict_server_creation: config + .features + .limits + .global + .restrict_server_creation, }, new_user: UserLimits::from_feature_limits(config.features.limits.new_user), default: UserLimits::from_feature_limits(config.features.limits.default), - } + }, }, ws: config.hosts.events, app: config.hosts.app, diff --git a/crates/delta/src/routes/servers/server_create.rs b/crates/delta/src/routes/servers/server_create.rs index 82f0a8aaf..5b9aa0101 100644 --- a/crates/delta/src/routes/servers/server_create.rs +++ b/crates/delta/src/routes/servers/server_create.rs @@ -1,3 +1,4 @@ +use revolt_config::config; use revolt_database::{Database, Member, Server, User}; use revolt_models::v0; use revolt_result::{create_error, Result}; @@ -20,6 +21,24 @@ pub async fn create_server( return Err(create_error!(IsBot)); } + let config = config().await; + + if !config + .features + .limits + .global + .restrict_server_creation + .is_empty() + && !config + .features + .limits + .global + .restrict_server_creation + .contains(&user.id) + { + return Err(create_error!(CantCreateServers)); + } + let data = data.into_inner(); data.validate().map_err(|error| { create_error!(FailedValidation { From 2a73d8225081f74274914169c82a79962d964c94 Mon Sep 17 00:00:00 2001 From: "stoat-tofu[bot]" <242700035+stoat-tofu[bot]@users.noreply.github.com> Date: Tue, 24 Mar 2026 18:59:15 +0000 Subject: [PATCH 117/211] chore: modify .github/workflows/git-town.yml --- .github/workflows/git-town.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/git-town.yml b/.github/workflows/git-town.yml index 1dba2ac7c..060fe1063 100644 --- a/.github/workflows/git-town.yml +++ b/.github/workflows/git-town.yml @@ -17,4 +17,3 @@ jobs: steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: stoatchat/action-git-town@4bc5c942e4603bffa0806b51d5fe5f0bc5deb0ac - continue-on-error: true From abfb3925fd6cec4f682e8279a51f33a6cb3e1f14 Mon Sep 17 00:00:00 2001 From: "stoat-tofu[bot]" <242700035+stoat-tofu[bot]@users.noreply.github.com> Date: Tue, 24 Mar 2026 19:03:37 +0000 Subject: [PATCH 118/211] chore: modify .github/workflows/git-town.yml --- .github/workflows/git-town.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/git-town.yml b/.github/workflows/git-town.yml index 060fe1063..678b60c1f 100644 --- a/.github/workflows/git-town.yml +++ b/.github/workflows/git-town.yml @@ -1,3 +1,6 @@ +# DO NOT EDIT DIRECTLY IN REPOSITORY +# Managed in Terraform templates + name: Git Town on: @@ -8,7 +11,7 @@ jobs: name: Display the branch stack runs-on: ubuntu-slim - if: ${{ !startsWith(github.head_ref, 'release-please--') }} + if: ${{ github.event.pull_request.head.repo.full_name == github.repository && !startsWith(github.head_ref, 'release-please--') }} permissions: contents: read @@ -17,3 +20,4 @@ jobs: steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - uses: stoatchat/action-git-town@4bc5c942e4603bffa0806b51d5fe5f0bc5deb0ac + continue-on-error: true \ No newline at end of file From 1a9d5b4b657eea32dfba1b37b4673f7940124846 Mon Sep 17 00:00:00 2001 From: "stoat-tofu[bot]" <242700035+stoat-tofu[bot]@users.noreply.github.com> Date: Tue, 24 Mar 2026 19:03:39 +0000 Subject: [PATCH 119/211] chore: modify .github/workflows/release-webhook.yml --- .github/workflows/release-webhook.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/release-webhook.yml b/.github/workflows/release-webhook.yml index 46504b1a7..3996b1f87 100644 --- a/.github/workflows/release-webhook.yml +++ b/.github/workflows/release-webhook.yml @@ -1,3 +1,6 @@ +# DO NOT EDIT DIRECTLY IN REPOSITORY +# Managed in Terraform templates + name: Release Webhook on: From ecb94e278ca34f0f05ddc4adcf4360e02657f5ce Mon Sep 17 00:00:00 2001 From: "stoat-tofu[bot]" <242700035+stoat-tofu[bot]@users.noreply.github.com> Date: Tue, 24 Mar 2026 19:03:59 +0000 Subject: [PATCH 120/211] chore: modify .github/workflows/validate-pr-title.yml --- .github/workflows/validate-pr-title.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/validate-pr-title.yml b/.github/workflows/validate-pr-title.yml index 6af093036..1374d58cc 100644 --- a/.github/workflows/validate-pr-title.yml +++ b/.github/workflows/validate-pr-title.yml @@ -1,3 +1,6 @@ +# DO NOT EDIT DIRECTLY IN REPOSITORY +# Managed in Terraform templates + name: "Lint PR" on: @@ -15,6 +18,6 @@ jobs: permissions: pull-requests: read steps: - - uses: amannn/action-semantic-pull-request@v6 + - uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6.1.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file From ec22deb2cd2e2122d32b8cf1fbfcbc2fc1fe1a49 Mon Sep 17 00:00:00 2001 From: flexxyfluxx <82163962+flexxyfluxx@users.noreply.github.com> Date: Fri, 27 Mar 2026 20:25:57 +0000 Subject: [PATCH 121/211] docs(readme): remove outdated reference to `scripts/install.sh`; add instruction to run `mise install` (#691) * chore: fill in missing install step: mise install Signed-off-by: flexxyfluxx <82163962+flexxyfluxx@users.noreply.github.com> * chore: remove outdated reference to scripts/start.sh Signed-off-by: flexxyfluxx <82163962+flexxyfluxx@users.noreply.github.com> --------- Signed-off-by: flexxyfluxx <82163962+flexxyfluxx@users.noreply.github.com> --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 86e93039f..dd62769ae 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,7 @@ Now you can clone and build the project: ```bash git clone https://github.com/stoatchat/stoatchat stoat-backend cd stoat-backend +mise install mise build ``` @@ -130,9 +131,6 @@ Then continue: # start other necessary services docker compose up -d -# run everything together -./scripts/start.sh -# .. or individually # run the API server cargo run --bin revolt-delta # run the events server From 98c7b1b5a5b9fdac5c0ab83be10f0e23114dbfc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0spik?= Date: Sat, 28 Mar 2026 03:02:12 +0300 Subject: [PATCH 122/211] feat: implement time based message sweep on user ban (#670) * feat: implement time based message sweep on user ban - Adds `delete_message_seconds` (0 to 7 days in seconds) to the ban request payload. Signed-off-by: arsabutispik * refactor: pass ulid conversion to database Signed-off-by: arsabutispik * fix: use COL constant instead of hardcoded string in error mapper Signed-off-by: arsabutispik * refactor: broadcast bulk delete events during ban sweep Updates the `delete_messages_by_author_since` trait to return a HashMap of deleted message IDs grouped by channel. The MongoDB implementation now uses a two-step process: it first runs a projected `find` query to gather the target `_id` and `channel` fields, then executes the `delete_many` operation. This allows the ban route to loop through the affected channels and dispatch `EventV1::BulkMessageDelete` WebSocket events, ensuring that the swept messages are instantly removed from the UI for all connected clients. Signed-off-by: arsabutispik * refactor: optimize message deletion by using $group and aggregate Signed-off-by: arsabutispik * refactor: use with_type in query Signed-off-by: arsabutispik * refactor: abstract function to Message model and mark attachments as deleted Signed-off-by: arsabutispik --------- Signed-off-by: arsabutispik --- .../database/src/models/messages/model.rs | 31 ++++- .../core/database/src/models/messages/ops.rs | 10 ++ .../src/models/messages/ops/mongodb.rs | 110 ++++++++++++++++++ .../src/models/messages/ops/reference.rs | 63 +++++++++- crates/core/models/src/v0/server_bans.rs | 3 + crates/delta/src/routes/servers/ban_create.rs | 13 ++- 6 files changed, 225 insertions(+), 5 deletions(-) diff --git a/crates/core/database/src/models/messages/model.rs b/crates/core/database/src/models/messages/model.rs index 2db57b12e..3db6df49f 100644 --- a/crates/core/database/src/models/messages/model.rs +++ b/crates/core/database/src/models/messages/model.rs @@ -1,5 +1,3 @@ -use std::{collections::HashSet, hash::RandomState}; - use indexmap::{IndexMap, IndexSet}; use iso8601_timestamp::Timestamp; use revolt_config::{config, FeaturesLimits}; @@ -9,6 +7,8 @@ use revolt_models::v0::{ }; use revolt_permissions::{calculate_channel_permissions, ChannelPermission, PermissionValue}; use revolt_result::{ErrorType, Result}; +use std::time::SystemTime; +use std::{collections::HashSet, hash::RandomState}; use ulid::Ulid; use validator::Validate; @@ -497,7 +497,7 @@ impl Message { user_mentions.retain(|m| recipients_hash.contains(m)); role_mentions.clear(); } - Channel::TextChannel { ref server, .. }=> { + Channel::TextChannel { ref server, .. } => { let mentions_vec = Vec::from_iter(user_mentions.iter().cloned()); let valid_members = db.fetch_members(server.as_str(), &mentions_vec[..]).await; @@ -1034,6 +1034,31 @@ impl Message { Ok(()) } + /// Bulk delete messages by an author since a given time + pub async fn bulk_delete_by_author_since( + db: &Database, + channels: &[String], + author: &str, + since: SystemTime, + ) -> Result<()> { + let deleted_groups = db + .delete_messages_by_author_since(channels, author, since) + .await?; + + for (channel_id, message_ids) in deleted_groups { + if !message_ids.is_empty() { + EventV1::BulkMessageDelete { + channel: channel_id.clone(), + ids: message_ids, + } + .p(channel_id) + .await; + } + } + + Ok(()) + } + /// Remove a reaction from a message pub async fn remove_reaction(&self, db: &Database, user: &str, emoji: &str) -> Result<()> { // Check if it actually exists diff --git a/crates/core/database/src/models/messages/ops.rs b/crates/core/database/src/models/messages/ops.rs index 4d54e83cb..6ebdf4c3b 100644 --- a/crates/core/database/src/models/messages/ops.rs +++ b/crates/core/database/src/models/messages/ops.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; +use std::time::SystemTime; use revolt_result::Result; use crate::{AppendMessage, FieldsMessage, Message, MessageQuery, PartialMessage}; @@ -40,4 +42,12 @@ pub trait AbstractMessages: Sync + Send { /// Delete messages from a channel by their ids and corresponding channel id async fn delete_messages(&self, channel: &str, ids: &[String]) -> Result<()>; + + /// Delete all messages from a specific author in a server from a certain ULID onwards + async fn delete_messages_by_author_since( + &self, + channels: &[String], + author: &str, + since: SystemTime + ) -> Result>>; } diff --git a/crates/core/database/src/models/messages/ops/mongodb.rs b/crates/core/database/src/models/messages/ops/mongodb.rs index 449e71efd..2a79ed5b4 100644 --- a/crates/core/database/src/models/messages/ops/mongodb.rs +++ b/crates/core/database/src/models/messages/ops/mongodb.rs @@ -1,8 +1,12 @@ use bson::{to_bson, Document}; use futures::try_join; +use futures::StreamExt; use mongodb::options::FindOptions; use revolt_models::v0::MessageSort; use revolt_result::Result; +use std::collections::{HashMap, HashSet}; +use std::time::SystemTime; +use ulid::Ulid; use crate::{ AppendMessage, DocumentId, FieldsMessage, IntoDocumentPath, Message, MessageQuery, @@ -306,6 +310,112 @@ impl AbstractMessages for MongoDb { .map(|_| ()) .map_err(|_| create_database_error!("delete_many", COL)) } + + /// Delete all messages from a specific author in a server from a certain ULID onwards + async fn delete_messages_by_author_since( + &self, + channels: &[String], + author: &str, + since: SystemTime, + ) -> Result>> { + let threshold_ulid = Ulid::from_datetime(since).to_string(); + + let filter = doc! { + "author": author, + "channel": { "$in": channels }, + "_id": { "$gte": &threshold_ulid } + }; + + let pipeline = vec![ + doc! { "$match": filter.clone() }, + doc! { + "$project": { + "channel": 1_i32, + "message_id": "$_id", + "attachment_ids": { + "$map": { + "input": { "$ifNull": ["$attachments", Vec::::new()] }, + "as": "a", + "in": "$$a._id" + } + } + } + }, + doc! { + "$group": { + "_id": "$channel", + "message_ids": { "$push": "$message_id" }, + "attachment_ids_nested": { "$push": "$attachment_ids" } + } + }, + doc! { + "$project": { + "message_ids": 1_i32, + "attachment_ids": { + "$reduce": { + "input": "$attachment_ids_nested", + "initialValue": Vec::::new(), + "in": { "$setUnion": ["$$value", "$$this"] } + } + } + } + }, + ]; + + #[derive(serde::Deserialize)] + struct AggregatedChannel { + #[serde(rename = "_id")] + channel: String, + message_ids: Vec, + #[serde(default)] + attachment_ids: Vec, + } + + let mut cursor = self + .col::(COL) + .aggregate(pipeline) + .await + .map_err(|_| create_database_error!("aggregate", COL))? + .with_type::(); + + let mut deleted_messages: HashMap> = HashMap::new(); + let mut attachment_ids: HashSet = HashSet::new(); + + while let Some(result) = cursor.next().await { + if let Ok(item) = result { + for id in item.attachment_ids { + attachment_ids.insert(id); + } + deleted_messages.insert(item.channel, item.message_ids); + } + } + + // Mark attachments as deleted before deleting messages + if !attachment_ids.is_empty() { + self.col::("attachments") + .update_many( + doc! { + "_id": { + "$in": attachment_ids.into_iter().collect::>() + } + }, + doc! { + "$set": { + "deleted": true + } + }, + ) + .await + .map_err(|_| create_database_error!("update_many", "attachments"))?; + } + + self.col::(COL) + .delete_many(filter) + .await + .map_err(|_| create_database_error!("delete_many", COL))?; + + Ok(deleted_messages) + } } impl IntoDocumentPath for FieldsMessage { diff --git a/crates/core/database/src/models/messages/ops/reference.rs b/crates/core/database/src/models/messages/ops/reference.rs index ae5b43f03..6f30de6ff 100644 --- a/crates/core/database/src/models/messages/ops/reference.rs +++ b/crates/core/database/src/models/messages/ops/reference.rs @@ -1,7 +1,9 @@ +use std::collections::HashMap; use futures::future::try_join_all; use indexmap::IndexSet; use revolt_result::Result; - +use std::time::SystemTime; +use ulid::Ulid; use crate::{AppendMessage, FieldsMessage, Message, MessageQuery, PartialMessage, ReferenceDb}; use super::AbstractMessages; @@ -286,4 +288,63 @@ impl AbstractMessages for ReferenceDb { Ok(()) } + + /// Delete all messages from a specific author in a list of channels from a certain ULID onwards + async fn delete_messages_by_author_since( + &self, + channels: &[String], + author: &str, + since: SystemTime + ) -> Result>> { + let threshold_ulid = Ulid::from_datetime(since).to_string(); + let mut deleted_messages: HashMap> = HashMap::new(); + let mut attachment_ids: Vec = Vec::new(); + + let messages = self.messages.lock().await; + + // First pass: collect attachment IDs and message IDs to delete + for (id, message) in messages.iter() { + let should_delete = message.author == author + && channels.contains(&message.channel) + && id.as_str() >= threshold_ulid.as_str(); + + if should_delete { + // Collect attachment IDs + if let Some(attachments) = &message.attachments { + for attachment in attachments { + attachment_ids.push(attachment.id.clone()); + } + } + + deleted_messages + .entry(message.channel.clone()) + .or_default() + .push(id.clone()); + } + } + drop(messages); + + // Mark attachments as deleted + if !attachment_ids.is_empty() { + let mut files = self.files.lock().await; + for attachment_id in attachment_ids { + if let Some(file) = files.get_mut(&attachment_id) { + file.deleted = Some(true); + } + } + } + + // Delete the messages + self.messages + .lock() + .await + .retain(|id, message| { + let should_keep = !(message.author == author + && channels.contains(&message.channel) + && id.as_str() >= threshold_ulid.as_str()); + should_keep + }); + + Ok(deleted_messages) + } } diff --git a/crates/core/models/src/v0/server_bans.rs b/crates/core/models/src/v0/server_bans.rs index b6debfcdc..940a3738b 100644 --- a/crates/core/models/src/v0/server_bans.rs +++ b/crates/core/models/src/v0/server_bans.rs @@ -19,6 +19,9 @@ auto_derived!( /// Ban reason #[cfg_attr(feature = "validator", validate(length(min = 0, max = 1024)))] pub reason: Option, + /// Messages to delete in seconds + #[cfg_attr(feature = "validator", validate(range(min = 0, max = 604800)))] + pub delete_message_seconds: Option, } /// Just enough information to list a ban diff --git a/crates/delta/src/routes/servers/ban_create.rs b/crates/delta/src/routes/servers/ban_create.rs index 4ff103299..a29b4300c 100644 --- a/crates/delta/src/routes/servers/ban_create.rs +++ b/crates/delta/src/routes/servers/ban_create.rs @@ -4,13 +4,16 @@ use revolt_database::{ get_user_voice_channel_in_server, remove_user_from_voice_channel, UserVoiceChannel, VoiceClient, }, - Database, RemovalIntention, ServerBan, User, + Database, Message, RemovalIntention, ServerBan, User, }; use revolt_models::v0; +use std::time::{Duration, SystemTime}; +use revolt_database::events::client::EventV1; use revolt_permissions::{calculate_server_permissions, ChannelPermission}; use revolt_result::{create_error, Result}; use rocket::{serde::json::Json, State}; +use ulid::Ulid; use validator::Validate; /// # Ban User @@ -73,7 +76,15 @@ pub async fn ban( .await?; } } + // We do this outside the member check so we can sweep hit-and-run spammers who already left. + if let Some(seconds) = data.delete_message_seconds { + if seconds > 0 { + let threshold_time = SystemTime::now() - Duration::from_secs(seconds as u64); + Message::bulk_delete_by_author_since(db, &server.channels, target.id, threshold_time) + .await?; + } + } ServerBan::create(db, &server, target.id, data.reason) .await .map(Into::into) From a5cd08a655dece4269f3ac84fa2387ae356709a5 Mon Sep 17 00:00:00 2001 From: Tom Date: Fri, 27 Mar 2026 17:03:48 -0700 Subject: [PATCH 123/211] fix: add flag for disabling events instead of commenting them out (#695) Signed-off-by: IAmTomahawkx --- crates/bonfire/src/events/impl.rs | 50 ++++++++++++++------------ crates/bonfire/src/websocket.rs | 59 ++++++++++++++++++------------- crates/core/config/Revolt.toml | 1 + crates/core/config/src/lib.rs | 1 + 4 files changed, 63 insertions(+), 48 deletions(-) diff --git a/crates/bonfire/src/events/impl.rs b/crates/bonfire/src/events/impl.rs index c6d07d2f3..121135376 100644 --- a/crates/bonfire/src/events/impl.rs +++ b/crates/bonfire/src/events/impl.rs @@ -400,29 +400,33 @@ impl State { } /// Push presence change to the user and all associated server topics - pub async fn broadcast_presence_change(&self, _target: bool) { - // disabled events - // if if let Some(status) = &self.cache.users.get(&self.cache.user_id).unwrap().status { - // status.presence != Some(Presence::Invisible) - // } else { - // true - // } { - // let event = EventV1::UserUpdate { - // id: self.cache.user_id.clone(), - // data: v0::PartialUser { - // online: Some(target), - // ..Default::default() - // }, - // clear: vec![], - // event_id: Some(ulid::Ulid::new().to_string()), - // }; - - // for server in self.cache.servers.keys() { - // event.clone().p(server.clone()).await; - // } - - // event.p(self.cache.user_id.clone()).await; - // } + pub async fn broadcast_presence_change(&self, target: bool) { + let config = revolt_config::config().await; + if config.disable_events_dont_use { + return; + } + + if if let Some(status) = &self.cache.users.get(&self.cache.user_id).unwrap().status { + status.presence != Some(Presence::Invisible) + } else { + true + } { + let event = EventV1::UserUpdate { + id: self.cache.user_id.clone(), + data: v0::PartialUser { + online: Some(target), + ..Default::default() + }, + clear: vec![], + event_id: Some(ulid::Ulid::new().to_string()), + }; + + for server in self.cache.servers.keys() { + event.clone().p(server.clone()).await; + } + + event.p(self.cache.user_id.clone()).await; + } } /// Handle an incoming event for protocol version 1 diff --git a/crates/bonfire/src/websocket.rs b/crates/bonfire/src/websocket.rs index 4a8cfe4c5..ec4202dc4 100644 --- a/crates/bonfire/src/websocket.rs +++ b/crates/bonfire/src/websocket.rs @@ -428,6 +428,8 @@ async fn worker( mut read: WsReader, write: &Mutex, ) { + let revolt_config = revolt_config::config().await; + loop { let t1 = read.try_next().fuse(); let t2 = kill_signal_r.recv().fuse(); @@ -463,31 +465,38 @@ async fn worker( }; match payload { - // disabled events - // ClientMessage::BeginTyping { channel } => { - // if !subscribed.read().await.contains(&channel) { - // continue; - // } - - // EventV1::ChannelStartTyping { - // id: channel.clone(), - // user: user_id.clone(), - // } - // .p(channel.clone()) - // .await; - // } - // ClientMessage::EndTyping { channel } => { - // if !subscribed.read().await.contains(&channel) { - // continue; - // } - - // EventV1::ChannelStopTyping { - // id: channel.clone(), - // user: user_id.clone(), - // } - // .p(channel.clone()) - // .await; - // } + ClientMessage::BeginTyping { channel } => { + if revolt_config.disable_events_dont_use { + continue; + } + + if !subscribed.read().await.contains(&channel) { + continue; + } + + EventV1::ChannelStartTyping { + id: channel.clone(), + user: user_id.clone(), + } + .p(channel.clone()) + .await; + } + ClientMessage::EndTyping { channel } => { + if revolt_config.disable_events_dont_use { + continue; + } + + if !subscribed.read().await.contains(&channel) { + continue; + } + + EventV1::ChannelStopTyping { + id: channel.clone(), + user: user_id.clone(), + } + .p(channel.clone()) + .await; + } ClientMessage::Subscribe { server_id } => { let mut servers = active_servers.lock().await; let has_item = servers.contains_key(&server_id); diff --git a/crates/core/config/Revolt.toml b/crates/core/config/Revolt.toml index 4468517fe..289ab0df9 100644 --- a/crates/core/config/Revolt.toml +++ b/crates/core/config/Revolt.toml @@ -1,4 +1,5 @@ production = false +disable_events_dont_use = false [database] # MongoDB connection URL diff --git a/crates/core/config/src/lib.rs b/crates/core/config/src/lib.rs index 23f7edf39..6183cca94 100644 --- a/crates/core/config/src/lib.rs +++ b/crates/core/config/src/lib.rs @@ -423,6 +423,7 @@ pub struct Settings { pub features: Features, pub sentry: Sentry, pub production: bool, + pub disable_events_dont_use: bool, } impl Settings { From 6107f242fd3ebaff71a15f9a16330ffbcb4f2d7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0spik?= Date: Sat, 28 Mar 2026 03:09:15 +0300 Subject: [PATCH 124/211] feat: Add slowmode functionality to text channels (#680) * feat: Add slowmode functionality to text channels Signed-off-by: arsabutispik * fix: use atomic check-and-set to prevent spamming with scripts Signed-off-by: arsabutispik * feat: Add BypassSlowmode permission to channel permissions Signed-off-by: arsabutispik * refactor: Use set_options instead of manually building the command Signed-off-by: arsabutispik --------- Signed-off-by: arsabutispik --- .../database/src/models/channels/model.rs | 8 ++++ crates/core/database/src/util/bridge/v0.rs | 10 +++- crates/core/models/src/v0/channels.rs | 10 ++++ crates/core/permissions/src/models/channel.rs | 4 +- crates/core/result/src/axum.rs | 3 ++ crates/core/result/src/lib.rs | 3 ++ crates/core/result/src/rocket.rs | 3 ++ .../delta/src/routes/channels/channel_edit.rs | 7 +++ .../delta/src/routes/channels/message_send.rs | 48 ++++++++++++++++++- 9 files changed, 92 insertions(+), 4 deletions(-) diff --git a/crates/core/database/src/models/channels/model.rs b/crates/core/database/src/models/channels/model.rs index d8a485b94..025b7934b 100644 --- a/crates/core/database/src/models/channels/model.rs +++ b/crates/core/database/src/models/channels/model.rs @@ -110,6 +110,10 @@ auto_derived!( /// Voice Information for when this channel is also a voice channel #[serde(skip_serializing_if = "Option::is_none")] voice: Option, + + /// The channel's slowmode delay in seconds + #[serde(skip_serializing_if = "Option::is_none")] + slowmode: Option, }, } @@ -146,6 +150,8 @@ auto_derived!( pub last_message_id: Option, #[serde(skip_serializing_if = "Option::is_none")] pub voice: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub slowmode: Option, } /// Optional fields on channel object @@ -206,6 +212,7 @@ impl Channel { role_permissions: HashMap::new(), nsfw: data.nsfw.unwrap_or(false), voice: data.voice.map(|voice| voice.into()), + slowmode: None }, v0::LegacyServerChannelType::Voice => Channel::TextChannel { id: id.clone(), @@ -218,6 +225,7 @@ impl Channel { role_permissions: HashMap::new(), nsfw: data.nsfw.unwrap_or(false), voice: Some(data.voice.unwrap_or_default().into()), + slowmode: None }, }; diff --git a/crates/core/database/src/util/bridge/v0.rs b/crates/core/database/src/util/bridge/v0.rs index 0b2a55ef8..e5e888d60 100644 --- a/crates/core/database/src/util/bridge/v0.rs +++ b/crates/core/database/src/util/bridge/v0.rs @@ -190,6 +190,7 @@ impl From for Channel { role_permissions, nsfw, voice, + slowmode } => Channel::TextChannel { id, server, @@ -201,6 +202,7 @@ impl From for Channel { role_permissions, nsfw, voice: voice.map(|voice| voice.into()), + slowmode }, } } @@ -254,6 +256,7 @@ impl From for crate::Channel { role_permissions, nsfw, voice, + slowmode } => crate::Channel::TextChannel { id, server, @@ -265,6 +268,7 @@ impl From for crate::Channel { role_permissions, nsfw, voice: voice.map(|voice| voice.into()), + slowmode }, } } @@ -283,7 +287,8 @@ impl From for PartialChannel { role_permissions: value.role_permissions, default_permissions: value.default_permissions, last_message_id: value.last_message_id, - voice: value.voice.map(|voice| voice.into()) + voice: value.voice.map(|voice| voice.into()), + slowmode: value.slowmode, } } } @@ -301,7 +306,8 @@ impl From for crate::PartialChannel { role_permissions: value.role_permissions, default_permissions: value.default_permissions, last_message_id: value.last_message_id, - voice: value.voice.map(|voice| voice.into()) + voice: value.voice.map(|voice| voice.into()), + slowmode: value.slowmode } } } diff --git a/crates/core/models/src/v0/channels.rs b/crates/core/models/src/v0/channels.rs index d8b4e228d..d9fe8e14d 100644 --- a/crates/core/models/src/v0/channels.rs +++ b/crates/core/models/src/v0/channels.rs @@ -112,6 +112,10 @@ auto_derived!( /// Voice Information for when this channel is also a voice channel #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] voice: Option, + + /// The channel's slowmode delay in seconds + #[serde(skip_serializing_if = "Option::is_none")] + slowmode: Option, }, } @@ -150,6 +154,8 @@ auto_derived!( pub last_message_id: Option, #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] pub voice: Option, + #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + pub slowmode: Option, } /// Optional fields on channel object @@ -189,6 +195,10 @@ auto_derived!( /// Voice Information for voice channels pub voice: Option, + /// The channel's slow mode delay in seconds, up to 6 hours + #[cfg_attr(feature = "validator", validate(range(min = 0, max = 21600)))] + pub slowmode: Option, + /// Fields to remove from channel #[cfg_attr(feature = "serde", serde(default))] pub remove: Vec, diff --git a/crates/core/permissions/src/models/channel.rs b/crates/core/permissions/src/models/channel.rs index 450fda64c..fc6fe49a0 100644 --- a/crates/core/permissions/src/models/channel.rs +++ b/crates/core/permissions/src/models/channel.rs @@ -75,6 +75,8 @@ pub enum ChannelPermission { Masquerade = 1 << 28, /// React to messages with emojis React = 1 << 29, + /// Bypass slowmode + BypassSlowmode = 1 << 39, // * Voice permissions /// Connect to a voice channel @@ -99,7 +101,7 @@ pub enum ChannelPermission { MentionRoles = 1 << 38, // * Misc. permissions - // % Bits 38 to 52: free area + // % Bits 39 to 52: free area // % Bits 53 to 64: do not use // * Grant all permissions diff --git a/crates/core/result/src/axum.rs b/crates/core/result/src/axum.rs index 1145009c9..23b09f7b3 100644 --- a/crates/core/result/src/axum.rs +++ b/crates/core/result/src/axum.rs @@ -36,6 +36,9 @@ impl IntoResponse for Error { ErrorType::NotInGroup => StatusCode::NOT_FOUND, ErrorType::AlreadyPinned => StatusCode::BAD_REQUEST, ErrorType::NotPinned => StatusCode::BAD_REQUEST, + ErrorType::InSlowmode { + retry_after: _, + } => StatusCode::TOO_MANY_REQUESTS, ErrorType::CantCreateServers => StatusCode::FORBIDDEN, ErrorType::UnknownServer => StatusCode::NOT_FOUND, diff --git a/crates/core/result/src/lib.rs b/crates/core/result/src/lib.rs index 17093f962..e4907a6b5 100644 --- a/crates/core/result/src/lib.rs +++ b/crates/core/result/src/lib.rs @@ -102,6 +102,9 @@ pub enum ErrorType { NotInGroup, AlreadyPinned, NotPinned, + InSlowmode { + retry_after: u64, + }, // ? Server related errors CantCreateServers, diff --git a/crates/core/result/src/rocket.rs b/crates/core/result/src/rocket.rs index 744d09cfb..5d2904d03 100644 --- a/crates/core/result/src/rocket.rs +++ b/crates/core/result/src/rocket.rs @@ -42,6 +42,9 @@ impl<'r> Responder<'r, 'static> for Error { ErrorType::NotInGroup => Status::NotFound, ErrorType::AlreadyPinned => Status::BadRequest, ErrorType::NotPinned => Status::BadRequest, + ErrorType::InSlowmode { + retry_after: _, + } => Status::TooManyRequests, ErrorType::InvalidFlagValue => Status::BadRequest, ErrorType::CantCreateServers => Status::Forbidden, diff --git a/crates/delta/src/routes/channels/channel_edit.rs b/crates/delta/src/routes/channels/channel_edit.rs index e60664e01..25ead30b5 100644 --- a/crates/delta/src/routes/channels/channel_edit.rs +++ b/crates/delta/src/routes/channels/channel_edit.rs @@ -41,6 +41,7 @@ pub async fn edit( && data.nsfw.is_none() && data.owner.is_none() && data.voice.is_none() + && data.slowmode.is_none() && data.remove.is_empty() { return Ok(Json(channel.into())); @@ -200,6 +201,7 @@ pub async fn edit( icon, nsfw, voice, + slowmode, .. } => { if data.remove.contains(&v0::FieldsChannel::Icon) { @@ -247,6 +249,11 @@ pub async fn edit( *voice = Some(new_voice.clone().into()); partial.voice = Some(new_voice.into()); } + + if let Some(new_slowmode) = data.slowmode { + *slowmode = Some(new_slowmode); + partial.slowmode = Some(new_slowmode); + } } _ => return Err(create_error!(InvalidOperation)), }; diff --git a/crates/delta/src/routes/channels/message_send.rs b/crates/delta/src/routes/channels/message_send.rs index d0479fa1a..51dd57136 100644 --- a/crates/delta/src/routes/channels/message_send.rs +++ b/crates/delta/src/routes/channels/message_send.rs @@ -1,9 +1,10 @@ use chrono::{Duration, Utc}; +use redis_kiss::{get_connection, redis, AsyncCommands}; use revolt_database::util::permissions::DatabasePermissionQuery; use revolt_database::{ util::idempotency::IdempotencyKey, util::reference::Reference, Database, User, }; -use revolt_database::{Interactions, Message, AMQP}; +use revolt_database::{Channel, Interactions, Message, AMQP}; use revolt_models::v0; use revolt_permissions::PermissionQuery; use revolt_permissions::{calculate_channel_permissions, ChannelPermission}; @@ -57,6 +58,50 @@ pub async fn message_send( permissions.throw_if_lacking_channel_permission(ChannelPermission::UploadFiles)?; } + if !permissions.has_channel_permission(ChannelPermission::BypassSlowmode) { + if let Channel::TextChannel { + slowmode: Some(channel_slowmode), + id: channel_id, + .. + } = &channel + { + if *channel_slowmode > 0 { + if let Ok(conn) = get_connection().await { + let mut conn = conn.into_inner(); + + let slowmode_key = format!("slowmode:{}:{}", user.id, channel_id); + + // Atomic check-and-set: only set if absent and apply expiry in one command. + let set_result: Option = conn + .set_options( + &slowmode_key, + "1", // The value doesn't matter, only the key's existence + redis::SetOptions::default() + .conditional_set(redis::ExistenceCheck::NX) + .with_expiration(redis::SetExpiry::EX(*channel_slowmode as usize)), + ) + .await + .unwrap_or(None); + + // If `set_result` is None, the `NX` condition failed because the key already exists. + // This means the user is currently in slowmode. + if set_result.is_none() { + // Fetch the remaining TTL to accurately populate the retry_after field + let ttl: i64 = conn.ttl(&slowmode_key).await.unwrap_or(0); + + // Redis returns positive integers for valid TTLs + if ttl > 0 { + return Err(create_error!(InSlowmode { + retry_after: ttl as u64 + })); + } + } + } + // If Redis connection fails, just skip the slowmode check + } + } + } + // Ensure interactions information is correct if let Some(interactions) = &data.interactions { let interactions: Interactions = interactions.clone().into(); @@ -186,6 +231,7 @@ mod test { }), last_message_id: None, voice: None, + slowmode: None, }; locked_channel .update(&harness.db, partial, vec![]) From d1e72cee42c54e16f4e49af569897528b10a28ca Mon Sep 17 00:00:00 2001 From: Tom Date: Fri, 27 Mar 2026 17:15:05 -0700 Subject: [PATCH 125/211] feat: parse message push notification content and replace internal formatting (#693) * parse message push notification content and replace internal formatting Signed-off-by: IAmTomahawkx * fix: don't unwrap the error I was using for db debugging Signed-off-by: IAmTomahawkx * fix: emojis & remove compiler warning Signed-off-by: IAmTomahawkx * fix: emojis in pushd Signed-off-by: IAmTomahawkx * feat: report errors in the render function to sentry Signed-off-by: IAmTomahawkx --------- Signed-off-by: IAmTomahawkx --- Cargo.lock | 11 +- crates/core/config/Revolt.toml | 5 + crates/core/config/src/lib.rs | 1 + .../database/src/models/messages/model.rs | 1 + crates/core/models/src/v0/messages.rs | 9 +- crates/core/parser/src/lib.rs | 173 ++++++++--- crates/daemons/pushd/Cargo.toml | 4 + .../src/consumers/inbound/mass_mention.rs | 15 +- .../pushd/src/consumers/inbound/message.rs | 13 +- crates/daemons/pushd/src/main.rs | 1 + crates/daemons/pushd/src/utils/mod.rs | 2 + crates/daemons/pushd/src/utils/renderer.rs | 272 ++++++++++++++++++ 12 files changed, 453 insertions(+), 54 deletions(-) create mode 100644 crates/daemons/pushd/src/utils/mod.rs create mode 100644 crates/daemons/pushd/src/utils/renderer.rs diff --git a/Cargo.lock b/Cargo.lock index ac4ed100a..c68b822fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6660,9 +6660,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.2" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" dependencies = [ "aho-corasick", "memchr", @@ -6672,9 +6672,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.10" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" dependencies = [ "aho-corasick", "memchr", @@ -7149,9 +7149,12 @@ dependencies = [ "iso8601-timestamp", "log", "pretty_env_logger", + "redis-kiss", + "regex", "revolt-config", "revolt-database", "revolt-models", + "revolt-parser", "revolt-presence", "revolt-result", "revolt_a2", diff --git a/crates/core/config/Revolt.toml b/crates/core/config/Revolt.toml index 289ab0df9..3bb331118 100644 --- a/crates/core/config/Revolt.toml +++ b/crates/core/config/Revolt.toml @@ -89,6 +89,11 @@ production = true # Increasing this will resolve mentions faster, but will consume more memory while resolving. mass_mention_chunk_size = 200 +# How long pushd will cache resolved names for rendered message notifications. +# Increasing this will result in lower database usage, but may result in a situation where a user/channel/role name changes +# and the notifications still resolve to the old name. +render_cache_time = 60 + # none of these should need changing exchange = "revolt.notifications" message_queue = "notifications.origin.message" diff --git a/crates/core/config/src/lib.rs b/crates/core/config/src/lib.rs index 6183cca94..b9e60a4f8 100644 --- a/crates/core/config/src/lib.rs +++ b/crates/core/config/src/lib.rs @@ -248,6 +248,7 @@ pub struct Pushd { pub production: bool, pub exchange: String, pub mass_mention_chunk_size: usize, + pub render_cache_time: usize, // Queues pub message_queue: String, diff --git a/crates/core/database/src/models/messages/model.rs b/crates/core/database/src/models/messages/model.rs index 3db6df49f..fc417d791 100644 --- a/crates/core/database/src/models/messages/model.rs +++ b/crates/core/database/src/models/messages/model.rs @@ -388,6 +388,7 @@ impl Message { mut role_mentions, mut mentions_everyone, mut mentions_online, + .. } = message_mentions; if allow_mass_mentions && server_id.is_some() && !role_mentions.is_empty() { diff --git a/crates/core/models/src/v0/messages.rs b/crates/core/models/src/v0/messages.rs index 67af69f85..e11831757 100644 --- a/crates/core/models/src/v0/messages.rs +++ b/crates/core/models/src/v0/messages.rs @@ -133,7 +133,10 @@ auto_derived!( #[serde(rename = "message_unpinned")] MessageUnpinned { id: String, by: String }, #[serde(rename = "call_started")] - CallStarted { by: String, finished_at: Option }, + CallStarted { + by: String, + finished_at: Option, + }, } /// Name and / or avatar override information @@ -201,6 +204,9 @@ auto_derived!( pub image: Option, /// Message content or system message information pub body: String, + /// The raw body, if the body has been rendered + #[serde(skip_serializing_if = "Option::is_none")] + pub raw_body: Option, /// Unique tag, usually the channel ID pub tag: String, /// Timestamp at which this notification was created @@ -508,6 +514,7 @@ impl PushNotification { icon, image, body, + raw_body: None, tag: channel.id().to_string(), timestamp, url: format!("{}/channel/{}/{}", config.hosts.app, channel.id(), msg.id), diff --git a/crates/core/parser/src/lib.rs b/crates/core/parser/src/lib.rs index 4ebbac630..bb5b50d7c 100644 --- a/crates/core/parser/src/lib.rs +++ b/crates/core/parser/src/lib.rs @@ -16,23 +16,29 @@ pub enum MessageToken<'a> { UserMention(&'a str), #[regex("<%(?&id)>", |lex| &lex.slice()[2..lex.slice().len() - 1],)] RoleMention(&'a str), + #[regex("<#(?&id)>", |lex| &lex.slice()[2..lex.slice().len() - 1],)] + ChannelMention(&'a str), + #[regex(":(?&id):", |lex| &lex.slice()[1..lex.slice().len() - 1],)] + Emoji(&'a str), #[token("@everyone")] MentionEveryone, #[token("@online")] - MentionOnline + MentionOnline, } #[derive(Debug, Clone, PartialEq, Default)] pub struct MessageResults { pub user_mentions: HashSet, pub role_mentions: HashSet, + pub channel_mentions: HashSet, + pub emojis: HashSet, pub mentions_everyone: bool, - pub mentions_online: bool + pub mentions_online: bool, } struct MessageParserIterator<'a, I> { inner: I, - temp: VecDeque> + temp: VecDeque>, } impl<'a, I: Iterator>> Iterator for MessageParserIterator<'a, I> { @@ -55,11 +61,11 @@ impl<'a, I: Iterator>> Iterator for MessageParserIterato if next_token == Some(MessageToken::CodeblockMarker(ty)) { self.temp.clear(); self.temp.push_back(MessageToken::CodeblockMarker(ty)); - break next_token + break next_token; } else if let Some(token) = next_token { self.temp.push_back(token); } else { - break Some(MessageToken::CodeblockMarker(ty)) + break Some(MessageToken::CodeblockMarker(ty)); } } } else { @@ -69,10 +75,10 @@ impl<'a, I: Iterator>> Iterator for MessageParserIterato } } -pub fn parse_message_iter(text: &str) -> impl Iterator + '_ { +pub fn parse_message_iter(text: &str) -> impl Iterator> + '_ { MessageParserIterator { inner: MessageToken::lexer(text).flatten(), - temp: VecDeque::new() + temp: VecDeque::new(), } } @@ -82,13 +88,23 @@ pub fn parse_message(text: &str) -> MessageResults { for token in parse_message_iter(text) { match token { MessageToken::Escape => {} - MessageToken::CodeblockMarker(_) => {}, - MessageToken::UserMention(id) => { results.user_mentions.insert(id.to_string()); }, - MessageToken::RoleMention(id) => { results.role_mentions.insert(id.to_string()); }, + MessageToken::CodeblockMarker(_) => {} + MessageToken::UserMention(id) => { + results.user_mentions.insert(id.to_string()); + } + MessageToken::RoleMention(id) => { + results.role_mentions.insert(id.to_string()); + } + MessageToken::ChannelMention(id) => { + results.channel_mentions.insert(id.to_string()); + } + MessageToken::Emoji(id) => { + results.emojis.insert(id.to_string()); + } MessageToken::MentionEveryone => results.mentions_everyone = true, MessageToken::MentionOnline => results.mentions_online = true, }; - }; + } results } @@ -109,7 +125,10 @@ mod tests { let output = parse_message_iter("Hello <@01FD58YK5W7QRV5H3D64KTQYX3>.").collect::>(); assert_eq!(output.len(), 1); - assert_eq!(output[0], MessageToken::UserMention("01FD58YK5W7QRV5H3D64KTQYX3")); + assert_eq!( + output[0], + MessageToken::UserMention("01FD58YK5W7QRV5H3D64KTQYX3") + ); } #[test] @@ -117,7 +136,10 @@ mod tests { let output = parse_message_iter("Hello <%01FD58YK5W7QRV5H3D64KTQYX3>.").collect::>(); assert_eq!(output.len(), 1); - assert_eq!(output[0], MessageToken::RoleMention("01FD58YK5W7QRV5H3D64KTQYX3")); + assert_eq!( + output[0], + MessageToken::RoleMention("01FD58YK5W7QRV5H3D64KTQYX3") + ); } #[test] @@ -138,29 +160,57 @@ mod tests { #[test] fn test_everything() { - let output = parse_message_iter("Hello <@01FD58YK5W7QRV5H3D64KTQYX3>, <%01FD58YK5W7QRV5H3D64KTQYX3>, @everyone and @online.").collect::>(); - - assert_eq!(output.len(), 4); - assert_eq!(output[0], MessageToken::UserMention("01FD58YK5W7QRV5H3D64KTQYX3")); - assert_eq!(output[1], MessageToken::RoleMention("01FD58YK5W7QRV5H3D64KTQYX3")); - assert_eq!(output[2], MessageToken::MentionEveryone); - assert_eq!(output[3], MessageToken::MentionOnline); + let output = parse_message_iter("Hello <@01FD58YK5W7QRV5H3D64KTQYX3>, <%01FD58YK5W7QRV5H3D64KTQYX3>, <#01FD58YK5W7QRV5H3D64KTQYX3> @everyone and @online. :01FD58YK5W7QRV5H3D64KTQYX3:").collect::>(); + + assert_eq!(output.len(), 6); + assert_eq!( + output[0], + MessageToken::UserMention("01FD58YK5W7QRV5H3D64KTQYX3") + ); + assert_eq!( + output[1], + MessageToken::RoleMention("01FD58YK5W7QRV5H3D64KTQYX3") + ); + assert_eq!( + output[2], + MessageToken::ChannelMention("01FD58YK5W7QRV5H3D64KTQYX3") + ); + assert_eq!(output[3], MessageToken::MentionEveryone); + assert_eq!(output[4], MessageToken::MentionOnline); + assert_eq!(output[5], MessageToken::Emoji("01FD58YK5W7QRV5H3D64KTQYX3")); } #[test] fn test_everything_no_spaces() { - let output = parse_message_iter("<@01FD58YK5W7QRV5H3D64KTQYX3><%01FD58YK5W7QRV5H3D64KTQYX3>@everyone@online").collect::>(); - - assert_eq!(output.len(), 4); - assert_eq!(output[0], MessageToken::UserMention("01FD58YK5W7QRV5H3D64KTQYX3")); - assert_eq!(output[1], MessageToken::RoleMention("01FD58YK5W7QRV5H3D64KTQYX3")); - assert_eq!(output[2], MessageToken::MentionEveryone); - assert_eq!(output[3], MessageToken::MentionOnline); + let output = parse_message_iter( + "<@01FD58YK5W7QRV5H3D64KTQYX3><%01FD58YK5W7QRV5H3D64KTQYX3><#01FD58YK5W7QRV5H3D64KTQYX3>@everyone@online:01FD58YK5W7QRV5H3D64KTQYX3:", + ) + .collect::>(); + + assert_eq!(output.len(), 6); + assert_eq!( + output[0], + MessageToken::UserMention("01FD58YK5W7QRV5H3D64KTQYX3") + ); + assert_eq!( + output[1], + MessageToken::RoleMention("01FD58YK5W7QRV5H3D64KTQYX3") + ); + assert_eq!( + output[2], + MessageToken::ChannelMention("01FD58YK5W7QRV5H3D64KTQYX3") + ); + assert_eq!(output[3], MessageToken::MentionEveryone); + assert_eq!(output[4], MessageToken::MentionOnline); + assert_eq!(output[5], MessageToken::Emoji("01FD58YK5W7QRV5H3D64KTQYX3")); } #[test] fn test_codeblock_no_mentions() { - let output = parse_message_iter("```\n<@01FD58YK5W7QRV5H3D64KTQYX3><%01FD58YK5W7QRV5H3D64KTQYX3>@everyone@online\n```").collect::>(); + let output = parse_message_iter( + "```\n<@01FD58YK5W7QRV5H3D64KTQYX3><%01FD58YK5W7QRV5H3D64KTQYX3><#01FD58YK5W7QRV5H3D64KTQYX3>@everyone@online:01FD58YK5W7QRV5H3D64KTQYX3:\n```", + ) + .collect::>(); assert_eq!(output.len(), 2); assert_eq!(output[0], MessageToken::CodeblockMarker(3)); @@ -169,19 +219,36 @@ mod tests { #[test] fn test_uncontained_codeblock_should_mention() { - let output = parse_message_iter("```\n<@01FD58YK5W7QRV5H3D64KTQYX3><%01FD58YK5W7QRV5H3D64KTQYX3>@everyone@online").collect::>(); + let output = parse_message_iter( + "```\n<@01FD58YK5W7QRV5H3D64KTQYX3><%01FD58YK5W7QRV5H3D64KTQYX3><#01FD58YK5W7QRV5H3D64KTQYX3>@everyone@online:01FD58YK5W7QRV5H3D64KTQYX3:", + ) + .collect::>(); - assert_eq!(output.len(), 5); + assert_eq!(output.len(), 7); assert_eq!(output[0], MessageToken::CodeblockMarker(3)); - assert_eq!(output[1], MessageToken::UserMention("01FD58YK5W7QRV5H3D64KTQYX3")); - assert_eq!(output[2], MessageToken::RoleMention("01FD58YK5W7QRV5H3D64KTQYX3")); - assert_eq!(output[3], MessageToken::MentionEveryone); - assert_eq!(output[4], MessageToken::MentionOnline); + assert_eq!( + output[1], + MessageToken::UserMention("01FD58YK5W7QRV5H3D64KTQYX3") + ); + assert_eq!( + output[2], + MessageToken::RoleMention("01FD58YK5W7QRV5H3D64KTQYX3") + ); + assert_eq!( + output[3], + MessageToken::ChannelMention("01FD58YK5W7QRV5H3D64KTQYX3") + ); + assert_eq!(output[4], MessageToken::MentionEveryone); + assert_eq!(output[5], MessageToken::MentionOnline); + assert_eq!(output[6], MessageToken::Emoji("01FD58YK5W7QRV5H3D64KTQYX3")); } #[test] fn test_inline_codeblock_no_mentions() { - let output = parse_message_iter("`<@01FD58YK5W7QRV5H3D64KTQYX3><%01FD58YK5W7QRV5H3D64KTQYX3>@everyone@online`").collect::>(); + let output = parse_message_iter( + "`<@01FD58YK5W7QRV5H3D64KTQYX3><%01FD58YK5W7QRV5H3D64KTQYX3><#01FD58YK5W7QRV5H3D64KTQYX3>@everyone@online:01FD58YK5W7QRV5H3D64KTQYX3:`", + ) + .collect::>(); assert_eq!(output.len(), 2); assert_eq!(output[0], MessageToken::CodeblockMarker(1)); @@ -190,19 +257,33 @@ mod tests { #[test] fn test_uncontained_inline_codeblock_should_mention() { - let output = parse_message_iter("`<@01FD58YK5W7QRV5H3D64KTQYX3><%01FD58YK5W7QRV5H3D64KTQYX3>@everyone@online").collect::>(); + let output = parse_message_iter( + "`<@01FD58YK5W7QRV5H3D64KTQYX3><%01FD58YK5W7QRV5H3D64KTQYX3><#01FD58YK5W7QRV5H3D64KTQYX3>@everyone@online:01FD58YK5W7QRV5H3D64KTQYX3:", + ) + .collect::>(); - assert_eq!(output.len(), 5); + assert_eq!(output.len(), 6); assert_eq!(output[0], MessageToken::CodeblockMarker(1)); - assert_eq!(output[1], MessageToken::UserMention("01FD58YK5W7QRV5H3D64KTQYX3")); - assert_eq!(output[2], MessageToken::RoleMention("01FD58YK5W7QRV5H3D64KTQYX3")); - assert_eq!(output[3], MessageToken::MentionEveryone); - assert_eq!(output[4], MessageToken::MentionOnline); + assert_eq!( + output[1], + MessageToken::UserMention("01FD58YK5W7QRV5H3D64KTQYX3") + ); + assert_eq!( + output[2], + MessageToken::RoleMention("01FD58YK5W7QRV5H3D64KTQYX3") + ); + assert_eq!( + output[3], + MessageToken::ChannelMention("01FD58YK5W7QRV5H3D64KTQYX3") + ); + assert_eq!(output[4], MessageToken::MentionEveryone); + assert_eq!(output[5], MessageToken::MentionOnline); + assert_eq!(output[6], MessageToken::Emoji("01FD58YK5W7QRV5H3D64KTQYX3")); } #[test] fn test_codeblock_with_language_no_mentions() { - let output = parse_message_iter("```rust\n<@01FD58YK5W7QRV5H3D64KTQYX3><%01FD58YK5W7QRV5H3D64KTQYX3>@everyone@online```").collect::>(); + let output = parse_message_iter("```rust\n<@01FD58YK5W7QRV5H3D64KTQYX3><%01FD58YK5W7QRV5H3D64KTQYX3><#01FD58YK5W7QRV5H3D64KTQYX3>@everyone@online:01FD58YK5W7QRV5H3D64KTQYX3:```").collect::>(); assert_eq!(output.len(), 2); assert_eq!(output[0], MessageToken::CodeblockMarker(3)); @@ -220,7 +301,8 @@ mod tests { #[test] fn test_double_inline_codeblock_with_backticks_inside() { - let output = parse_message_iter("``this `should` not `ping` @everyone``").collect::>(); + let output = + parse_message_iter("``this `should` not `ping` @everyone``").collect::>(); assert_eq!(output.len(), 2); assert_eq!(output[0], MessageToken::CodeblockMarker(2)); @@ -238,7 +320,8 @@ mod tests { #[test] fn test_escaped_codeblock() { - let output = parse_message_iter("i am ~~not~~ pinging \\`@everyone` ok.").collect::>(); + let output = + parse_message_iter("i am ~~not~~ pinging \\`@everyone` ok.").collect::>(); assert_eq!(output.len(), 3); assert_eq!(output[0], MessageToken::Escape); @@ -253,4 +336,4 @@ mod tests { assert_eq!(output.len(), 1); assert_eq!(output[0], MessageToken::Escape); } -} \ No newline at end of file +} diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index 6efb02ba5..9ea3d8867 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -18,6 +18,7 @@ revolt-models = { version = "0.11.5", path = "../../core/models", features = [ revolt-presence = { version = "0.11.5", path = "../../core/presence", features = [ "redis-is-patched", ] } +revolt-parser = { version = "0.11.5", path = "../../core/parser" } anyhow = { version = "1.0.98" } @@ -26,6 +27,7 @@ fcm_v1 = "0.3.0" web-push = "0.10.0" isahc = { optional = true, version = "1.7", features = ["json"] } revolt_a2 = { version = "0.10", default-features = false, features = ["ring"] } +redis-kiss = "0.1.4" tokio = "1.39.2" async-trait = "0.1.81" ulid = "1.0.0" @@ -35,6 +37,8 @@ authifier = "1.0.16" log = "0.4.11" pretty_env_logger = "0.4.0" +regex = "1.12.3" + #serialization serde_json = "1" revolt_optional_struct = "0.2.0" diff --git a/crates/daemons/pushd/src/consumers/inbound/mass_mention.rs b/crates/daemons/pushd/src/consumers/inbound/mass_mention.rs index cb6f3c445..8d43cce8c 100644 --- a/crates/daemons/pushd/src/consumers/inbound/mass_mention.rs +++ b/crates/daemons/pushd/src/consumers/inbound/mass_mention.rs @@ -3,7 +3,7 @@ use std::{ hash::RandomState, }; -use crate::consumers::inbound::internal::*; +use crate::{consumers::inbound::internal::*, utils}; use amqprs::{ channel::{BasicPublishArguments, Channel}, connection::Connection, @@ -17,6 +17,7 @@ use revolt_database::{ MessageFlagsValue, }; use revolt_models::v0::{MessageFlags, PushNotification}; +use revolt_result::ToRevoltError; pub struct MassMessageConsumer { #[allow(dead_code)] @@ -129,7 +130,17 @@ impl MassMessageConsumer { ) -> Result<()> { let config = revolt_config::config().await; let content = String::from_utf8(content)?; - let payload: MassMessageSentPayload = serde_json::from_str(content.as_str())?; + let mut payload: MassMessageSentPayload = serde_json::from_str(content.as_str())?; + + for push in payload.notifications.iter_mut() { + if let Ok(body) = utils::render_notification_content(push, &self.db) + .await + .to_internal_error() + { + push.raw_body = Some(push.body.clone()); + push.body = body; + } + } debug!("Received mass message event"); diff --git a/crates/daemons/pushd/src/consumers/inbound/message.rs b/crates/daemons/pushd/src/consumers/inbound/message.rs index 420c37076..45de0b0b4 100644 --- a/crates/daemons/pushd/src/consumers/inbound/message.rs +++ b/crates/daemons/pushd/src/consumers/inbound/message.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use crate::consumers::inbound::internal::*; +use crate::{consumers::inbound::internal::*, utils}; use amqprs::{ channel::{BasicPublishArguments, Channel}, connection::Connection, @@ -11,6 +11,7 @@ use anyhow::Result; use async_trait::async_trait; use log::debug; use revolt_database::{events::rabbit::*, Database}; +use revolt_result::ToRevoltError; pub struct MessageConsumer { #[allow(dead_code)] @@ -64,7 +65,15 @@ impl MessageConsumer { content: Vec, ) -> Result<()> { let content = String::from_utf8(content)?; - let payload: MessageSentPayload = serde_json::from_str(content.as_str())?; + let mut payload: MessageSentPayload = serde_json::from_str(content.as_str())?; + + if let Ok(body) = utils::render_notification_content(&payload.notification, &self.db) + .await + .to_internal_error() + { + payload.notification.raw_body = Some(payload.notification.body); + payload.notification.body = body; + } debug!("Received message event on origin"); diff --git a/crates/daemons/pushd/src/main.rs b/crates/daemons/pushd/src/main.rs index 472caafe4..eaa2e1b81 100644 --- a/crates/daemons/pushd/src/main.rs +++ b/crates/daemons/pushd/src/main.rs @@ -14,6 +14,7 @@ use revolt_config::{config, Settings}; use tokio::sync::Notify; mod consumers; +mod utils; use consumers::{ inbound::{ ack::AckConsumer, dm_call::DmCallConsumer, fr_accepted::FRAcceptedConsumer, diff --git a/crates/daemons/pushd/src/utils/mod.rs b/crates/daemons/pushd/src/utils/mod.rs new file mode 100644 index 000000000..62032e80b --- /dev/null +++ b/crates/daemons/pushd/src/utils/mod.rs @@ -0,0 +1,2 @@ +mod renderer; +pub use renderer::render_notification_content; diff --git a/crates/daemons/pushd/src/utils/renderer.rs b/crates/daemons/pushd/src/utils/renderer.rs new file mode 100644 index 000000000..ef16c9d8f --- /dev/null +++ b/crates/daemons/pushd/src/utils/renderer.rs @@ -0,0 +1,272 @@ +use redis_kiss::{get_connection as _get_conn, AsyncCommands, Conn}; +use regex::Regex; +use revolt_config::config; +use revolt_database::{Channel, Database}; +use revolt_models::v0::PushNotification; +use revolt_parser::parse_message; +use revolt_result::{create_error, Result, ToRevoltError}; +use std::{ + borrow::Cow, + collections::{HashMap, HashSet}, +}; +use tokio::join; + +async fn get_connection() -> Result { + _get_conn().await.map_err(|_| create_error!(InternalError)) +} + +pub async fn render_notification_content( + notification: &PushNotification, + db: &Database, +) -> Result { + let parsed = parse_message(¬ification.body); + + let user_mentions: HashMap; + let channel_mentions: HashMap; + let emojis: HashMap; + let roles: HashMap; + + let server_id: Option = get_channel_server_id(notification.channel.id(), db) + .await + .map(Some) + .or(Ok(None))?; + + if server_id.is_some() { + (user_mentions, channel_mentions, emojis, roles) = join!( + get_items( + parsed.user_mentions, + server_id.as_deref(), + db, + get_user_display_name, + "Unknown User".to_string() + ), + get_items( + parsed.channel_mentions, + server_id.as_deref(), + db, + get_channel_name, + "Unknown Channel".to_string() + ), + get_items( + parsed.emojis, + server_id.as_deref(), + db, + get_emoji_name, + "Unknown Emoji".to_string() + ), + get_items( + parsed.role_mentions, + server_id.as_deref(), + db, + get_role_name, + "Unknown Role".to_string() + ), + ); + } else { + roles = HashMap::default(); + + (user_mentions, channel_mentions, emojis) = join!( + get_items( + parsed.user_mentions, + server_id.as_deref(), + db, + get_user_display_name, + "Unknown User".to_string() + ), + get_items( + parsed.channel_mentions, + server_id.as_deref(), + db, + get_channel_name, + "Unknown Channel".to_string() + ), + get_items( + parsed.emojis, + server_id.as_deref(), + db, + get_emoji_name, + "Unknown Emoji".to_string() + ), + ); + } + + let mut body = Cow::Borrowed(notification.body.as_str()); + + for (uid, name) in user_mentions { + replace_all_in_place( + Regex::new(format!("<@{uid}>").as_str()).unwrap(), + &mut body, + format!("@{name}").as_str(), + ); + } + + for (uid, name) in channel_mentions { + replace_all_in_place( + Regex::new(format!("<#{uid}>").as_str()).unwrap(), + &mut body, + format!("#{name}").as_str(), + ); + } + + for (uid, name) in roles { + replace_all_in_place( + Regex::new(format!("<%{uid}>").as_str()).unwrap(), + &mut body, + format!("%{name}").as_str(), + ); + } + + for (uid, name) in emojis { + replace_all_in_place( + Regex::new(format!(":{uid}:").as_str()).unwrap(), + &mut body, + format!(":{name}:").as_str(), + ); + } + + Ok(body.to_string()) +} + +async fn get_items( + items: HashSet, + server_id: Option<&str>, + db: &Database, + getter: F, + invalid_string: String, +) -> HashMap +where + F: AsyncFn(&str, Option<&str>, &Database) -> Result, +{ + let mut resp = HashMap::default(); + + for obj_id in items { + resp.insert( + obj_id.clone(), + getter(&obj_id, server_id, db) + .await + .unwrap_or(invalid_string.clone()), + ); + } + + resp +} + +// Getters + +async fn get_user_display_name(id: &str, server: Option<&str>, db: &Database) -> Result { + let config = config().await; + + let mut conn = get_connection().await?; + let key = format!("pushd-user-cache:{}:{id}", server.unwrap_or("GLOBAL")); + + if let Ok(name) = conn.get(key.clone()).await { + return Ok(name); + } + + if let Some(server) = server { + let member = db.fetch_member(server, id).await?; + if let Some(nickname) = member.nickname { + conn.set_ex::<_, _, ()>(key, nickname.clone(), config.pushd.render_cache_time) + .await + .to_internal_error()?; + return Ok(nickname); + } + } + + let user = db.fetch_user(id).await?; + let name = user.display_name.unwrap_or(user.username); + + conn.set_ex::<_, _, ()>(key, name.clone(), config.pushd.render_cache_time) + .await + .to_internal_error()?; + + Ok(name) +} + +async fn get_channel_name(id: &str, _server: Option<&str>, db: &Database) -> Result { + let config = config().await; + + let mut conn = get_connection().await?; + let key = format!("pushd-channel-cache:{id}"); + + if let Ok(name) = conn.get(key.clone()).await { + return Ok(name); + } + + let channel = db.fetch_channel(id).await?; + let name = match channel { + Channel::DirectMessage { .. } => "DM Channel".to_string(), + Channel::Group { name, .. } | Channel::TextChannel { name, .. } => name, + Channel::SavedMessages { .. } => "Err".to_string(), + }; + + conn.set_ex::<_, _, ()>(key, name.clone(), config.pushd.render_cache_time) + .await + .to_internal_error()?; + + Ok(name) +} + +async fn get_role_name(id: &str, server: Option<&str>, db: &Database) -> Result { + let server = server.unwrap(); // Must be passed, but the interface must stay the same as the other getters + let config: revolt_config::Settings = config().await; + + let mut conn = get_connection().await?; + let key = format!("pushd-role-cache:{server}:{id}"); + + if let Ok(name) = conn.get(key.clone()).await { + return Ok(name); + } + + let server = db.fetch_server(server).await?; + let name = server + .roles + .get(id) + .ok_or_else(|| create_error!(NotFound))? + .name + .clone(); + + conn.set_ex::<_, _, ()>(key, name.clone(), config.pushd.render_cache_time) + .await + .to_internal_error()?; + + Ok(name) +} + +async fn get_emoji_name(id: &str, _server: Option<&str>, db: &Database) -> Result { + let config: revolt_config::Settings = config().await; + + let mut conn = get_connection().await?; + let key = format!("pushd-emoji-cache:{id}"); + + if let Ok(name) = conn.get(key.clone()).await { + return Ok(name); + } + + let emoji = db.fetch_emoji(id).await?; + let name = emoji.name; + + conn.set_ex::<_, _, ()>(key, name.clone(), config.pushd.render_cache_time) + .await + .to_internal_error()?; + + Ok(name) +} + +// utility + +async fn get_channel_server_id(channel_id: &str, db: &Database) -> Result { + match db.fetch_channel(channel_id).await? { + Channel::DirectMessage { .. } | Channel::Group { .. } | Channel::SavedMessages { .. } => { + Err(create_error!(NotFound)) + } + Channel::TextChannel { server, .. } => Ok(server), + } +} + +fn replace_all_in_place(regex: Regex, s: &mut Cow<'_, str>, replacer: R) { + let new = regex.replace_all(s, replacer); + if let Cow::Owned(o) = new { + *s = Cow::Owned(o); + } +} From 735d644e043793cb86e74aab5b88bb4b8bc17ba2 Mon Sep 17 00:00:00 2001 From: LazyCat <68156188+LazyCat2@users.noreply.github.com> Date: Sat, 28 Mar 2026 03:24:53 +0300 Subject: [PATCH 126/211] feat: Transfer ownership (#396) * feat: Transfer ownership Signed-off-by: LazyCat2 <68156188+LazyCat2@users.noreply.github.com> * Allow privileged users to change ownership Signed-off-by: LazyCat2 <68156188+LazyCat2@users.noreply.github.com> * Require TOTP Signed-off-by: LazyCat2 <68156188+LazyCat2@users.noreply.github.com> * Require TOTP or password Signed-off-by: LazyCat2 <68156188+LazyCat2@users.noreply.github.com> --------- Signed-off-by: LazyCat2 <68156188+LazyCat2@users.noreply.github.com> Signed-off-by: Tom Co-authored-by: Tom --- crates/core/models/src/v0/servers.rs | 3 ++ .../delta/src/routes/servers/server_edit.rs | 34 ++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/crates/core/models/src/v0/servers.rs b/crates/core/models/src/v0/servers.rs index 0d330334c..d9835443c 100644 --- a/crates/core/models/src/v0/servers.rs +++ b/crates/core/models/src/v0/servers.rs @@ -252,6 +252,9 @@ auto_derived!( /// Must be enabled in order to show up on [Revolt Discover](https://rvlt.gg). pub analytics: Option, + /// User id of the new owner + pub owner: Option, + /// Fields to remove from server object #[cfg_attr(feature = "serde", serde(default))] pub remove: Vec, diff --git a/crates/delta/src/routes/servers/server_edit.rs b/crates/delta/src/routes/servers/server_edit.rs index 23d79c344..3c9a6d1bc 100644 --- a/crates/delta/src/routes/servers/server_edit.rs +++ b/crates/delta/src/routes/servers/server_edit.rs @@ -1,5 +1,6 @@ use std::collections::HashSet; +use authifier::models::{totp::Totp, Account, ValidatedTicket}; use revolt_database::{ util::{permissions::DatabasePermissionQuery, reference::Reference}, Database, File, PartialServer, User, @@ -7,7 +8,7 @@ use revolt_database::{ use revolt_models::v0; use revolt_permissions::{calculate_server_permissions, ChannelPermission}; use revolt_result::{create_error, Result}; -use rocket::{serde::json::Json, State}; +use rocket::{serde::json::Json, Request, State}; use validator::Validate; /// # Edit Server @@ -17,9 +18,11 @@ use validator::Validate; #[patch("/", data = "")] pub async fn edit( db: &State, + account: Account, user: User, target: Reference<'_>, data: Json, + validated_ticket: Option, ) -> Result> { let data = data.into_inner(); data.validate().map_err(|error| { @@ -43,6 +46,7 @@ pub async fn edit( && data.flags.is_none() && data.analytics.is_none() && data.discoverable.is_none() + && data.owner.is_none() && data.remove.is_empty() { return Ok(Json(server.into())); @@ -57,6 +61,17 @@ pub async fn edit( permissions.throw_if_lacking_channel_permission(ChannelPermission::ManageServer)?; } + // Check we are the server owner or privileged if changing sensitive fields + if data.owner.is_some() { + if user.id != server.owner && !user.privileged { + return Err(create_error!(NotOwner)); + } + + if validated_ticket.is_none() { + return Err(create_error!(InvalidCredentials)); + } + } + // Check we are privileged if changing sensitive fields if (data.flags.is_some() /*|| data.nsfw.is_some()*/ || data.discoverable.is_some()) && !user.privileged @@ -80,6 +95,7 @@ pub async fn edit( // nsfw, discoverable, analytics, + owner, remove, } = data; @@ -92,6 +108,7 @@ pub async fn edit( // nsfw, discoverable, analytics, + owner: owner.clone(), ..Default::default() }; @@ -146,6 +163,21 @@ pub async fn edit( server.banner = partial.banner.clone(); } + // 5. Transfer ownership + if let Some(owner) = owner { + let owner_reference = Reference { id: owner.clone() }; + // Check if member exists + owner_reference.as_member(db, &server.id).await?; + let owner_user = owner_reference.as_user(db).await?; + + if owner_user.bot.is_some() { + return Err(create_error!(InvalidOperation)); + } + + server.owner = owner; + partial.owner = Some(server.owner.clone()); + } + server .update(db, partial, remove.into_iter().map(Into::into).collect()) .await?; From 91783b906697fc85305dee683f7c15dda55f0c50 Mon Sep 17 00:00:00 2001 From: Angelo Kontaxis Date: Sat, 28 Mar 2026 00:29:37 +0000 Subject: [PATCH 127/211] fix: only show first line on commit messages (#696) Signed-off-by: Zomatree --- .../routes/webhooks/webhook_execute_github.rs | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/crates/delta/src/routes/webhooks/webhook_execute_github.rs b/crates/delta/src/routes/webhooks/webhook_execute_github.rs index 124b2e97c..049392d2d 100644 --- a/crates/delta/src/routes/webhooks/webhook_execute_github.rs +++ b/crates/delta/src/routes/webhooks/webhook_execute_github.rs @@ -688,11 +688,23 @@ const LIGHT_ORANGE: &str = "#d9916d"; // for future use // const WHITE: &str = "#c3e1c3"; -fn shorten_text(text: &str, length: usize) -> String { - if text.len() < length { +fn shorten_single_line_text(text: &str, length: usize) -> String { + if text.contains('\n') { + let text = text.split('\n').next().unwrap(); + + format!("{}...", &text[..text.len().min(length) - 3]) + } else if text.len() > length { + format!("{}...", &text[..length - 3]) + } else { text.to_string() + } +} + +fn shorten_text(text: &str, length: usize) -> String { + if text.len() >= length { + format!("{}...", &text[..length - 3]) } else { - format!("{}...", &text[0..length]) + text.to_string() } } @@ -823,7 +835,7 @@ pub async fn webhook_execute_github( "[`{}`]({}) {} - {}", &commit.id[0..=7], commit.url, - shorten_text(&commit.message, 50), + shorten_single_line_text(&commit.message, 50), commit.author.name ) }) From c2d4369e160f32d79bce0a0b0f14677f89de3669 Mon Sep 17 00:00:00 2001 From: "newt (" Date: Sat, 28 Mar 2026 00:29:55 +0000 Subject: [PATCH 128/211] feat: compute thumbhash for images (#596) * feat: compute thumbhash for images Signed-off-by: newt * Merge branch 'main' into feat/thumbhash Signed-off-by: newt * style: move comment onto newline Signed-off-by: newt * feat: make thumbhash optional Signed-off-by: newt --------- Signed-off-by: newt Signed-off-by: newt (: Signed-off-by: Tom Co-authored-by: Tom --- Cargo.lock | 7 +++++++ .../database/src/models/file_hashes/model.rs | 1 + crates/core/database/src/util/bridge/v0.rs | 16 +++++++++++----- crates/core/models/src/v0/files.rs | 1 + crates/services/autumn/Cargo.toml | 1 + crates/services/autumn/src/exif.rs | 2 ++ crates/services/autumn/src/metadata.rs | 11 +++++++++++ 7 files changed, 34 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c68b822fb..3cf777f2f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6824,6 +6824,7 @@ dependencies = [ "simdutf8", "strum_macros", "tempfile", + "thumbhash", "tokio 1.49.0", "tower-http 0.5.2", "tracing", @@ -8835,6 +8836,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "thumbhash" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b7726e0245a7331bd0c9a1fb4fd99fd695bcd478ca569f0eda2ff2cb14e7a00" + [[package]] name = "tiff" version = "0.10.3" diff --git a/crates/core/database/src/models/file_hashes/model.rs b/crates/core/database/src/models/file_hashes/model.rs index 756ce3d5c..b25abb12b 100644 --- a/crates/core/database/src/models/file_hashes/model.rs +++ b/crates/core/database/src/models/file_hashes/model.rs @@ -45,6 +45,7 @@ auto_derived!( Image { width: isize, height: isize, + thumbhash: Option>, #[serde(default)] animated: bool, }, diff --git a/crates/core/database/src/util/bridge/v0.rs b/crates/core/database/src/util/bridge/v0.rs index e5e888d60..2e6377952 100644 --- a/crates/core/database/src/util/bridge/v0.rs +++ b/crates/core/database/src/util/bridge/v0.rs @@ -415,11 +415,13 @@ impl From for Metadata { crate::Metadata::Image { width, height, + thumbhash, animated, } => Metadata::Image { width: width as usize, height: height as usize, - animated: animated as bool, + thumbhash, + animated, }, crate::Metadata::Video { width, height } => Metadata::Video { width: width as usize, @@ -438,10 +440,12 @@ impl From for crate::Metadata { Metadata::Image { width, height, + thumbhash, animated, } => crate::Metadata::Image { width: width as isize, height: height as isize, + thumbhash, animated, }, Metadata::Video { width, height } => crate::Metadata::Video { @@ -531,7 +535,9 @@ impl From for SystemMessage { crate::SystemMessage::UserRemove { id, by } => Self::UserRemove { id, by }, crate::SystemMessage::MessagePinned { id, by } => Self::MessagePinned { id, by }, crate::SystemMessage::MessageUnpinned { id, by } => Self::MessageUnpinned { id, by }, - crate::SystemMessage::CallStarted { by, finished_at } => Self::CallStarted { by, finished_at } + crate::SystemMessage::CallStarted { by, finished_at } => { + Self::CallStarted { by, finished_at } + } } } } @@ -1398,7 +1404,7 @@ impl From for crate::FieldsMessage { impl From for crate::VoiceInformation { fn from(value: VoiceInformation) -> Self { crate::VoiceInformation { - max_users: value.max_users + max_users: value.max_users, } } } @@ -1406,7 +1412,7 @@ impl From for crate::VoiceInformation { impl From for VoiceInformation { fn from(value: crate::VoiceInformation) -> Self { VoiceInformation { - max_users: value.max_users + max_users: value.max_users, } } -} \ No newline at end of file +} diff --git a/crates/core/models/src/v0/files.rs b/crates/core/models/src/v0/files.rs index 7ed1e20e8..32ccf0e1d 100644 --- a/crates/core/models/src/v0/files.rs +++ b/crates/core/models/src/v0/files.rs @@ -50,6 +50,7 @@ auto_derived!( Image { width: usize, height: usize, + thumbhash: Option>, animated: bool, }, /// File is a video with specific dimensions diff --git a/crates/services/autumn/Cargo.toml b/crates/services/autumn/Cargo.toml index 84cf65311..ba426dc80 100644 --- a/crates/services/autumn/Cargo.toml +++ b/crates/services/autumn/Cargo.toml @@ -17,6 +17,7 @@ jxl-oxide = "0.8.1" kamadak-exif = "0.5.4" # revolt_little_exif = "0.5.1" image = { version = "0.25.2" } # avif encode requires dav1d system library: features = ["avif-native"] +thumbhash = "0.1.0" # File processing revolt_clamav-client = { version = "0.1.5" } diff --git a/crates/services/autumn/src/exif.rs b/crates/services/autumn/src/exif.rs index 562f975ee..af02953e5 100644 --- a/crates/services/autumn/src/exif.rs +++ b/crates/services/autumn/src/exif.rs @@ -19,6 +19,7 @@ pub async fn strip_metadata( Metadata::Image { width, height, + thumbhash, animated, } => match mime { // // little_exif does not appear to parse JPEGs correctly? had 2/2 files fail @@ -102,6 +103,7 @@ pub async fn strip_metadata( Metadata::Image { width, height, + thumbhash: thumbhash.clone(), animated: *animated, }, )) diff --git a/crates/services/autumn/src/metadata.rs b/crates/services/autumn/src/metadata.rs index 3c69cf848..3493cf492 100644 --- a/crates/services/autumn/src/metadata.rs +++ b/crates/services/autumn/src/metadata.rs @@ -1,5 +1,6 @@ use std::io::Cursor; +use image::{GenericImageView, ImageError, ImageReader}; use revolt_database::Metadata; use revolt_files::{image_size, is_animated, video_size}; use tempfile::NamedTempFile; @@ -26,6 +27,16 @@ pub fn generate_metadata(f: &NamedTempFile, mime_type: &str) -> Metadata { .map(|(width, height)| Metadata::Image { width: width as isize, height: height as isize, + thumbhash: ImageReader::open(f) + .and_then(|r| r.with_guessed_format()) + .map_err(ImageError::from) + .and_then(|r| r.decode()) + .map(|img| img.thumbnail(100, 100)) + .map(|img| (img.dimensions(), img.to_rgba8().into_raw())) + .map(|((width, height), rgba)| { + thumbhash::rgba_to_thumb_hash(width as usize, height as usize, &rgba) + }) + .ok(), animated: is_animated(f, mime_type).unwrap_or(false), }) .unwrap_or_default() From 52ed5100c2446e0b261085639e123e7e124cab2c Mon Sep 17 00:00:00 2001 From: Damocles <106018783+Damocles078@users.noreply.github.com> Date: Sat, 28 Mar 2026 01:31:57 +0100 Subject: [PATCH 129/211] fix: improve generated openapi.json (#584) * fix: /bots/{bot} Paths "/bots/{bot}" and "/bots/{target}" must not be equivalent. Signed-off-by: Damocles078 * fix: /channels/{group_id}/recipients/{member_id} Paths "/channels/{group_id}/recipients/{member_id}" and "/channels/{target}/recipients/{member}" must not be equivalent. Signed-off-by: Damocles078 * fix: /channels/{channel_id}/webhook Paths "/channels/{target}/webhooks" and "/channels/{channel_id}/webhooks" must not be equivalent. Signed-off-by: Damocles078 * fix: /servers/{server_id}/members/{member_id} Paths "/servers/{target}/members/{member}" and "/servers/{server}/members/{member}" must not be equivalent. Signed-off-by: Damocles078 * fix: /custom/emoji/{emoji_id} Paths "/custom/emoji/{id}" and "/custom/emoji/{emoji_id}" must not be equivalent. Signed-off-by: Damocles078 --------- Signed-off-by: Damocles078 Signed-off-by: Damocles <106018783+Damocles078@users.noreply.github.com> --- crates/delta/src/routes/bots/delete.rs | 6 +++--- crates/delta/src/routes/bots/edit.rs | 6 +++--- crates/delta/src/routes/bots/fetch.rs | 6 +++--- .../src/routes/channels/group_remove_member.rs | 14 +++++++------- .../src/routes/channels/webhook_create.rs | 6 +++--- .../src/routes/customisation/emoji_create.rs | 8 ++++---- crates/delta/src/routes/servers/member_edit.rs | 12 ++++++------ .../delta/src/routes/servers/member_fetch.rs | 10 +++++----- .../delta/src/routes/servers/member_remove.rs | 18 +++++++++--------- 9 files changed, 43 insertions(+), 43 deletions(-) diff --git a/crates/delta/src/routes/bots/delete.rs b/crates/delta/src/routes/bots/delete.rs index 11132f278..c3c89fcc5 100644 --- a/crates/delta/src/routes/bots/delete.rs +++ b/crates/delta/src/routes/bots/delete.rs @@ -11,14 +11,14 @@ use rocket_empty::EmptyResponse; /// /// Delete a bot by its id. #[openapi(tag = "Bots")] -#[delete("/")] +#[delete("/")] pub async fn delete_bot( db: &State, voice_client: &State, user: User, - target: Reference<'_>, + bot_id: Reference<'_>, ) -> Result { - let bot = target.as_bot(db).await?; + let bot = bot_id.as_bot(db).await?; if bot.owner != user.id { return Err(create_error!(NotFound)); } diff --git a/crates/delta/src/routes/bots/edit.rs b/crates/delta/src/routes/bots/edit.rs index 6c454e135..a142ba462 100644 --- a/crates/delta/src/routes/bots/edit.rs +++ b/crates/delta/src/routes/bots/edit.rs @@ -10,11 +10,11 @@ use validator::Validate; /// /// Edit bot details by its id. #[openapi(tag = "Bots")] -#[patch("/", data = "")] +#[patch("/", data = "")] pub async fn edit_bot( db: &State, user: User, - target: Reference<'_>, + bot_id: Reference<'_>, data: Json, ) -> Result> { let data = data.into_inner(); @@ -24,7 +24,7 @@ pub async fn edit_bot( }) })?; - let mut bot = target.as_bot(db).await?; + let mut bot = bot_id.as_bot(db).await?; if bot.owner != user.id { return Err(create_error!(NotFound)); } diff --git a/crates/delta/src/routes/bots/fetch.rs b/crates/delta/src/routes/bots/fetch.rs index 586ce124e..344620cf5 100644 --- a/crates/delta/src/routes/bots/fetch.rs +++ b/crates/delta/src/routes/bots/fetch.rs @@ -7,17 +7,17 @@ use rocket::{serde::json::Json, State}; /// /// Fetch details of a bot you own by its id. #[openapi(tag = "Bots")] -#[get("/")] +#[get("/")] pub async fn fetch_bot( db: &State, user: User, - bot: Reference<'_>, + bot_id: Reference<'_>, ) -> Result> { if user.bot.is_some() { return Err(create_error!(IsBot)); } - let bot = bot.as_bot(db).await?; + let bot = bot_id.as_bot(db).await?; if bot.owner != user.id { return Err(create_error!(NotFound)); } diff --git a/crates/delta/src/routes/channels/group_remove_member.rs b/crates/delta/src/routes/channels/group_remove_member.rs index 083bb44ed..052216294 100644 --- a/crates/delta/src/routes/channels/group_remove_member.rs +++ b/crates/delta/src/routes/channels/group_remove_member.rs @@ -11,20 +11,20 @@ use rocket_empty::EmptyResponse; /// /// Removes a user from the group. #[openapi(tag = "Groups")] -#[delete("//recipients/")] +#[delete("//recipients/")] pub async fn remove_member( db: &State, voice_client: &State, amqp: &State, user: User, - target: Reference<'_>, - member: Reference<'_>, + group_id: Reference<'_>, + member_id: Reference<'_>, ) -> Result { if user.bot.is_some() { return Err(create_error!(IsBot)); } - let channel = target.as_channel(db).await?; + let channel = group_id.as_channel(db).await?; if let Channel::Group { owner, recipients, .. @@ -36,7 +36,7 @@ pub async fn remove_member( })); } - let member = member.as_user(db).await?; + let member = member_id.as_user(db).await?; if user.id == member.id { return Err(create_error!(CannotRemoveYourself)); } @@ -54,8 +54,8 @@ pub async fn remove_member( let user_voice_channel = UserVoiceChannel::from_channel(&channel); - if is_in_voice_channel(member.id, &user_voice_channel).await? { - remove_user_from_voice_channel(voice_client, &user_voice_channel, member.id).await?; + if is_in_voice_channel(member_id.id, &user_voice_channel).await? { + remove_user_from_voice_channel(voice_client, &user_voice_channel, member_id.id).await?; }; Ok(EmptyResponse) diff --git a/crates/delta/src/routes/channels/webhook_create.rs b/crates/delta/src/routes/channels/webhook_create.rs index 71f8e8dee..dc8cad64d 100644 --- a/crates/delta/src/routes/channels/webhook_create.rs +++ b/crates/delta/src/routes/channels/webhook_create.rs @@ -15,11 +15,11 @@ use validator::Validate; /// /// Creates a webhook which 3rd party platforms can use to send messages #[openapi(tag = "Webhooks")] -#[post("//webhooks", data = "")] +#[post("//webhooks", data = "")] pub async fn create_webhook( db: &State, user: User, - target: Reference<'_>, + channel_id: Reference<'_>, data: Json, ) -> Result> { let data = data.into_inner(); @@ -29,7 +29,7 @@ pub async fn create_webhook( }) })?; - let channel = target.as_channel(db).await?; + let channel = channel_id.as_channel(db).await?; if !matches!(channel, Channel::TextChannel { .. } | Channel::Group { .. }) { return Err(create_error!(InvalidOperation)); diff --git a/crates/delta/src/routes/customisation/emoji_create.rs b/crates/delta/src/routes/customisation/emoji_create.rs index d8288dae7..52b5c9043 100644 --- a/crates/delta/src/routes/customisation/emoji_create.rs +++ b/crates/delta/src/routes/customisation/emoji_create.rs @@ -11,11 +11,11 @@ use rocket::{serde::json::Json, State}; /// /// Create an emoji by its Autumn upload id. #[openapi(tag = "Emojis")] -#[put("/emoji/", data = "")] +#[put("/emoji/", data = "")] pub async fn create_emoji( db: &State, user: User, - id: String, + emoji_id: String, data: Json, ) -> Result> { let config = config().await; @@ -50,11 +50,11 @@ pub async fn create_emoji( }; // Find the relevant attachment - let attachment = File::use_emoji(db, &id, &id, &user.id).await?; + let attachment = File::use_emoji(db, &emoji_id, &emoji_id, &user.id).await?; // Create the emoji object let emoji = Emoji { - id, + id: emoji_id, parent: data.parent.into(), creator_id: user.id, name: data.name, diff --git a/crates/delta/src/routes/servers/member_edit.rs b/crates/delta/src/routes/servers/member_edit.rs index 87b455243..e3f63e498 100644 --- a/crates/delta/src/routes/servers/member_edit.rs +++ b/crates/delta/src/routes/servers/member_edit.rs @@ -24,13 +24,13 @@ use validator::Validate; /// /// Edit a member by their id. #[openapi(tag = "Server Members")] -#[patch("//members/", data = "")] +#[patch("//members/", data = "")] pub async fn edit( db: &State, voice_client: &State, user: User, - server: Reference<'_>, - member: Reference<'_>, + server_id: Reference<'_>, + member_id: Reference<'_>, data: Json, ) -> Result> { let data = data.into_inner(); @@ -41,9 +41,9 @@ pub async fn edit( })?; // Fetch server and member - let mut server = server.as_server(db).await?; - let target_user = member.as_user(db).await?; - let mut member = member.as_member(db, &server.id).await?; + let mut server = server_id.as_server(db).await?; + let target_user = member_id.as_user(db).await?; + let mut member = member_id.as_member(db, &server.id).await?; // Fetch our currrent permissions let mut query = DatabasePermissionQuery::new(db, &user).server(&server); diff --git a/crates/delta/src/routes/servers/member_fetch.rs b/crates/delta/src/routes/servers/member_fetch.rs index c05935be3..967f98140 100644 --- a/crates/delta/src/routes/servers/member_fetch.rs +++ b/crates/delta/src/routes/servers/member_fetch.rs @@ -11,21 +11,21 @@ use rocket::{serde::json::Json, State}; /// /// Retrieve a member. #[openapi(tag = "Server Members")] -#[get("//members/?")] +#[get("//members/?")] pub async fn fetch( db: &State, user: User, - target: Reference<'_>, - member: Reference<'_>, + server_id: Reference<'_>, + member_id: Reference<'_>, roles: Option, ) -> Result> { - let server = target.as_server(db).await?; + let server = server_id.as_server(db).await?; let mut query = DatabasePermissionQuery::new(db, &user).server(&server); if !query.are_we_a_member().await { return Err(create_error!(NotFound)); } - let member = member.as_member(db, &server.id).await?; + let member = member_id.as_member(db, &server.id).await?; if let Some(true) = roles { Ok(Json(v0::MemberResponse::MemberWithRoles { roles: server diff --git a/crates/delta/src/routes/servers/member_remove.rs b/crates/delta/src/routes/servers/member_remove.rs index de5b02541..1885c5bac 100644 --- a/crates/delta/src/routes/servers/member_remove.rs +++ b/crates/delta/src/routes/servers/member_remove.rs @@ -15,21 +15,21 @@ use rocket_empty::EmptyResponse; /// /// Removes a member from the server. #[openapi(tag = "Server Members")] -#[delete("//members/")] +#[delete("//members/")] pub async fn kick( db: &State, voice_client: &State, user: User, - target: Reference<'_>, - member: Reference<'_>, + server_id: Reference<'_>, + member_id: Reference<'_>, ) -> Result { - let server = target.as_server(db).await?; + let server = server_id.as_server(db).await?; - if member.id == user.id { + if member_id.id == user.id { return Err(create_error!(CannotRemoveYourself)); } - if member.id == server.owner { + if member_id.id == server.owner { return Err(create_error!(InvalidOperation)); } @@ -38,7 +38,7 @@ pub async fn kick( .await .throw_if_lacking_channel_permission(ChannelPermission::KickMembers)?; - let member = member.as_member(db, &server.id).await?; + let member = member_id.as_member(db, &server.id).await?; if member.get_ranking(query.server_ref().as_ref().unwrap()) <= query.get_member_rank().unwrap_or(i64::MIN) { @@ -49,14 +49,14 @@ pub async fn kick( .remove(db, &server, RemovalIntention::Kick, false) .await?; - if let Some(channel_id) = get_user_voice_channel_in_server(target.id, &server.id).await? { + if let Some(channel_id) = get_user_voice_channel_in_server(member_id.id, &server.id).await? { remove_user_from_voice_channel( voice_client, &UserVoiceChannel { id: channel_id, server_id: Some(server.id.clone()), }, - target.id, + member_id.id, ) .await?; }; From ccda6f5c53ee043705f7ff6b5f6c393f020781de Mon Sep 17 00:00:00 2001 From: Angelo Kontaxis Date: Sat, 28 Mar 2026 01:39:00 +0000 Subject: [PATCH 130/211] fix: pass &str to Reference (#697) Signed-off-by: Zomatree --- crates/delta/src/routes/servers/server_edit.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/delta/src/routes/servers/server_edit.rs b/crates/delta/src/routes/servers/server_edit.rs index 3c9a6d1bc..986c3b08a 100644 --- a/crates/delta/src/routes/servers/server_edit.rs +++ b/crates/delta/src/routes/servers/server_edit.rs @@ -165,7 +165,7 @@ pub async fn edit( // 5. Transfer ownership if let Some(owner) = owner { - let owner_reference = Reference { id: owner.clone() }; + let owner_reference = Reference::from_unchecked(&owner); // Check if member exists owner_reference.as_member(db, &server.id).await?; let owner_user = owner_reference.as_user(db).await?; From f181edc8f2ff3ce4b6d48938dfc73931ecfa2279 Mon Sep 17 00:00:00 2001 From: Tom Date: Fri, 27 Mar 2026 21:14:22 -0700 Subject: [PATCH 131/211] feat: update livekit (#698) --- compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compose.yml b/compose.yml index e1e84b6fe..a01c965e5 100644 --- a/compose.yml +++ b/compose.yml @@ -70,8 +70,8 @@ services: MAILDEV_INCOMING_PASS: smtp livekit: - image: ghcr.io/stoatchat/livekit-server:v1.9.9 + image: ghcr.io/stoatchat/livekit-server:v1.9.13 command: --config /etc/livekit.yml network_mode: "host" volumes: - - ./livekit.yml:/etc/livekit.yml \ No newline at end of file + - ./livekit.yml:/etc/livekit.yml From 4d4b0dd864868df24ad795ece0d76ff123037728 Mon Sep 17 00:00:00 2001 From: "stoat-release[bot]" <245062572+stoat-release[bot]@users.noreply.github.com> Date: Sat, 28 Mar 2026 22:22:37 -0700 Subject: [PATCH 132/211] chore(main): release 0.12.0 (#602) Co-authored-by: stoat-release[bot] <245062572+stoat-release[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- CHANGELOG.md | 37 +++++++++++++++++++++++++ crates/bonfire/Cargo.toml | 2 +- crates/core/coalesced/Cargo.toml | 2 +- crates/core/config/Cargo.toml | 4 +-- crates/core/database/Cargo.toml | 14 +++++----- crates/core/files/Cargo.toml | 6 ++-- crates/core/models/Cargo.toml | 6 ++-- crates/core/parser/Cargo.toml | 2 +- crates/core/permissions/Cargo.toml | 4 +-- crates/core/presence/Cargo.toml | 4 +-- crates/core/ratelimits/Cargo.toml | 8 +++--- crates/core/result/Cargo.toml | 2 +- crates/daemons/crond/Cargo.toml | 10 +++---- crates/daemons/pushd/Cargo.toml | 12 ++++---- crates/daemons/voice-ingress/Cargo.toml | 2 +- crates/delta/Cargo.toml | 2 +- crates/services/autumn/Cargo.toml | 12 ++++---- crates/services/gifbox/Cargo.toml | 14 +++++----- crates/services/january/Cargo.toml | 10 +++---- version.txt | 2 +- 21 files changed, 97 insertions(+), 60 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 3bb04a8d9..53d4a3f21 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.11.5" + ".": "0.12.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 60676b6c6..7153a56f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,42 @@ # Changelog +## [0.12.0](https://github.com/stoatchat/stoatchat/compare/v0.11.5...v0.12.0) (2026-03-28) + + +### Features + +* add bug report template for issue tracking ([#627](https://github.com/stoatchat/stoatchat/issues/627)) ([f777e28](https://github.com/stoatchat/stoatchat/commit/f777e2863c6ca50057c8b5d0a5be14915d287724)) +* Add slowmode functionality to text channels ([#680](https://github.com/stoatchat/stoatchat/issues/680)) ([6107f24](https://github.com/stoatchat/stoatchat/commit/6107f242fd3ebaff71a15f9a16330ffbcb4f2d7b)) +* Allow restricting server creation to specific users ([#685](https://github.com/stoatchat/stoatchat/issues/685)) ([edfa97d](https://github.com/stoatchat/stoatchat/commit/edfa97db108c9c81828547f98a1db5315cb5ba4a)) +* compute thumbhash for images ([#596](https://github.com/stoatchat/stoatchat/issues/596)) ([c2d4369](https://github.com/stoatchat/stoatchat/commit/c2d4369e160f32d79bce0a0b0f14677f89de3669)) +* Detect animation in image files for fetch_preview ([#574](https://github.com/stoatchat/stoatchat/issues/574)) ([3fa0abf](https://github.com/stoatchat/stoatchat/commit/3fa0abf47f5f42ddd8ee041fe4c44fbc5ba800c1)) +* expose global and user limits in root API response ([#644](https://github.com/stoatchat/stoatchat/issues/644)) ([0b522eb](https://github.com/stoatchat/stoatchat/commit/0b522ebddc17f2e3f792ff5e2347793e9849fa23)) +* implement time based message sweep on user ban ([#670](https://github.com/stoatchat/stoatchat/issues/670)) ([98c7b1b](https://github.com/stoatchat/stoatchat/commit/98c7b1b5a5b9fdac5c0ab83be10f0e23114dbfc9)) +* load config from env vars ([#576](https://github.com/stoatchat/stoatchat/issues/576)) ([5191bd1](https://github.com/stoatchat/stoatchat/commit/5191bd16b2a905b8409838e34eb0baca96f08580)) +* parse message push notification content and replace internal formatting ([#693](https://github.com/stoatchat/stoatchat/issues/693)) ([d1e72ce](https://github.com/stoatchat/stoatchat/commit/d1e72cee42c54e16f4e49af569897528b10a28ca)) +* Transfer ownership ([#396](https://github.com/stoatchat/stoatchat/issues/396)) ([735d644](https://github.com/stoatchat/stoatchat/commit/735d644e043793cb86e74aab5b88bb4b8bc17ba2)) +* update livekit ([#698](https://github.com/stoatchat/stoatchat/issues/698)) ([f181edc](https://github.com/stoatchat/stoatchat/commit/f181edc8f2ff3ce4b6d48938dfc73931ecfa2279)) + + +### Bug Fixes + +* add flag for disabling events instead of commenting them out ([#695](https://github.com/stoatchat/stoatchat/issues/695)) ([a5cd08a](https://github.com/stoatchat/stoatchat/commit/a5cd08a655dece4269f3ac84fa2387ae356709a5)) +* add masquerade permission to default direct message settings ([#665](https://github.com/stoatchat/stoatchat/issues/665)) ([ab52569](https://github.com/stoatchat/stoatchat/commit/ab525699bd6663333f0e9fed6d2455e482e6a09f)) +* Check for appropriate permission for removing other users avatar ([#657](https://github.com/stoatchat/stoatchat/issues/657)) ([d56135e](https://github.com/stoatchat/stoatchat/commit/d56135e0cbc713884c9378832952f7ad490fa315)) +* default video resolution is a non-existent size ([#601](https://github.com/stoatchat/stoatchat/issues/601)) ([0698e11](https://github.com/stoatchat/stoatchat/commit/0698e115e8d003d615e468c4fb9654e6bbc9107f)), closes [#588](https://github.com/stoatchat/stoatchat/issues/588) +* **docs:** Update GitHub links ([#647](https://github.com/stoatchat/stoatchat/issues/647)) ([b830631](https://github.com/stoatchat/stoatchat/commit/b830631bd25a546844b7bdd30386084bb365e4de)) +* don't use a bitop for OR ([#676](https://github.com/stoatchat/stoatchat/issues/676)) ([5701b5c](https://github.com/stoatchat/stoatchat/commit/5701b5c18c513f796af365169ceaea372a22638c)) +* Fix typo for p256dh in vapid notification flow ([#622](https://github.com/stoatchat/stoatchat/issues/622)) ([a80ad1c](https://github.com/stoatchat/stoatchat/commit/a80ad1cbe58b8af5e45751e51d94d93c1cea1c9f)) +* improve generated openapi.json ([#584](https://github.com/stoatchat/stoatchat/issues/584)) ([52ed510](https://github.com/stoatchat/stoatchat/commit/52ed5100c2446e0b261085639e123e7e124cab2c)) +* no node state set on channel creation ([#653](https://github.com/stoatchat/stoatchat/issues/653)) ([24d0d2b](https://github.com/stoatchat/stoatchat/commit/24d0d2b7266f6f8a692d0a52704acfecf517674c)) +* only show first line on commit messages ([#696](https://github.com/stoatchat/stoatchat/issues/696)) ([91783b9](https://github.com/stoatchat/stoatchat/commit/91783b906697fc85305dee683f7c15dda55f0c50)) +* pass &str to Reference ([#697](https://github.com/stoatchat/stoatchat/issues/697)) ([ccda6f5](https://github.com/stoatchat/stoatchat/commit/ccda6f5c53ee043705f7ff6b5f6c393f020781de)) +* redis_url vs redis_uri in config ([#666](https://github.com/stoatchat/stoatchat/issues/666)) ([b0b728f](https://github.com/stoatchat/stoatchat/commit/b0b728fb0dbc9ee28360301de1c3ea501bbbff1d)) +* replace some links and Revolt mentions to current Stoat ([#515](https://github.com/stoatchat/stoatchat/issues/515)) ([d629e89](https://github.com/stoatchat/stoatchat/commit/d629e89304be2f0011e189293b278f07d346aa7d)) +* send push notifications for DM and group messages ([#660](https://github.com/stoatchat/stoatchat/issues/660)) ([52c0d2f](https://github.com/stoatchat/stoatchat/commit/52c0d2f266b76d8975bba2d5e75c62bb30149c45)) +* store server id in redis and in room metadata to be able to delete voice state in all scenarios ([#656](https://github.com/stoatchat/stoatchat/issues/656)) ([49c6289](https://github.com/stoatchat/stoatchat/commit/49c628958070e4f0a5edc764d3b48158589219d9)) +* uname is missing from crond ([#675](https://github.com/stoatchat/stoatchat/issues/675)) ([dc4438b](https://github.com/stoatchat/stoatchat/commit/dc4438bc3c7b2cad8d442b3cd438afb9ed566a5e)) + ## [0.11.5](https://github.com/stoatchat/stoatchat/compare/v0.11.4...v0.11.5) (2026-02-17) diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index 93ac8d4b0..e4481b1c4 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-bonfire" -version = "0.11.5" +version = "0.12.0" license = "AGPL-3.0-or-later" edition = "2021" publish = false diff --git a/crates/core/coalesced/Cargo.toml b/crates/core/coalesced/Cargo.toml index b1242a5b1..4b589c0d5 100644 --- a/crates/core/coalesced/Cargo.toml +++ b/crates/core/coalesced/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-coalesced" -version = "0.11.5" +version = "0.12.0" edition = "2021" license = "MIT" authors = ["Paul Makles ", "Zomatree "] diff --git a/crates/core/config/Cargo.toml b/crates/core/config/Cargo.toml index f870f1f1e..ad1ee4692 100644 --- a/crates/core/config/Cargo.toml +++ b/crates/core/config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-config" -version = "0.11.5" +version = "0.12.0" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -38,4 +38,4 @@ sentry = { version = "0.31.5", optional = true } sentry-anyhow = { version = "0.38.1", optional = true } # Core -revolt-result = { version = "0.11.5", path = "../result", optional = true } +revolt-result = { version = "0.12.0", path = "../result", optional = true } diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index 35d0e9095..05a66179a 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-database" -version = "0.11.5" +version = "0.12.0" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -32,19 +32,19 @@ default = ["mongodb", "async-std-runtime", "tasks"] [dependencies] # Core -revolt-config = { version = "0.11.5", path = "../config", features = [ +revolt-config = { version = "0.12.0", path = "../config", features = [ "report-macros", ] } -revolt-result = { version = "0.11.5", path = "../result" } -revolt-models = { version = "0.11.5", path = "../models", features = [ +revolt-result = { version = "0.12.0", path = "../result" } +revolt-models = { version = "0.12.0", path = "../models", features = [ "validator", ] } -revolt-presence = { version = "0.11.5", path = "../presence" } -revolt-permissions = { version = "0.11.5", path = "../permissions", features = [ +revolt-presence = { version = "0.12.0", path = "../presence" } +revolt-permissions = { version = "0.12.0", path = "../permissions", features = [ "serde", "bson", ] } -revolt-parser = { version = "0.11.5", path = "../parser" } +revolt-parser = { version = "0.12.0", path = "../parser" } # Utility log = "0.4" diff --git a/crates/core/files/Cargo.toml b/crates/core/files/Cargo.toml index 94ea4f478..2a4a52054 100644 --- a/crates/core/files/Cargo.toml +++ b/crates/core/files/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-files" -version = "0.11.5" +version = "0.12.0" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -27,10 +27,10 @@ typenum = "1.17.0" aws-config = "1.5.5" aws-sdk-s3 = { version = "1.46.0", features = ["behavior-version-latest"] } -revolt-config = { version = "0.11.5", path = "../config", features = [ +revolt-config = { version = "0.12.0", path = "../config", features = [ "report-macros", ] } -revolt-result = { version = "0.11.5", path = "../result" } +revolt-result = { version = "0.12.0", path = "../result" } # image processing jxl-oxide = { workspace = true } diff --git a/crates/core/models/Cargo.toml b/crates/core/models/Cargo.toml index cbc0001fc..a1a65e194 100644 --- a/crates/core/models/Cargo.toml +++ b/crates/core/models/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-models" -version = "0.11.5" +version = "0.12.0" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -21,8 +21,8 @@ default = ["serde", "partials", "rocket"] [dependencies] # Core -revolt-config = { version = "0.11.5", path = "../config" } -revolt-permissions = { version = "0.11.5", path = "../permissions" } +revolt-config = { version = "0.12.0", path = "../config" } +revolt-permissions = { version = "0.12.0", path = "../permissions" } # Utility regex = "1.11" diff --git a/crates/core/parser/Cargo.toml b/crates/core/parser/Cargo.toml index 187916d87..f542b7aaf 100644 --- a/crates/core/parser/Cargo.toml +++ b/crates/core/parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-parser" -version = "0.11.5" +version = "0.12.0" edition = "2021" license = "MIT" authors = ["Zomatree ", "Paul Makles "] diff --git a/crates/core/permissions/Cargo.toml b/crates/core/permissions/Cargo.toml index 92d1afe20..98edf99bc 100644 --- a/crates/core/permissions/Cargo.toml +++ b/crates/core/permissions/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-permissions" -version = "0.11.5" +version = "0.12.0" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -22,7 +22,7 @@ async-std = { version = "1.8.0", features = ["attributes"] } [dependencies] # Core -revolt-result = { version = "0.11.5", path = "../result" } +revolt-result = { version = "0.12.0", path = "../result" } # Utility auto_ops = "0.3.0" diff --git a/crates/core/presence/Cargo.toml b/crates/core/presence/Cargo.toml index 3cf324c46..3b3ce3ee9 100644 --- a/crates/core/presence/Cargo.toml +++ b/crates/core/presence/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-presence" -version = "0.11.5" +version = "0.12.0" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -17,7 +17,7 @@ redis-is-patched = [] async-std = { version = "1.8.0", features = ["attributes"] } # Config for loading Redis URI -revolt-config = { version = "0.11.5", path = "../config" } +revolt-config = { version = "0.12.0", path = "../config" } [dependencies] # Utility diff --git a/crates/core/ratelimits/Cargo.toml b/crates/core/ratelimits/Cargo.toml index f7a764620..54c1a702d 100644 --- a/crates/core/ratelimits/Cargo.toml +++ b/crates/core/ratelimits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-ratelimits" -version = "0.11.5" +version = "0.12.0" edition = "2024" license = "MIT" authors = ["Zomatree ", "Paul Makles "] @@ -18,9 +18,9 @@ axum = ["dep:axum", "revolt-database/axum-impl"] default = ["rocket", "axum"] [dependencies] -revolt-database = { version = "0.11.5", path = "../database" } -revolt-result = { version = "0.11.5", path = "../result" } -revolt-config = { version = "0.11.5", path = "../config" } +revolt-database = { version = "0.12.0", path = "../database" } +revolt-result = { version = "0.12.0", path = "../result" } +revolt-config = { version = "0.12.0", path = "../config" } rocket = { version = "0.5.1", optional = true } revolt_rocket_okapi = { version = "0.10.0", optional = true } diff --git a/crates/core/result/Cargo.toml b/crates/core/result/Cargo.toml index 31cb06cc0..0ebcc4e2e 100644 --- a/crates/core/result/Cargo.toml +++ b/crates/core/result/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-result" -version = "0.11.5" +version = "0.12.0" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/daemons/crond/Cargo.toml b/crates/daemons/crond/Cargo.toml index 870eff02c..1f9de2b09 100644 --- a/crates/daemons/crond/Cargo.toml +++ b/crates/daemons/crond/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-crond" -version = "0.11.5" +version = "0.12.0" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2021" @@ -17,7 +17,7 @@ log = "0.4" tokio = { version = "1" } # Core -revolt-database = { version = "0.11.5", path = "../../core/database" } -revolt-result = { version = "0.11.5", path = "../../core/result" } -revolt-config = { version = "0.11.5", path = "../../core/config" } -revolt-files = { version = "0.11.5", path = "../../core/files" } +revolt-database = { version = "0.12.0", path = "../../core/database" } +revolt-result = { version = "0.12.0", path = "../../core/result" } +revolt-config = { version = "0.12.0", path = "../../core/config" } +revolt-files = { version = "0.12.0", path = "../../core/files" } diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index 9ea3d8867..3ff6daabf 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -1,21 +1,21 @@ [package] name = "revolt-pushd" -version = "0.11.5" +version = "0.12.0" edition = "2021" license = "AGPL-3.0-or-later" publish = false [dependencies] -revolt-result = { version = "0.11.5", path = "../../core/result" } -revolt-config = { version = "0.11.5", path = "../../core/config", features = [ +revolt-result = { version = "0.12.0", path = "../../core/result" } +revolt-config = { version = "0.12.0", path = "../../core/config", features = [ "report-macros", "anyhow", ] } -revolt-database = { version = "0.11.5", path = "../../core/database" } -revolt-models = { version = "0.11.5", path = "../../core/models", features = [ +revolt-database = { version = "0.12.0", path = "../../core/database" } +revolt-models = { version = "0.12.0", path = "../../core/models", features = [ "validator", ] } -revolt-presence = { version = "0.11.5", path = "../../core/presence", features = [ +revolt-presence = { version = "0.12.0", path = "../../core/presence", features = [ "redis-is-patched", ] } revolt-parser = { version = "0.11.5", path = "../../core/parser" } diff --git a/crates/daemons/voice-ingress/Cargo.toml b/crates/daemons/voice-ingress/Cargo.toml index 177a91f87..0b498d930 100644 --- a/crates/daemons/voice-ingress/Cargo.toml +++ b/crates/daemons/voice-ingress/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-voice-ingress" -version = "0.11.5" +version = "0.12.0" license = "AGPL-3.0-or-later" edition = "2021" publish = false diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index af6de573a..7976d2086 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-delta" -version = "0.11.5" +version = "0.12.0" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2018" diff --git a/crates/services/autumn/Cargo.toml b/crates/services/autumn/Cargo.toml index ba426dc80..aad1efe5f 100644 --- a/crates/services/autumn/Cargo.toml +++ b/crates/services/autumn/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-autumn" -version = "0.11.5" +version = "0.12.0" edition = "2021" license = "AGPL-3.0-or-later" publish = false @@ -45,16 +45,16 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # Core crates -revolt-files = { version = "0.11.5", path = "../../core/files" } -revolt-config = { version = "0.11.5", path = "../../core/config" } -revolt-database = { version = "0.11.5", path = "../../core/database", features = [ +revolt-files = { version = "0.12.0", path = "../../core/files" } +revolt-config = { version = "0.12.0", path = "../../core/config" } +revolt-database = { version = "0.12.0", path = "../../core/database", features = [ "axum-impl", ] } -revolt-result = { version = "0.11.5", path = "../../core/result", features = [ +revolt-result = { version = "0.12.0", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-ratelimits = { version = "0.11.5", path = "../../core/ratelimits", features = ["axum"] } +revolt-ratelimits = { version = "0.12.0", path = "../../core/ratelimits", features = ["axum"] } # Axum / web server tempfile = "3.12.0" diff --git a/crates/services/gifbox/Cargo.toml b/crates/services/gifbox/Cargo.toml index 2d6d2b6e4..5a4d8e216 100644 --- a/crates/services/gifbox/Cargo.toml +++ b/crates/services/gifbox/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-gifbox" -version = "0.11.5" +version = "0.12.0" edition = "2021" license = "AGPL-3.0-or-later" publish = false @@ -17,19 +17,19 @@ tokio = { version = "1.0", features = ["full"] } reqwest = { version = "0.12", features = ["json"] } # Core crates -revolt-config = { version = "0.11.5", path = "../../core/config" } -revolt-models = { version = "0.11.5", path = "../../core/models" } -revolt-result = { version = "0.11.5", path = "../../core/result", features = [ +revolt-config = { version = "0.12.0", path = "../../core/config" } +revolt-models = { version = "0.12.0", path = "../../core/models" } +revolt-result = { version = "0.12.0", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-coalesced = { version = "0.11.5", path = "../../core/coalesced", features = [ +revolt-coalesced = { version = "0.12.0", path = "../../core/coalesced", features = [ "queue", ] } -revolt-database = { version = "0.11.5", path = "../../core/database", features = [ +revolt-database = { version = "0.12.0", path = "../../core/database", features = [ "axum-impl", ] } -revolt-ratelimits = { version = "0.11.5", path = "../../core/ratelimits", features = [ +revolt-ratelimits = { version = "0.12.0", path = "../../core/ratelimits", features = [ "axum", ] } diff --git a/crates/services/january/Cargo.toml b/crates/services/january/Cargo.toml index c1ad87591..0595827b8 100644 --- a/crates/services/january/Cargo.toml +++ b/crates/services/january/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-january" -version = "0.11.5" +version = "0.12.0" edition = "2021" license = "AGPL-3.0-or-later" publish = false @@ -33,13 +33,13 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # Core crates -revolt-config = { version = "0.11.5", path = "../../core/config" } -revolt-models = { version = "0.11.5", path = "../../core/models" } -revolt-result = { version = "0.11.5", path = "../../core/result", features = [ +revolt-config = { version = "0.12.0", path = "../../core/config" } +revolt-models = { version = "0.12.0", path = "../../core/models" } +revolt-result = { version = "0.12.0", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-files = { version = "0.11.5", path = "../../core/files" } +revolt-files = { version = "0.12.0", path = "../../core/files" } # Axum / web server axum = { version = "0.7.5" } diff --git a/version.txt b/version.txt index 62d5dbdf3..ac454c6a1 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.11.5 +0.12.0 From f0e513ccaeaa37cd9e1061133c78001a875d66bd Mon Sep 17 00:00:00 2001 From: Tom Date: Sat, 28 Mar 2026 22:35:51 -0700 Subject: [PATCH 133/211] fix: update release (me from this) please (#699) From 5466ada9ae860fcc95d0e42f6d9f85f807247bb4 Mon Sep 17 00:00:00 2001 From: Tom Date: Sat, 28 Mar 2026 22:42:13 -0700 Subject: [PATCH 134/211] Fix: release please bs 2 electric boogaloo (#701) * fix: update release (me from this) please * fix: add dep to release please * Revert "fix: update release (me from this) please" This reverts commit 0618c492c7d8a3d3af6e59a6f670105a048510c9. --- release-please-config.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/release-please-config.json b/release-please-config.json index bac633610..14710a302 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -205,6 +205,11 @@ "path": "crates/daemons/pushd/Cargo.toml", "jsonpath": "$.dependencies['revolt-presence'].version" }, + { + "type": "toml", + "path": "crates/daemons/pushd/Cargo.toml", + "jsonpath": "$.dependencies['revolt-parser'].version" + }, { "type": "toml", "path": "crates/daemons/voice-ingress/Cargo.toml", From 8814bf4c239694fe53c8ea7a59c99604d8c78f1d Mon Sep 17 00:00:00 2001 From: Tom Date: Sat, 28 Mar 2026 22:53:12 -0700 Subject: [PATCH 135/211] fix: release-please-3 (#702) --- crates/daemons/pushd/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index 3ff6daabf..95e13fb22 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -18,7 +18,7 @@ revolt-models = { version = "0.12.0", path = "../../core/models", features = [ revolt-presence = { version = "0.12.0", path = "../../core/presence", features = [ "redis-is-patched", ] } -revolt-parser = { version = "0.11.5", path = "../../core/parser" } +revolt-parser = { version = "0.12.0", path = "../../core/parser" } anyhow = { version = "1.0.98" } From 1e80916b652f1a2f118163b54e40283a1e9e94de Mon Sep 17 00:00:00 2001 From: Tom Date: Sat, 28 Mar 2026 23:05:01 -0700 Subject: [PATCH 136/211] Fix/release please fix 4 (#703) * fix: release-please-3 * fix: release please bs v4 --- Cargo.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3cf777f2f..99a062dcd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6798,7 +6798,7 @@ dependencies = [ [[package]] name = "revolt-autumn" -version = "0.11.5" +version = "0.12.0" dependencies = [ "axum", "axum-macros", @@ -6837,7 +6837,7 @@ dependencies = [ [[package]] name = "revolt-bonfire" -version = "0.11.5" +version = "0.12.0" dependencies = [ "async-channel 2.5.0", "async-std", @@ -6868,7 +6868,7 @@ dependencies = [ [[package]] name = "revolt-coalesced" -version = "0.11.5" +version = "0.12.0" dependencies = [ "indexmap 2.13.0", "lru 0.16.3", @@ -6877,7 +6877,7 @@ dependencies = [ [[package]] name = "revolt-config" -version = "0.11.5" +version = "0.12.0" dependencies = [ "async-std", "cached", @@ -6894,7 +6894,7 @@ dependencies = [ [[package]] name = "revolt-crond" -version = "0.11.5" +version = "0.12.0" dependencies = [ "log", "revolt-config", @@ -6906,7 +6906,7 @@ dependencies = [ [[package]] name = "revolt-database" -version = "0.11.5" +version = "0.12.0" dependencies = [ "amqprs", "async-lock 2.8.0", @@ -6956,7 +6956,7 @@ dependencies = [ [[package]] name = "revolt-delta" -version = "0.11.5" +version = "0.12.0" dependencies = [ "amqprs", "async-channel 1.9.0", @@ -7006,7 +7006,7 @@ dependencies = [ [[package]] name = "revolt-files" -version = "0.11.5" +version = "0.12.0" dependencies = [ "aes-gcm", "anyhow", @@ -7034,7 +7034,7 @@ dependencies = [ [[package]] name = "revolt-gifbox" -version = "0.11.5" +version = "0.12.0" dependencies = [ "axum", "axum-extra", @@ -7057,7 +7057,7 @@ dependencies = [ [[package]] name = "revolt-january" -version = "0.11.5" +version = "0.12.0" dependencies = [ "async-recursion", "axum", @@ -7085,7 +7085,7 @@ dependencies = [ [[package]] name = "revolt-models" -version = "0.11.5" +version = "0.12.0" dependencies = [ "indexmap 1.9.3", "iso8601-timestamp", @@ -7104,14 +7104,14 @@ dependencies = [ [[package]] name = "revolt-parser" -version = "0.11.5" +version = "0.12.0" dependencies = [ "logos", ] [[package]] name = "revolt-permissions" -version = "0.11.5" +version = "0.12.0" dependencies = [ "async-std", "async-trait", @@ -7126,7 +7126,7 @@ dependencies = [ [[package]] name = "revolt-presence" -version = "0.11.5" +version = "0.12.0" dependencies = [ "async-std", "log", @@ -7138,7 +7138,7 @@ dependencies = [ [[package]] name = "revolt-pushd" -version = "0.11.5" +version = "0.12.0" dependencies = [ "amqprs", "anyhow", @@ -7169,7 +7169,7 @@ dependencies = [ [[package]] name = "revolt-ratelimits" -version = "0.11.5" +version = "0.12.0" dependencies = [ "async-trait", "authifier", @@ -7186,7 +7186,7 @@ dependencies = [ [[package]] name = "revolt-result" -version = "0.11.5" +version = "0.12.0" dependencies = [ "axum", "log", @@ -7202,7 +7202,7 @@ dependencies = [ [[package]] name = "revolt-voice-ingress" -version = "0.11.5" +version = "0.12.0" dependencies = [ "amqprs", "async-std", From f81e3291bdd57af9ceedb2987b111acc7051d69c Mon Sep 17 00:00:00 2001 From: Tom Date: Tue, 31 Mar 2026 03:06:39 -0700 Subject: [PATCH 137/211] fix: test failure due to wrong assertion (#707) --- crates/core/parser/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/core/parser/src/lib.rs b/crates/core/parser/src/lib.rs index bb5b50d7c..27211c1ba 100644 --- a/crates/core/parser/src/lib.rs +++ b/crates/core/parser/src/lib.rs @@ -262,7 +262,7 @@ mod tests { ) .collect::>(); - assert_eq!(output.len(), 6); + assert_eq!(output.len(), 7); assert_eq!(output[0], MessageToken::CodeblockMarker(1)); assert_eq!( output[1], From f30b729ca90d0be6853c57ab4935694e5e59ae56 Mon Sep 17 00:00:00 2001 From: Tom Date: Tue, 31 Mar 2026 15:25:36 -0700 Subject: [PATCH 138/211] fix: don't send self dm notifications (#706) * fix: don't send self dm notifications Signed-off-by: IAmTomahawkx * fix: test failure due to wrong assertion (#707) Signed-off-by: IAmTomahawkx * fix: RA auto import moment Signed-off-by: IAmTomahawkx --------- Signed-off-by: IAmTomahawkx --- crates/core/database/src/models/messages/model.rs | 8 ++++++-- crates/core/models/src/v0/messages.rs | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/crates/core/database/src/models/messages/model.rs b/crates/core/database/src/models/messages/model.rs index fc417d791..bacb3c53f 100644 --- a/crates/core/database/src/models/messages/model.rs +++ b/crates/core/database/src/models/messages/model.rs @@ -705,7 +705,7 @@ impl Message { Some( PushNotification::from( self.clone().into_model(user, member), - Some(author), + Some(author.clone()), channel.to_owned().into(), ) .await, @@ -713,7 +713,11 @@ impl Message { self.clone(), match channel { Channel::DirectMessage { recipients, .. } - | Channel::Group { recipients, .. } => recipients.clone(), + | Channel::Group { recipients, .. } => recipients + .iter() + .filter(|uid| *uid != author.id()) + .cloned() + .collect(), Channel::TextChannel { .. } => { self.mentions.clone().unwrap_or_default() } diff --git a/crates/core/models/src/v0/messages.rs b/crates/core/models/src/v0/messages.rs index e11831757..2b03d2114 100644 --- a/crates/core/models/src/v0/messages.rs +++ b/crates/core/models/src/v0/messages.rs @@ -391,6 +391,7 @@ auto_derived!( ); /// Message Author Abstraction +#[derive(Clone)] pub enum MessageAuthor<'a> { User(&'a User), Webhook(&'a Webhook), From f2c056a1515be493b195f3f5db5886c2ddf36700 Mon Sep 17 00:00:00 2001 From: Angelo Kontaxis Date: Thu, 2 Apr 2026 03:48:22 +0100 Subject: [PATCH 139/211] fix: add migration to update existing files to be animated (#705) * fix: add migration to update existing files to be animated Signed-off-by: Zomatree * Revert "fix: add migration to update existing files to be animated" This reverts commit 4e1f1c116cd2a7f648889ce8f0c8a951024fb90e. Signed-off-by: Zomatree * fix: calculate animated for existing files when fetched Signed-off-by: Zomatree --------- Signed-off-by: Zomatree --- .../database/src/models/file_hashes/model.rs | 3 +- .../database/src/models/file_hashes/ops.rs | 6 +++ .../src/models/file_hashes/ops/mongodb.rs | 23 ++++++++++ .../src/models/file_hashes/ops/reference.rs | 26 +++++++++++- crates/core/models/src/v0/files.rs | 2 +- crates/services/autumn/src/api.rs | 42 ++++++++++++++++--- crates/services/autumn/src/metadata.rs | 2 +- 7 files changed, 92 insertions(+), 12 deletions(-) diff --git a/crates/core/database/src/models/file_hashes/model.rs b/crates/core/database/src/models/file_hashes/model.rs index b25abb12b..dfc9b96e5 100644 --- a/crates/core/database/src/models/file_hashes/model.rs +++ b/crates/core/database/src/models/file_hashes/model.rs @@ -46,8 +46,7 @@ auto_derived!( width: isize, height: isize, thumbhash: Option>, - #[serde(default)] - animated: bool, + animated: Option, }, /// File is a video with specific dimensions Video { width: isize, height: isize }, diff --git a/crates/core/database/src/models/file_hashes/ops.rs b/crates/core/database/src/models/file_hashes/ops.rs index 4b249e4cb..cdd6c936e 100644 --- a/crates/core/database/src/models/file_hashes/ops.rs +++ b/crates/core/database/src/models/file_hashes/ops.rs @@ -17,6 +17,12 @@ pub trait AbstractAttachmentHashes: Sync + Send { /// Update an attachment hash nonce value. async fn set_attachment_hash_nonce(&self, hash: &str, nonce: &str) -> Result<()>; + /// Updates the attachments animated metadata value. + /// + /// The primary use for this is to update the metadata for existing uploaded files, this + /// can only be used for images. + async fn set_attachment_hash_animated(&self, hash: &str, animated: bool) -> Result<()>; + /// Delete attachment hash by id. async fn delete_attachment_hash(&self, id: &str) -> Result<()>; } diff --git a/crates/core/database/src/models/file_hashes/ops/mongodb.rs b/crates/core/database/src/models/file_hashes/ops/mongodb.rs index e2f06067d..9e67a0a56 100644 --- a/crates/core/database/src/models/file_hashes/ops/mongodb.rs +++ b/crates/core/database/src/models/file_hashes/ops/mongodb.rs @@ -48,6 +48,29 @@ impl AbstractAttachmentHashes for MongoDb { .map_err(|_| create_database_error!("update_one", COL)) } + /// Updates the attachments animated metadata value. + /// + /// The primary use for this is to update the metadata for existing uploaded files, this + /// can only be used for images. + async fn set_attachment_hash_animated(&self, hash: &str, animated: bool) -> Result<()> { + self.col::(COL) + .update_one( + doc! { + "_id": hash, + "metadata.type": "Image", + "metadata.animated": { "$exists": false }, + }, + doc! { + "$set": { + "metadata.animated": animated + } + }, + ) + .await + .map(|_| ()) + .map_err(|_| create_database_error!("update_one", COL)) + } + /// Delete attachment hash by id. async fn delete_attachment_hash(&self, id: &str) -> Result<()> { query!(self, delete_one_by_id, COL, id).map(|_| ()) diff --git a/crates/core/database/src/models/file_hashes/ops/reference.rs b/crates/core/database/src/models/file_hashes/ops/reference.rs index 7733523e3..3c54d9e2d 100644 --- a/crates/core/database/src/models/file_hashes/ops/reference.rs +++ b/crates/core/database/src/models/file_hashes/ops/reference.rs @@ -1,7 +1,6 @@ use revolt_result::Result; -use crate::FileHash; -use crate::ReferenceDb; +use crate::{FileHash, Metadata, ReferenceDb}; use super::AbstractAttachmentHashes; @@ -39,6 +38,29 @@ impl AbstractAttachmentHashes for ReferenceDb { } } + /// Updates the attachments animated metadata value. + /// + /// The primary use for this is to update the metadata for existing uploaded files, this + /// can only be used for images. + async fn set_attachment_hash_animated(&self, hash: &str, animated: bool) -> Result<()> { + let mut hashes = self.file_hashes.lock().await; + if let Some(FileHash { + metadata: + Metadata::Image { + animated: Some(animated_metadata), + .. + }, + .. + }) = hashes.get_mut(hash) + { + *animated_metadata = animated; + + Ok(()) + } else { + Err(create_error!(NotFound)) + } + } + /// Delete attachment hash by id. async fn delete_attachment_hash(&self, id: &str) -> Result<()> { let mut file_hashes = self.file_hashes.lock().await; diff --git a/crates/core/models/src/v0/files.rs b/crates/core/models/src/v0/files.rs index 32ccf0e1d..2d68b7f2b 100644 --- a/crates/core/models/src/v0/files.rs +++ b/crates/core/models/src/v0/files.rs @@ -51,7 +51,7 @@ auto_derived!( width: usize, height: usize, thumbhash: Option>, - animated: bool, + animated: Option, }, /// File is a video with specific dimensions Video { width: usize, height: usize }, diff --git a/crates/services/autumn/src/api.rs b/crates/services/autumn/src/api.rs index 4018e72c1..49a61c43c 100644 --- a/crates/services/autumn/src/api.rs +++ b/crates/services/autumn/src/api.rs @@ -1,5 +1,5 @@ use std::{ - io::{Cursor, Read}, + io::{Cursor, Read, Write}, time::Duration, }; @@ -15,9 +15,10 @@ use lazy_static::lazy_static; use revolt_config::{config, report_internal_error}; use revolt_database::{iso8601_timestamp::Timestamp, Database, FileHash, Metadata, User}; use revolt_files::{ - create_thumbnail, decode_image, fetch_from_s3, upload_to_s3, AUTHENTICATION_TAG_SIZE_BYTES, + create_thumbnail, decode_image, fetch_from_s3, is_animated, upload_to_s3, + AUTHENTICATION_TAG_SIZE_BYTES, }; -use revolt_result::{create_error, Error, Result}; +use revolt_result::{create_error, Error, Result, ToRevoltError}; use serde::{Deserialize, Serialize}; use sha2::Digest; use tempfile::NamedTempFile; @@ -25,7 +26,9 @@ use tokio::time::Instant; use tower_http::cors::{AllowHeaders, Any, CorsLayer}; use utoipa::ToSchema; -use crate::{exif::strip_metadata, metadata::generate_metadata, mime_type::determine_mime_type, AppState}; +use crate::{ + exif::strip_metadata, metadata::generate_metadata, mime_type::determine_mime_type, AppState, +}; /// Build the API router pub async fn router() -> Router { @@ -380,7 +383,30 @@ async fn fetch_preview( let hash = file.as_hash(&db).await?; - let is_animated = matches!(hash.metadata, Metadata::Image { animated: true, .. }); + let mut data = None; + + // If animated is unset, check the file contents to see if it is animated and update the filehash + let is_animated = match &hash.metadata { + Metadata::Image { + animated: Some(value), + .. + } => *value, + Metadata::Image { animated: None, .. } => { + let file_data = retrieve_file_by_hash(&hash).await?; + + let mut named_file = NamedTempFile::new().to_internal_error()?; + named_file.write(&file_data).to_internal_error()?; + + data = Some(file_data); + + // If it fails for some reason, set it to not be animated + let animated = is_animated(&named_file, &hash.content_type).unwrap_or(false); + db.set_attachment_hash_animated(&hash.id, animated).await?; + + animated + } + _ => false, + }; // Only process image files and don't process GIFs if not avatar or icon if !matches!(hash.metadata, Metadata::Image { .. }) @@ -392,7 +418,11 @@ async fn fetch_preview( } // Original image data - let data = retrieve_file_by_hash(&hash).await?; + let data = if let Some(data) = data { + data + } else { + retrieve_file_by_hash(&hash).await? + }; // Read image and create thumbnail let data = create_thumbnail( diff --git a/crates/services/autumn/src/metadata.rs b/crates/services/autumn/src/metadata.rs index 3493cf492..8e0c89cd9 100644 --- a/crates/services/autumn/src/metadata.rs +++ b/crates/services/autumn/src/metadata.rs @@ -37,7 +37,7 @@ pub fn generate_metadata(f: &NamedTempFile, mime_type: &str) -> Metadata { thumbhash::rgba_to_thumb_hash(width as usize, height as usize, &rgba) }) .ok(), - animated: is_animated(f, mime_type).unwrap_or(false), + animated: is_animated(f, mime_type).or(Some(false)), }) .unwrap_or_default() } else if mime_type.starts_with("video/") { From fb8fe1655776791421284a6a093e86f0320c258a Mon Sep 17 00:00:00 2001 From: Damocles <106018783+Damocles078@users.noreply.github.com> Date: Thu, 2 Apr 2026 04:51:14 +0200 Subject: [PATCH 140/211] fix: mise start + missing docker image (#564) * fix: mise start + missing docker image Signed-off-by: Damocles078 * fix: bump livekit version Signed-off-by: Damocles <106018783+Damocles078@users.noreply.github.com> --------- Signed-off-by: Damocles078 Signed-off-by: Tom Signed-off-by: Damocles <106018783+Damocles078@users.noreply.github.com> Co-authored-by: Tom --- .mise/config.toml | 9 ++++++++ .mise/tasks/build | 2 +- .mise/tasks/docker/start | 8 +++++++ README.md | 46 ++++++++++++++++++++++------------------ 4 files changed, 43 insertions(+), 22 deletions(-) diff --git a/.mise/config.toml b/.mise/config.toml index 85fcd8983..f5238e777 100644 --- a/.mise/config.toml +++ b/.mise/config.toml @@ -16,4 +16,13 @@ idiomatic_version_file_enable_tools = ["rust"] [tasks.start] description = "Run all services" depends = ["docker:start", "build"] +wait_for = ["docker:start", "build"] run = [{ task = "service:*" }] + +[env] +BUILDER = "cargo" +DOCKER_NETWORK_NAME = "stoatchat_default" +DATABASE_PORT = "27017" +RABBIT_PORT = "5672" +REDIS_PORT = "6379" +_.file = { path = ".env", tools = true } diff --git a/.mise/tasks/build b/.mise/tasks/build index c97c28d80..2e584eaf4 100755 --- a/.mise/tasks/build +++ b/.mise/tasks/build @@ -2,4 +2,4 @@ #MISE description="Build project" set -e -cargo build "$@" +${BUILDER} build "$@" diff --git a/.mise/tasks/docker/start b/.mise/tasks/docker/start index cfcb0a9a5..c045a4bd0 100755 --- a/.mise/tasks/docker/start +++ b/.mise/tasks/docker/start @@ -3,3 +3,11 @@ set -e docker compose up -d + +docker run \ +--network=${DOCKER_NETWORK_NAME} \ +--name wait \ +--rm dokku/wait -c \ +rabbit:${RABBIT_PORT},\ +database:${DATABASE_PORT},\ +redis:${REDIS_PORT} diff --git a/README.md b/README.md index dd62769ae..e090149e7 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,14 @@ mise install mise build ``` +> [!TIP] +> You can override `BUILDER` in your `.env` file to run cargo with mold if you installed it: +> +> ```bash +> # .env +> BUILDER = "mold --run cargo" +> ``` + A default configuration `Revolt.toml` is present in this project that is suited for development. If you'd like to change anything, create a `Revolt.overrides.toml` file and specify relevant variables. @@ -112,7 +120,7 @@ If you'd like to change anything, create a `Revolt.overrides.toml` file and spec > - "14672:15672" > ``` > -> And corresponding Revolt configuration: +> With the corresponding Revolt configuration: > > ```toml > # Revolt.overrides.toml @@ -124,32 +132,25 @@ If you'd like to change anything, create a `Revolt.overrides.toml` file and spec > [rabbit] > port = 14072 > ``` +> +> And mise configuration +> +> ```bash +> #.env +> DATABASE_PORT = "14017" +> RABBIT_PORT = "14072" +> REDIS_PORT = "14079" +> ``` Then continue: ```bash -# start other necessary services -docker compose up -d +cp livekit.example.yml livekit.yml -# run the API server -cargo run --bin revolt-delta -# run the events server -cargo run --bin revolt-bonfire -# run the file server -cargo run --bin revolt-autumn -# run the proxy server -cargo run --bin revolt-january -# run the tenor proxy -cargo run --bin revolt-gifbox -# run the push daemon (not usually needed in regular development) -cargo run --bin revolt-pushd - -# hint: -# mold -run -# mold -run ./scripts/start.sh +mise start ``` -You can start a web client by doing the following: +You can start a web client by doing the following in another terminal: ```bash # if you do not have yarn yet and have a modern Node.js: @@ -163,6 +164,9 @@ cd stoat-web When signing up, go to http://localhost:14080 to find confirmation/password reset emails. +To stop all services, hit (CTRL + c) in the terminal you ran `mise start` and run `mise docker:stop` + + ## Deployment Guide ### Cutting new crate releases @@ -198,7 +202,7 @@ If you have bumped the crate versions, proceed to [GitHub releases](https://gith First, start the required services: ```sh -docker compose -f docker-compose.db.yml up -d +docker compose up -d ``` Now run tests for whichever database: From 4ea8f90c0d8eaad253ba152682a013a014eb57bd Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Fri, 3 Apr 2026 00:28:49 +0100 Subject: [PATCH 141/211] docs: update donation link (#709) --- docs/docs/help.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/help.md b/docs/docs/help.md index 91887e6be..7de5ca510 100644 --- a/docs/docs/help.md +++ b/docs/docs/help.md @@ -23,7 +23,7 @@ You can contribute translations through [**Weblate**](https://translate.stoat.ch ### 3. Donate Stoat is not backed by a big company, is not currently monetised (for example, via a subscription service) and does not serve you advertisements; as such, Stoat currently relies entirely on donations. -You can learn more about donating [here](https://wiki.revolt.chat/notes/project/financial-support/) - if you want to make a larger donation, please consult me first. +You can learn more about donating [here](https://ko-fi.com/stoatchat) - if you want to make a larger donation, please consult me first. ### 4. Join the project From 47336a7940a076e358ffd3c78d0614512c96f728 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Fri, 10 Apr 2026 20:44:29 +0100 Subject: [PATCH 142/211] docs: pr template (#713) --- .github/pull_request_template.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .github/pull_request_template.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 000000000..da918526e --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,24 @@ + + +Fixes # (issue) + +## How was this PR tested? + + + +- [ ] Test A +- [ ] Test B + +## Checklist: + +- [ ] I have carefully read [the contributing guidelines](https://developers.stoat.chat/developing/contrib/) +- [ ] I have performed a self-review of my own code +- [ ] I have made corresponding changes to the documentation if applicable +- [ ] I have no unrelated changes in the PR +- [ ] I have confirmed that any new dependencies are strictly necessary +- [ ] I have written tests for new code (if applicable) +- [ ] I have followed naming conventions/patterns in the surrounding code + +## Please declare, if any, LLM usage involved in creating this PR + +... From 61fd13629f9fbf750139c8928f83750502428179 Mon Sep 17 00:00:00 2001 From: "stoat-release[bot]" <245062572+stoat-release[bot]@users.noreply.github.com> Date: Sat, 11 Apr 2026 12:31:11 +0100 Subject: [PATCH 143/211] chore(main): release 0.12.1 (#700) Co-authored-by: stoat-release[bot] <245062572+stoat-release[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] --- .release-please-manifest.json | 2 +- CHANGELOG.md | 10 +++++++ Cargo.lock | 36 ++++++++++++------------- crates/bonfire/Cargo.toml | 2 +- crates/core/coalesced/Cargo.toml | 2 +- crates/core/config/Cargo.toml | 4 +-- crates/core/database/Cargo.toml | 14 +++++----- crates/core/files/Cargo.toml | 6 ++--- crates/core/models/Cargo.toml | 6 ++--- crates/core/parser/Cargo.toml | 2 +- crates/core/permissions/Cargo.toml | 4 +-- crates/core/presence/Cargo.toml | 4 +-- crates/core/ratelimits/Cargo.toml | 8 +++--- crates/core/result/Cargo.toml | 2 +- crates/daemons/crond/Cargo.toml | 10 +++---- crates/daemons/pushd/Cargo.toml | 14 +++++----- crates/daemons/voice-ingress/Cargo.toml | 2 +- crates/delta/Cargo.toml | 2 +- crates/services/autumn/Cargo.toml | 12 ++++----- crates/services/gifbox/Cargo.toml | 14 +++++----- crates/services/january/Cargo.toml | 10 +++---- version.txt | 2 +- 22 files changed, 89 insertions(+), 79 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 53d4a3f21..8950f7120 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.12.0" + ".": "0.12.1" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 7153a56f6..cc7f73283 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## [0.12.1](https://github.com/stoatchat/stoatchat/compare/v0.12.0...v0.12.1) (2026-04-10) + + +### Bug Fixes + +* add migration to update existing files to be animated ([#705](https://github.com/stoatchat/stoatchat/issues/705)) ([f2c056a](https://github.com/stoatchat/stoatchat/commit/f2c056a1515be493b195f3f5db5886c2ddf36700)) +* don't send self dm notifications ([#706](https://github.com/stoatchat/stoatchat/issues/706)) ([f30b729](https://github.com/stoatchat/stoatchat/commit/f30b729ca90d0be6853c57ab4935694e5e59ae56)) +* mise start + missing docker image ([#564](https://github.com/stoatchat/stoatchat/issues/564)) ([fb8fe16](https://github.com/stoatchat/stoatchat/commit/fb8fe1655776791421284a6a093e86f0320c258a)) +* test failure due to wrong assertion ([#707](https://github.com/stoatchat/stoatchat/issues/707)) ([f81e329](https://github.com/stoatchat/stoatchat/commit/f81e3291bdd57af9ceedb2987b111acc7051d69c)) + ## [0.12.0](https://github.com/stoatchat/stoatchat/compare/v0.11.5...v0.12.0) (2026-03-28) diff --git a/Cargo.lock b/Cargo.lock index 99a062dcd..96987c747 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6798,7 +6798,7 @@ dependencies = [ [[package]] name = "revolt-autumn" -version = "0.12.0" +version = "0.12.1" dependencies = [ "axum", "axum-macros", @@ -6837,7 +6837,7 @@ dependencies = [ [[package]] name = "revolt-bonfire" -version = "0.12.0" +version = "0.12.1" dependencies = [ "async-channel 2.5.0", "async-std", @@ -6868,7 +6868,7 @@ dependencies = [ [[package]] name = "revolt-coalesced" -version = "0.12.0" +version = "0.12.1" dependencies = [ "indexmap 2.13.0", "lru 0.16.3", @@ -6877,7 +6877,7 @@ dependencies = [ [[package]] name = "revolt-config" -version = "0.12.0" +version = "0.12.1" dependencies = [ "async-std", "cached", @@ -6894,7 +6894,7 @@ dependencies = [ [[package]] name = "revolt-crond" -version = "0.12.0" +version = "0.12.1" dependencies = [ "log", "revolt-config", @@ -6906,7 +6906,7 @@ dependencies = [ [[package]] name = "revolt-database" -version = "0.12.0" +version = "0.12.1" dependencies = [ "amqprs", "async-lock 2.8.0", @@ -6956,7 +6956,7 @@ dependencies = [ [[package]] name = "revolt-delta" -version = "0.12.0" +version = "0.12.1" dependencies = [ "amqprs", "async-channel 1.9.0", @@ -7006,7 +7006,7 @@ dependencies = [ [[package]] name = "revolt-files" -version = "0.12.0" +version = "0.12.1" dependencies = [ "aes-gcm", "anyhow", @@ -7034,7 +7034,7 @@ dependencies = [ [[package]] name = "revolt-gifbox" -version = "0.12.0" +version = "0.12.1" dependencies = [ "axum", "axum-extra", @@ -7057,7 +7057,7 @@ dependencies = [ [[package]] name = "revolt-january" -version = "0.12.0" +version = "0.12.1" dependencies = [ "async-recursion", "axum", @@ -7085,7 +7085,7 @@ dependencies = [ [[package]] name = "revolt-models" -version = "0.12.0" +version = "0.12.1" dependencies = [ "indexmap 1.9.3", "iso8601-timestamp", @@ -7104,14 +7104,14 @@ dependencies = [ [[package]] name = "revolt-parser" -version = "0.12.0" +version = "0.12.1" dependencies = [ "logos", ] [[package]] name = "revolt-permissions" -version = "0.12.0" +version = "0.12.1" dependencies = [ "async-std", "async-trait", @@ -7126,7 +7126,7 @@ dependencies = [ [[package]] name = "revolt-presence" -version = "0.12.0" +version = "0.12.1" dependencies = [ "async-std", "log", @@ -7138,7 +7138,7 @@ dependencies = [ [[package]] name = "revolt-pushd" -version = "0.12.0" +version = "0.12.1" dependencies = [ "amqprs", "anyhow", @@ -7169,7 +7169,7 @@ dependencies = [ [[package]] name = "revolt-ratelimits" -version = "0.12.0" +version = "0.12.1" dependencies = [ "async-trait", "authifier", @@ -7186,7 +7186,7 @@ dependencies = [ [[package]] name = "revolt-result" -version = "0.12.0" +version = "0.12.1" dependencies = [ "axum", "log", @@ -7202,7 +7202,7 @@ dependencies = [ [[package]] name = "revolt-voice-ingress" -version = "0.12.0" +version = "0.12.1" dependencies = [ "amqprs", "async-std", diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index e4481b1c4..c5f42a476 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-bonfire" -version = "0.12.0" +version = "0.12.1" license = "AGPL-3.0-or-later" edition = "2021" publish = false diff --git a/crates/core/coalesced/Cargo.toml b/crates/core/coalesced/Cargo.toml index 4b589c0d5..2e770bd72 100644 --- a/crates/core/coalesced/Cargo.toml +++ b/crates/core/coalesced/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-coalesced" -version = "0.12.0" +version = "0.12.1" edition = "2021" license = "MIT" authors = ["Paul Makles ", "Zomatree "] diff --git a/crates/core/config/Cargo.toml b/crates/core/config/Cargo.toml index ad1ee4692..e74cbca40 100644 --- a/crates/core/config/Cargo.toml +++ b/crates/core/config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-config" -version = "0.12.0" +version = "0.12.1" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -38,4 +38,4 @@ sentry = { version = "0.31.5", optional = true } sentry-anyhow = { version = "0.38.1", optional = true } # Core -revolt-result = { version = "0.12.0", path = "../result", optional = true } +revolt-result = { version = "0.12.1", path = "../result", optional = true } diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index 05a66179a..fafbccd46 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-database" -version = "0.12.0" +version = "0.12.1" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -32,19 +32,19 @@ default = ["mongodb", "async-std-runtime", "tasks"] [dependencies] # Core -revolt-config = { version = "0.12.0", path = "../config", features = [ +revolt-config = { version = "0.12.1", path = "../config", features = [ "report-macros", ] } -revolt-result = { version = "0.12.0", path = "../result" } -revolt-models = { version = "0.12.0", path = "../models", features = [ +revolt-result = { version = "0.12.1", path = "../result" } +revolt-models = { version = "0.12.1", path = "../models", features = [ "validator", ] } -revolt-presence = { version = "0.12.0", path = "../presence" } -revolt-permissions = { version = "0.12.0", path = "../permissions", features = [ +revolt-presence = { version = "0.12.1", path = "../presence" } +revolt-permissions = { version = "0.12.1", path = "../permissions", features = [ "serde", "bson", ] } -revolt-parser = { version = "0.12.0", path = "../parser" } +revolt-parser = { version = "0.12.1", path = "../parser" } # Utility log = "0.4" diff --git a/crates/core/files/Cargo.toml b/crates/core/files/Cargo.toml index 2a4a52054..926b8c158 100644 --- a/crates/core/files/Cargo.toml +++ b/crates/core/files/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-files" -version = "0.12.0" +version = "0.12.1" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -27,10 +27,10 @@ typenum = "1.17.0" aws-config = "1.5.5" aws-sdk-s3 = { version = "1.46.0", features = ["behavior-version-latest"] } -revolt-config = { version = "0.12.0", path = "../config", features = [ +revolt-config = { version = "0.12.1", path = "../config", features = [ "report-macros", ] } -revolt-result = { version = "0.12.0", path = "../result" } +revolt-result = { version = "0.12.1", path = "../result" } # image processing jxl-oxide = { workspace = true } diff --git a/crates/core/models/Cargo.toml b/crates/core/models/Cargo.toml index a1a65e194..34fd5a151 100644 --- a/crates/core/models/Cargo.toml +++ b/crates/core/models/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-models" -version = "0.12.0" +version = "0.12.1" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -21,8 +21,8 @@ default = ["serde", "partials", "rocket"] [dependencies] # Core -revolt-config = { version = "0.12.0", path = "../config" } -revolt-permissions = { version = "0.12.0", path = "../permissions" } +revolt-config = { version = "0.12.1", path = "../config" } +revolt-permissions = { version = "0.12.1", path = "../permissions" } # Utility regex = "1.11" diff --git a/crates/core/parser/Cargo.toml b/crates/core/parser/Cargo.toml index f542b7aaf..20d9e8c79 100644 --- a/crates/core/parser/Cargo.toml +++ b/crates/core/parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-parser" -version = "0.12.0" +version = "0.12.1" edition = "2021" license = "MIT" authors = ["Zomatree ", "Paul Makles "] diff --git a/crates/core/permissions/Cargo.toml b/crates/core/permissions/Cargo.toml index 98edf99bc..f351e0593 100644 --- a/crates/core/permissions/Cargo.toml +++ b/crates/core/permissions/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-permissions" -version = "0.12.0" +version = "0.12.1" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -22,7 +22,7 @@ async-std = { version = "1.8.0", features = ["attributes"] } [dependencies] # Core -revolt-result = { version = "0.12.0", path = "../result" } +revolt-result = { version = "0.12.1", path = "../result" } # Utility auto_ops = "0.3.0" diff --git a/crates/core/presence/Cargo.toml b/crates/core/presence/Cargo.toml index 3b3ce3ee9..899fef51b 100644 --- a/crates/core/presence/Cargo.toml +++ b/crates/core/presence/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-presence" -version = "0.12.0" +version = "0.12.1" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -17,7 +17,7 @@ redis-is-patched = [] async-std = { version = "1.8.0", features = ["attributes"] } # Config for loading Redis URI -revolt-config = { version = "0.12.0", path = "../config" } +revolt-config = { version = "0.12.1", path = "../config" } [dependencies] # Utility diff --git a/crates/core/ratelimits/Cargo.toml b/crates/core/ratelimits/Cargo.toml index 54c1a702d..0bdca6bf8 100644 --- a/crates/core/ratelimits/Cargo.toml +++ b/crates/core/ratelimits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-ratelimits" -version = "0.12.0" +version = "0.12.1" edition = "2024" license = "MIT" authors = ["Zomatree ", "Paul Makles "] @@ -18,9 +18,9 @@ axum = ["dep:axum", "revolt-database/axum-impl"] default = ["rocket", "axum"] [dependencies] -revolt-database = { version = "0.12.0", path = "../database" } -revolt-result = { version = "0.12.0", path = "../result" } -revolt-config = { version = "0.12.0", path = "../config" } +revolt-database = { version = "0.12.1", path = "../database" } +revolt-result = { version = "0.12.1", path = "../result" } +revolt-config = { version = "0.12.1", path = "../config" } rocket = { version = "0.5.1", optional = true } revolt_rocket_okapi = { version = "0.10.0", optional = true } diff --git a/crates/core/result/Cargo.toml b/crates/core/result/Cargo.toml index 0ebcc4e2e..de21e357c 100644 --- a/crates/core/result/Cargo.toml +++ b/crates/core/result/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-result" -version = "0.12.0" +version = "0.12.1" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/daemons/crond/Cargo.toml b/crates/daemons/crond/Cargo.toml index 1f9de2b09..570729cd9 100644 --- a/crates/daemons/crond/Cargo.toml +++ b/crates/daemons/crond/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-crond" -version = "0.12.0" +version = "0.12.1" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2021" @@ -17,7 +17,7 @@ log = "0.4" tokio = { version = "1" } # Core -revolt-database = { version = "0.12.0", path = "../../core/database" } -revolt-result = { version = "0.12.0", path = "../../core/result" } -revolt-config = { version = "0.12.0", path = "../../core/config" } -revolt-files = { version = "0.12.0", path = "../../core/files" } +revolt-database = { version = "0.12.1", path = "../../core/database" } +revolt-result = { version = "0.12.1", path = "../../core/result" } +revolt-config = { version = "0.12.1", path = "../../core/config" } +revolt-files = { version = "0.12.1", path = "../../core/files" } diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index 95e13fb22..2a3d4fc10 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -1,24 +1,24 @@ [package] name = "revolt-pushd" -version = "0.12.0" +version = "0.12.1" edition = "2021" license = "AGPL-3.0-or-later" publish = false [dependencies] -revolt-result = { version = "0.12.0", path = "../../core/result" } -revolt-config = { version = "0.12.0", path = "../../core/config", features = [ +revolt-result = { version = "0.12.1", path = "../../core/result" } +revolt-config = { version = "0.12.1", path = "../../core/config", features = [ "report-macros", "anyhow", ] } -revolt-database = { version = "0.12.0", path = "../../core/database" } -revolt-models = { version = "0.12.0", path = "../../core/models", features = [ +revolt-database = { version = "0.12.1", path = "../../core/database" } +revolt-models = { version = "0.12.1", path = "../../core/models", features = [ "validator", ] } -revolt-presence = { version = "0.12.0", path = "../../core/presence", features = [ +revolt-presence = { version = "0.12.1", path = "../../core/presence", features = [ "redis-is-patched", ] } -revolt-parser = { version = "0.12.0", path = "../../core/parser" } +revolt-parser = { version = "0.12.1", path = "../../core/parser" } anyhow = { version = "1.0.98" } diff --git a/crates/daemons/voice-ingress/Cargo.toml b/crates/daemons/voice-ingress/Cargo.toml index 0b498d930..f41e4ec12 100644 --- a/crates/daemons/voice-ingress/Cargo.toml +++ b/crates/daemons/voice-ingress/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-voice-ingress" -version = "0.12.0" +version = "0.12.1" license = "AGPL-3.0-or-later" edition = "2021" publish = false diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index 7976d2086..47cd64ac2 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-delta" -version = "0.12.0" +version = "0.12.1" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2018" diff --git a/crates/services/autumn/Cargo.toml b/crates/services/autumn/Cargo.toml index aad1efe5f..521d91b72 100644 --- a/crates/services/autumn/Cargo.toml +++ b/crates/services/autumn/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-autumn" -version = "0.12.0" +version = "0.12.1" edition = "2021" license = "AGPL-3.0-or-later" publish = false @@ -45,16 +45,16 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # Core crates -revolt-files = { version = "0.12.0", path = "../../core/files" } -revolt-config = { version = "0.12.0", path = "../../core/config" } -revolt-database = { version = "0.12.0", path = "../../core/database", features = [ +revolt-files = { version = "0.12.1", path = "../../core/files" } +revolt-config = { version = "0.12.1", path = "../../core/config" } +revolt-database = { version = "0.12.1", path = "../../core/database", features = [ "axum-impl", ] } -revolt-result = { version = "0.12.0", path = "../../core/result", features = [ +revolt-result = { version = "0.12.1", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-ratelimits = { version = "0.12.0", path = "../../core/ratelimits", features = ["axum"] } +revolt-ratelimits = { version = "0.12.1", path = "../../core/ratelimits", features = ["axum"] } # Axum / web server tempfile = "3.12.0" diff --git a/crates/services/gifbox/Cargo.toml b/crates/services/gifbox/Cargo.toml index 5a4d8e216..ae689d8e9 100644 --- a/crates/services/gifbox/Cargo.toml +++ b/crates/services/gifbox/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-gifbox" -version = "0.12.0" +version = "0.12.1" edition = "2021" license = "AGPL-3.0-or-later" publish = false @@ -17,19 +17,19 @@ tokio = { version = "1.0", features = ["full"] } reqwest = { version = "0.12", features = ["json"] } # Core crates -revolt-config = { version = "0.12.0", path = "../../core/config" } -revolt-models = { version = "0.12.0", path = "../../core/models" } -revolt-result = { version = "0.12.0", path = "../../core/result", features = [ +revolt-config = { version = "0.12.1", path = "../../core/config" } +revolt-models = { version = "0.12.1", path = "../../core/models" } +revolt-result = { version = "0.12.1", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-coalesced = { version = "0.12.0", path = "../../core/coalesced", features = [ +revolt-coalesced = { version = "0.12.1", path = "../../core/coalesced", features = [ "queue", ] } -revolt-database = { version = "0.12.0", path = "../../core/database", features = [ +revolt-database = { version = "0.12.1", path = "../../core/database", features = [ "axum-impl", ] } -revolt-ratelimits = { version = "0.12.0", path = "../../core/ratelimits", features = [ +revolt-ratelimits = { version = "0.12.1", path = "../../core/ratelimits", features = [ "axum", ] } diff --git a/crates/services/january/Cargo.toml b/crates/services/january/Cargo.toml index 0595827b8..b2bc30e62 100644 --- a/crates/services/january/Cargo.toml +++ b/crates/services/january/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-january" -version = "0.12.0" +version = "0.12.1" edition = "2021" license = "AGPL-3.0-or-later" publish = false @@ -33,13 +33,13 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # Core crates -revolt-config = { version = "0.12.0", path = "../../core/config" } -revolt-models = { version = "0.12.0", path = "../../core/models" } -revolt-result = { version = "0.12.0", path = "../../core/result", features = [ +revolt-config = { version = "0.12.1", path = "../../core/config" } +revolt-models = { version = "0.12.1", path = "../../core/models" } +revolt-result = { version = "0.12.1", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-files = { version = "0.12.0", path = "../../core/files" } +revolt-files = { version = "0.12.1", path = "../../core/files" } # Axum / web server axum = { version = "0.7.5" } diff --git a/version.txt b/version.txt index ac454c6a1..34a83616b 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.12.0 +0.12.1 From 144e939c6bca85ae0162645bb45949e22796c928 Mon Sep 17 00:00:00 2001 From: infi Date: Sun, 12 Apr 2026 01:46:05 +0200 Subject: [PATCH 144/211] docs: add run in yaak button to endpoints page (#711) --- docs/docs/developers/endpoints.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/docs/developers/endpoints.md b/docs/docs/developers/endpoints.md index a89b4d3ee..99a7d6f44 100644 --- a/docs/docs/developers/endpoints.md +++ b/docs/docs/developers/endpoints.md @@ -4,6 +4,8 @@ sidebar_position: 1 # Endpoints +[![Run in Yaak](https://external.stoatusercontent.com/proxy?url=https://yaak.app/static/button.svg)](https://yaak.app/button/run?name=Stoat+API&url=https%3A%2F%2Fstoat.chat%2Fapi%2Fopenapi.json) + **We are moving stuff around currently following the rebrand, guidance will follow soon!** You can connect to the API on the following URLs: From 3675ff1a1ff4d91856a5cfe66f866cab64869a22 Mon Sep 17 00:00:00 2001 From: Angelo Kontaxis Date: Sat, 18 Apr 2026 03:02:18 +0100 Subject: [PATCH 145/211] chore: migrate all local dependancies to workspace dependancies (#710) * chore: start moving all deps to workspace deps Signed-off-by: Zomatree * chore: migrate all deps to workspace deps Signed-off-by: Zomatree * chore: add more dep groups Signed-off-by: Zomatree * fix: add migration to update existing files to be animated (#705) * fix: add migration to update existing files to be animated Signed-off-by: Zomatree * Revert "fix: add migration to update existing files to be animated" This reverts commit 4e1f1c116cd2a7f648889ce8f0c8a951024fb90e. Signed-off-by: Zomatree * fix: calculate animated for existing files when fetched Signed-off-by: Zomatree --------- Signed-off-by: Zomatree * fix: mise start + missing docker image (#564) * fix: mise start + missing docker image Signed-off-by: Damocles078 * fix: bump livekit version Signed-off-by: Damocles <106018783+Damocles078@users.noreply.github.com> --------- Signed-off-by: Damocles078 Signed-off-by: Tom Signed-off-by: Damocles <106018783+Damocles078@users.noreply.github.com> Co-authored-by: Tom * docs: update donation link (#709) Signed-off-by: Zomatree * fix: remove usage of deprecated functions Signed-off-by: Zomatree --------- Signed-off-by: Zomatree Signed-off-by: Damocles078 Signed-off-by: Tom Signed-off-by: Damocles <106018783+Damocles078@users.noreply.github.com> Co-authored-by: Damocles <106018783+Damocles078@users.noreply.github.com> Co-authored-by: Tom Co-authored-by: Paul Makles --- Cargo.lock | 3779 +++++++++-------- Cargo.toml | 169 +- crates/bonfire/Cargo.toml | 54 +- crates/bonfire/src/events/state.rs | 6 +- crates/core/coalesced/Cargo.toml | 8 +- crates/core/config/Cargo.toml | 22 +- crates/core/database/Cargo.toml | 97 +- .../src/models/messages/ops/reference.rs | 4 +- crates/core/files/Cargo.toml | 32 +- crates/core/models/Cargo.toml | 26 +- crates/core/parser/Cargo.toml | 2 +- crates/core/permissions/Cargo.toml | 18 +- crates/core/presence/Cargo.toml | 12 +- crates/core/ratelimits/Cargo.toml | 22 +- crates/core/result/Cargo.toml | 20 +- crates/daemons/crond/Cargo.toml | 12 +- crates/daemons/pushd/Cargo.toml | 57 +- crates/daemons/voice-ingress/Cargo.toml | 44 +- crates/delta/Cargo.toml | 87 +- .../routes/channels/message_bulk_delete.rs | 10 +- .../delta/src/routes/channels/message_send.rs | 11 +- crates/services/autumn/Cargo.toml | 71 +- crates/services/gifbox/Cargo.toml | 43 +- crates/services/january/Cargo.toml | 47 +- release-please-config.json | 199 +- 25 files changed, 2463 insertions(+), 2389 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 96987c747..7322d38f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 4 [[package]] name = "addr2line" -version = "0.24.2" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" dependencies = [ "gimli", ] @@ -58,7 +58,7 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", "once_cell", "version_check", ] @@ -70,7 +70,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", - "getrandom 0.3.3", + "getrandom 0.3.4", "once_cell", "version_check", "zerocopy", @@ -78,9 +78,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] @@ -126,11 +126,11 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "amqp_serde" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46af430da4849b906416235798be5d0b8ff07e478d9809f05a00f81eb9527781" +checksum = "f5f450f572a1ec4cdb4af7af09cbd0c7c3e1b9da2bfc7414c059a780993a8e16" dependencies = [ - "bytes 1.10.1", + "bytes 1.11.1", "serde", "serde_bytes", ] @@ -143,10 +143,10 @@ checksum = "3f1b4afcbd862e16c272b7625b6b057930b052d63c720bc90f6afab0d9abe8a8" dependencies = [ "amqp_serde", "async-trait", - "bytes 1.10.1", + "bytes 1.11.1", "serde", "serde_bytes_ng", - "tokio 1.49.0", + "tokio 1.51.0", ] [[package]] @@ -160,12 +160,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.100" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" -dependencies = [ - "backtrace", -] +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] name = "arbitrary" @@ -175,9 +172,12 @@ checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" [[package]] name = "arc-swap" -version = "1.7.1" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" +checksum = "6a3a1fd6f75306b68087b831f025c712524bcb19aad54e557b1129cfa0a2b207" +dependencies = [ + "rustversion", +] [[package]] name = "arg_enum_proc_macro" @@ -186,8 +186,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -217,7 +217,7 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5" dependencies = [ - "quote 1.0.40", + "quote 1.0.45", "syn 1.0.109", ] @@ -241,20 +241,20 @@ dependencies = [ "concurrent-queue", "event-listener-strategy", "futures-core", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", ] [[package]] name = "async-executor" -version = "1.13.3" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497c00e0fd83a72a79a39fcbd8e3e2f055d6f6c7e025f3b3d91f4f8e76527fb8" +checksum = "c96bf972d85afc50bf5ab8fe2d54d1586b4e0b46c97c50a0c9e71e2f7bcd812a" dependencies = [ "async-task", "concurrent-queue", - "fastrand 2.3.0", - "futures-lite 2.6.1", - "pin-project-lite 0.2.16", + "fastrand 2.4.0", + "futures-lite", + "pin-project-lite 0.2.17", "slab", ] @@ -267,12 +267,12 @@ dependencies = [ "async-channel 2.5.0", "async-executor", "async-io", - "async-lock 3.4.1", + "async-lock 3.4.2", "blocking", - "futures-lite 2.6.1", + "futures-lite", "once_cell", "tokio 0.2.25", - "tokio 1.49.0", + "tokio 1.51.0", ] [[package]] @@ -281,16 +281,16 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" dependencies = [ - "autocfg 1.5.0", + "autocfg", "cfg-if", "concurrent-queue", "futures-io", - "futures-lite 2.6.1", + "futures-lite", "parking", - "polling 3.11.0", + "polling", "rustix", "slab", - "windows-sys 0.61.0", + "windows-sys 0.61.2", ] [[package]] @@ -304,13 +304,13 @@ dependencies = [ [[package]] name = "async-lock" -version = "3.4.1" +version = "3.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc" +checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" dependencies = [ "event-listener 5.4.1", "event-listener-strategy", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", ] [[package]] @@ -321,13 +321,13 @@ checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75" dependencies = [ "async-channel 2.5.0", "async-io", - "async-lock 3.4.1", + "async-lock 3.4.2", "async-signal", "async-task", "blocking", "cfg-if", "event-listener 5.4.1", - "futures-lite 2.6.1", + "futures-lite", "rustix", ] @@ -338,8 +338,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -349,7 +349,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43c070bbf59cd3570b6b2dd54cd772527c7c3620fce8be898406dd3ed6adc64c" dependencies = [ "async-io", - "async-lock 3.4.1", + "async-lock 3.4.2", "atomic-waker", "cfg-if", "futures-core", @@ -357,7 +357,7 @@ dependencies = [ "rustix", "signal-hook-registry", "slab", - "windows-sys 0.61.0", + "windows-sys 0.61.2", ] [[package]] @@ -370,19 +370,19 @@ dependencies = [ "async-channel 1.9.0", "async-global-executor", "async-io", - "async-lock 3.4.1", + "async-lock 3.4.2", "async-process", "crossbeam-utils", "futures-channel", "futures-core", "futures-io", - "futures-lite 2.6.1", + "futures-lite", "gloo-timers", "kv-log-macro", "log", "memchr", "once_cell", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", "pin-utils", "slab", "wasm-bindgen-futures", @@ -396,7 +396,7 @@ checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" dependencies = [ "async-stream-impl", "futures-core", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", ] [[package]] @@ -406,8 +406,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -423,8 +423,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -437,7 +437,7 @@ dependencies = [ "futures-io", "futures-util", "log", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", "tungstenite", ] @@ -499,7 +499,7 @@ dependencies = [ "revolt_rocket_okapi", "rocket", "rust-argon2", - "schemars 0.8.22", + "schemars", "serde", "serde_json", "sha1", @@ -514,15 +514,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7460f7dd8e100147b82a63afca1a20eb6c231ee36b90ba7272e14951cb58af59" -[[package]] -name = "autocfg" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" -dependencies = [ - "autocfg 1.5.0", -] - [[package]] name = "autocfg" version = "1.5.0" @@ -551,32 +542,32 @@ dependencies = [ [[package]] name = "av1-grain" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f3efb2ca85bc610acfa917b5aaa36f3fcbebed5b3182d7f877b02531c4b80c8" +checksum = "8cfddb07216410377231960af4fcab838eaa12e013417781b78bd95ee22077f8" dependencies = [ "anyhow", "arrayvec", "log", - "nom", + "nom 8.0.0", "num-rational", "v_frame", ] [[package]] name = "avif-serialize" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47c8fbc0f831f4519fe8b810b6a7a91410ec83031b8233f730a0480029f6a23f" +checksum = "375082f007bd67184fb9c0374614b29f9aaa604ec301635f72338bb65386a53d" dependencies = [ "arrayvec", ] [[package]] name = "aws-config" -version = "1.8.6" +version = "1.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bc1b40fb26027769f16960d2f4a6bc20c4bb755d403e552c8c1a73af433c246" +checksum = "11493b0bad143270fb8ad284a096dd529ba91924c5409adeac856cc1bf047dbc" dependencies = [ "aws-credential-types", "aws-runtime", @@ -590,13 +581,13 @@ dependencies = [ "aws-smithy-runtime-api", "aws-smithy-types", "aws-types", - "bytes 1.10.1", - "fastrand 2.3.0", + "bytes 1.11.1", + "fastrand 2.4.0", "hex", - "http 1.3.1", - "ring", + "http 1.4.0", + "sha1", "time", - "tokio 1.49.0", + "tokio 1.51.0", "tracing", "url", "zeroize", @@ -604,9 +595,9 @@ dependencies = [ [[package]] name = "aws-credential-types" -version = "1.2.6" +version = "1.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d025db5d9f52cbc413b167136afb3d8aeea708c0d8884783cf6253be5e22f6f2" +checksum = "8f20799b373a1be121fe3005fba0c2090af9411573878f224df44b42727fcaf7" dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api", @@ -616,9 +607,9 @@ dependencies = [ [[package]] name = "aws-lc-rs" -version = "1.14.0" +version = "1.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94b8ff6c09cd57b16da53641caa860168b88c172a5ee163b0288d3d6eea12786" +checksum = "a054912289d18629dc78375ba2c3726a3afe3ff71b4edba9dedfca0e3446d1fc" dependencies = [ "aws-lc-sys", "zeroize", @@ -626,11 +617,10 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.31.0" +version = "0.39.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e44d16778acaf6a9ec9899b92cebd65580b83f685446bf2e1f5d3d732f99dcd" +checksum = "83a25cf98105baa966497416dbd42565ce3a8cf8dbfd59803ec9ad46f3126399" dependencies = [ - "bindgen", "cc", "cmake", "dunce", @@ -639,9 +629,9 @@ dependencies = [ [[package]] name = "aws-runtime" -version = "1.5.10" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c034a1bc1d70e16e7f4e4caf7e9f7693e4c9c24cd91cf17c2a0b21abaebc7c8b" +checksum = "5fc0651c57e384202e47153c1260b84a9936e19803d747615edf199dc3b98d17" dependencies = [ "aws-credential-types", "aws-sigv4", @@ -652,21 +642,24 @@ dependencies = [ "aws-smithy-runtime-api", "aws-smithy-types", "aws-types", - "bytes 1.10.1", - "fastrand 2.3.0", + "bytes 1.11.1", + "bytes-utils", + "fastrand 2.4.0", "http 0.2.12", + "http 1.4.0", "http-body 0.4.6", + "http-body 1.0.1", "percent-encoding", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", "tracing", "uuid", ] [[package]] name = "aws-sdk-s3" -version = "1.106.0" +version = "1.128.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c230530df49ed3f2b7b4d9c8613b72a04cdac6452eede16d587fc62addfabac" +checksum = "99304b64672e0d81a3c100a589b93d9ef5e9c0ce12e21c848fd39e50f493c2a1" dependencies = [ "aws-credential-types", "aws-runtime", @@ -676,19 +669,20 @@ dependencies = [ "aws-smithy-eventstream", "aws-smithy-http", "aws-smithy-json", + "aws-smithy-observability", "aws-smithy-runtime", "aws-smithy-runtime-api", "aws-smithy-types", "aws-smithy-xml", "aws-types", - "bytes 1.10.1", - "fastrand 2.3.0", + "bytes 1.11.1", + "fastrand 2.4.0", "hex", "hmac", "http 0.2.12", - "http 1.3.1", - "http-body 0.4.6", - "lru 0.12.5", + "http 1.4.0", + "http-body 1.0.1", + "lru", "percent-encoding", "regex-lite", "sha2", @@ -698,89 +692,95 @@ dependencies = [ [[package]] name = "aws-sdk-sso" -version = "1.84.0" +version = "1.97.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357a841807f6b52cb26123878b3326921e2a25faca412fabdd32bd35b7edd5d3" +checksum = "9aadc669e184501caaa6beafb28c6267fc1baef0810fb58f9b205485ca3f2567" dependencies = [ "aws-credential-types", "aws-runtime", "aws-smithy-async", "aws-smithy-http", "aws-smithy-json", + "aws-smithy-observability", "aws-smithy-runtime", "aws-smithy-runtime-api", "aws-smithy-types", "aws-types", - "bytes 1.10.1", - "fastrand 2.3.0", + "bytes 1.11.1", + "fastrand 2.4.0", "http 0.2.12", + "http 1.4.0", "regex-lite", "tracing", ] [[package]] name = "aws-sdk-ssooidc" -version = "1.85.0" +version = "1.99.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67e05f33b6c9026fecfe9b3b6740f34d41bc6ff641a6a32dabaab60209245b75" +checksum = "1342a7db8f358d3de0aed2007a0b54e875458e39848d54cc1d46700b2bfcb0a8" dependencies = [ "aws-credential-types", "aws-runtime", "aws-smithy-async", "aws-smithy-http", "aws-smithy-json", + "aws-smithy-observability", "aws-smithy-runtime", "aws-smithy-runtime-api", "aws-smithy-types", "aws-types", - "bytes 1.10.1", - "fastrand 2.3.0", + "bytes 1.11.1", + "fastrand 2.4.0", "http 0.2.12", + "http 1.4.0", "regex-lite", "tracing", ] [[package]] name = "aws-sdk-sts" -version = "1.86.0" +version = "1.101.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7d835f123f307cafffca7b9027c14979f1d403b417d8541d67cf252e8a21e35" +checksum = "ab41ad64e4051ecabeea802d6a17845a91e83287e1dd249e6963ea1ba78c428a" dependencies = [ "aws-credential-types", "aws-runtime", "aws-smithy-async", "aws-smithy-http", "aws-smithy-json", + "aws-smithy-observability", "aws-smithy-query", "aws-smithy-runtime", "aws-smithy-runtime-api", "aws-smithy-types", "aws-smithy-xml", "aws-types", - "fastrand 2.3.0", + "fastrand 2.4.0", "http 0.2.12", + "http 1.4.0", "regex-lite", "tracing", ] [[package]] name = "aws-sigv4" -version = "1.3.4" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "084c34162187d39e3740cb635acd73c4e3a551a36146ad6fe8883c929c9f876c" +checksum = "b0b660013a6683ab23797778e21f1f854744fdf05f68204b4cca4c8c04b5d1f4" dependencies = [ "aws-credential-types", "aws-smithy-eventstream", "aws-smithy-http", "aws-smithy-runtime-api", "aws-smithy-types", - "bytes 1.10.1", + "bytes 1.11.1", "crypto-bigint 0.5.5", "form_urlencoded", "hex", "hmac", "http 0.2.12", - "http 1.3.1", + "http 1.4.0", "p256 0.11.1", "percent-encoding", "ring", @@ -793,30 +793,31 @@ dependencies = [ [[package]] name = "aws-smithy-async" -version = "1.2.5" +version = "1.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e190749ea56f8c42bf15dd76c65e14f8f765233e6df9b0506d9d934ebef867c" +checksum = "2ffcaf626bdda484571968400c326a244598634dc75fd451325a54ad1a59acfc" dependencies = [ "futures-util", - "pin-project-lite 0.2.16", - "tokio 1.49.0", + "pin-project-lite 0.2.17", + "tokio 1.51.0", ] [[package]] name = "aws-smithy-checksums" -version = "0.63.8" +version = "0.64.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56d2df0314b8e307995a3b86d44565dfe9de41f876901a7d71886c756a25979f" +checksum = "6750f3dd509b0694a4377f0293ed2f9630d710b1cebe281fa8bac8f099f88bc6" dependencies = [ "aws-smithy-http", "aws-smithy-types", - "bytes 1.10.1", + "bytes 1.11.1", "crc-fast", "hex", - "http 0.2.12", - "http-body 0.4.6", + "http 1.4.0", + "http-body 1.0.1", + "http-body-util", "md-5", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", "sha1", "sha2", "tracing", @@ -824,89 +825,90 @@ dependencies = [ [[package]] name = "aws-smithy-eventstream" -version = "0.60.11" +version = "0.60.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "182b03393e8c677347fb5705a04a9392695d47d20ef0a2f8cfe28c8e6b9b9778" +checksum = "faf09d74e5e32f76b8762da505a3cd59303e367a664ca67295387baa8c1d7548" dependencies = [ "aws-smithy-types", - "bytes 1.10.1", + "bytes 1.11.1", "crc32fast", ] [[package]] name = "aws-smithy-http" -version = "0.62.3" +version = "0.63.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c4dacf2d38996cf729f55e7a762b30918229917eca115de45dfa8dfb97796c9" +checksum = "ba1ab2dc1c2c3749ead27180d333c42f11be8b0e934058fb4b2258ee8dbe5231" dependencies = [ "aws-smithy-eventstream", "aws-smithy-runtime-api", "aws-smithy-types", - "bytes 1.10.1", + "bytes 1.11.1", "bytes-utils", "futures-core", - "http 0.2.12", - "http 1.3.1", - "http-body 0.4.6", + "futures-util", + "http 1.4.0", + "http-body 1.0.1", + "http-body-util", "percent-encoding", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", "pin-utils", "tracing", ] [[package]] name = "aws-smithy-http-client" -version = "1.1.1" +version = "1.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147e8eea63a40315d704b97bf9bc9b8c1402ae94f89d5ad6f7550d963309da1b" +checksum = "6a2f165a7feee6f263028b899d0a181987f4fa7179a6411a32a439fba7c5f769" dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api", "aws-smithy-types", "h2 0.3.27", - "h2 0.4.12", + "h2 0.4.13", "http 0.2.12", - "http 1.3.1", + "http 1.4.0", "http-body 0.4.6", "hyper 0.14.32", - "hyper 1.7.0", + "hyper 1.9.0", "hyper-rustls 0.24.2", "hyper-rustls 0.27.7", "hyper-util", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", "rustls 0.21.12", - "rustls 0.23.32", - "rustls-native-certs 0.8.1", + "rustls 0.23.37", + "rustls-native-certs 0.8.3", "rustls-pki-types", - "tokio 1.49.0", - "tokio-rustls 0.26.3", + "tokio 1.51.0", + "tokio-rustls 0.26.4", "tower", "tracing", ] [[package]] name = "aws-smithy-json" -version = "0.61.5" +version = "0.62.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaa31b350998e703e9826b2104dd6f63be0508666e1aba88137af060e8944047" +checksum = "9648b0bb82a2eedd844052c6ad2a1a822d1f8e3adee5fbf668366717e428856a" dependencies = [ "aws-smithy-types", ] [[package]] name = "aws-smithy-observability" -version = "0.1.3" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9364d5989ac4dd918e5cc4c4bdcc61c9be17dcd2586ea7f69e348fc7c6cab393" +checksum = "a06c2315d173edbf1920da8ba3a7189695827002e4c0fc961973ab1c54abca9c" dependencies = [ "aws-smithy-runtime-api", ] [[package]] name = "aws-smithy-query" -version = "0.60.7" +version = "0.60.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2fbd61ceb3fe8a1cb7352e42689cec5335833cd9f94103a61e98f9bb61c64bb" +checksum = "1a56d79744fb3edb5d722ef79d86081e121d3b9422cb209eb03aea6aa4f21ebd" dependencies = [ "aws-smithy-types", "urlencoding", @@ -914,9 +916,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime" -version = "1.9.2" +version = "1.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fa63ad37685ceb7762fa4d73d06f1d5493feb88e3f27259b9ed277f4c01b185" +checksum = "028999056d2d2fd58a697232f9eec4a643cf73a71cf327690a7edad1d2af2110" dependencies = [ "aws-smithy-async", "aws-smithy-http", @@ -924,75 +926,76 @@ dependencies = [ "aws-smithy-observability", "aws-smithy-runtime-api", "aws-smithy-types", - "bytes 1.10.1", - "fastrand 2.3.0", + "bytes 1.11.1", + "fastrand 2.4.0", "http 0.2.12", - "http 1.3.1", + "http 1.4.0", "http-body 0.4.6", "http-body 1.0.1", - "pin-project-lite 0.2.16", + "http-body-util", + "pin-project-lite 0.2.17", "pin-utils", - "tokio 1.49.0", + "tokio 1.51.0", "tracing", ] [[package]] name = "aws-smithy-runtime-api" -version = "1.9.0" +version = "1.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07f5e0fc8a6b3f2303f331b94504bbf754d85488f402d6f1dd7a6080f99afe56" +checksum = "876ab3c9c29791ba4ba02b780a3049e21ec63dabda09268b175272c3733a79e6" dependencies = [ "aws-smithy-async", "aws-smithy-types", - "bytes 1.10.1", + "bytes 1.11.1", "http 0.2.12", - "http 1.3.1", - "pin-project-lite 0.2.16", - "tokio 1.49.0", + "http 1.4.0", + "pin-project-lite 0.2.17", + "tokio 1.51.0", "tracing", "zeroize", ] [[package]] name = "aws-smithy-types" -version = "1.3.2" +version = "1.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d498595448e43de7f4296b7b7a18a8a02c61ec9349128c80a368f7c3b4ab11a8" +checksum = "9d73dbfbaa8e4bc57b9045137680b958d274823509a360abfd8e1d514d40c95c" dependencies = [ "base64-simd", - "bytes 1.10.1", + "bytes 1.11.1", "bytes-utils", "futures-core", "http 0.2.12", - "http 1.3.1", + "http 1.4.0", "http-body 0.4.6", "http-body 1.0.1", "http-body-util", "itoa", "num-integer", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", "pin-utils", "ryu", "serde", "time", - "tokio 1.49.0", + "tokio 1.51.0", "tokio-util", ] [[package]] name = "aws-smithy-xml" -version = "0.60.10" +version = "0.60.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3db87b96cb1b16c024980f133968d52882ca0daaee3a086c6decc500f6c99728" +checksum = "0ce02add1aa3677d022f8adf81dcbe3046a95f17a1b1e8979c145cd21d3d22b3" dependencies = [ "xmlparser", ] [[package]] name = "aws-types" -version = "1.3.8" +version = "1.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b069d19bf01e46298eaedd7c6f283fe565a59263e53eebec945f3e6398f42390" +checksum = "47c8323699dd9b3c8d5b3c13051ae9cdef58fd179957c882f8374dd8725962d9" dependencies = [ "aws-credential-types", "aws-smithy-async", @@ -1011,12 +1014,12 @@ dependencies = [ "async-trait", "axum-core", "axum-macros", - "bytes 1.10.1", + "bytes 1.11.1", "futures-util", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "http-body-util", - "hyper 1.7.0", + "hyper 1.9.0", "hyper-util", "itoa", "matchit", @@ -1024,14 +1027,14 @@ dependencies = [ "mime", "multer", "percent-encoding", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", "rustversion", "serde", "serde_json", "serde_path_to_error", "serde_urlencoded", "sync_wrapper 1.0.2", - "tokio 1.49.0", + "tokio 1.51.0", "tower", "tower-layer", "tower-service", @@ -1045,13 +1048,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" dependencies = [ "async-trait", - "bytes 1.10.1", + "bytes 1.11.1", "futures-util", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "http-body-util", "mime", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", "rustversion", "sync_wrapper 1.0.2", "tower-layer", @@ -1067,16 +1070,16 @@ checksum = "c794b30c904f0a1c2fb7740f7df7f7972dfaa14ef6f57cb6178dc63e5dca2f04" dependencies = [ "axum", "axum-core", - "bytes 1.10.1", - "fastrand 2.3.0", + "bytes 1.11.1", + "fastrand 2.4.0", "futures-util", "headers", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "http-body-util", "mime", "multer", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", "serde", "tower", "tower-layer", @@ -1090,8 +1093,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57d123550fa8d071b7255cb0cc04dc302baa6c8c4a79f55701552684d8399bce" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -1103,13 +1106,13 @@ dependencies = [ "anyhow", "axum", "axum_typed_multipart_macros", - "bytes 1.10.1", + "bytes 1.11.1", "chrono", "futures-core", "futures-util", "tempfile", "thiserror 1.0.69", - "tokio 1.49.0", + "tokio 1.51.0", "uuid", ] @@ -1122,16 +1125,16 @@ dependencies = [ "darling 0.20.11", "heck 0.5.0", "proc-macro-error", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", "ubyte", ] [[package]] name = "backtrace" -version = "0.3.75" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" dependencies = [ "addr2line", "cfg-if", @@ -1139,7 +1142,7 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-targets 0.52.6", + "windows-link", ] [[package]] @@ -1190,9 +1193,9 @@ dependencies = [ [[package]] name = "base64ct" -version = "1.8.0" +version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" +checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" [[package]] name = "beef" @@ -1215,26 +1218,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bindgen" -version = "0.72.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" -dependencies = [ - "bitflags 2.9.4", - "cexpr", - "clang-sys", - "itertools 0.13.0", - "log", - "prettyplease", - "proc-macro2", - "quote 1.0.40", - "regex", - "rustc-hash", - "shlex", - "syn 2.0.106", -] - [[package]] name = "binstring" version = "0.1.7" @@ -1261,9 +1244,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.4" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" +checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" [[package]] name = "bitstream-io" @@ -1288,13 +1271,13 @@ dependencies = [ [[package]] name = "blake2b_simd" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e903a20b159e944f91ec8499fe1e55651480c541ea0a584f5d967c49ad9d99" +checksum = "b79834656f71332577234b50bfc009996f7449e0c056884e6a02492ded0ca2f3" dependencies = [ "arrayref", "arrayvec", - "constant_time_eq", + "constant_time_eq 0.4.2", ] [[package]] @@ -1306,6 +1289,15 @@ dependencies = [ "generic-array 0.14.7", ] +[[package]] +name = "block2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" +dependencies = [ + "objc2", +] + [[package]] name = "blocking" version = "1.6.2" @@ -1315,7 +1307,7 @@ dependencies = [ "async-channel 2.5.0", "async-task", "futures-io", - "futures-lite 2.6.1", + "futures-lite", "piper", ] @@ -1338,10 +1330,10 @@ dependencies = [ "ahash 0.8.12", "base64 0.22.1", "bitvec", - "getrandom 0.2.16", - "getrandom 0.3.3", + "getrandom 0.2.17", + "getrandom 0.3.4", "hex", - "indexmap 2.13.0", + "indexmap 2.13.1", "js-sys", "once_cell", "rand 0.9.2", @@ -1360,15 +1352,15 @@ checksum = "f4ad8f11f288f48ca24471bbd51ac257aaeaaa07adae295591266b792902ae64" [[package]] name = "bumpalo" -version = "3.19.0" +version = "3.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" [[package]] name = "bytemuck" -version = "1.23.2" +version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3995eaeebcdf32f91f980d360f78732ddc061097ab4e39991ae7a6ace9194677" +checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" [[package]] name = "byteorder" @@ -1390,9 +1382,9 @@ checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" [[package]] name = "bytes" -version = "1.10.1" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "bytes-utils" @@ -1400,7 +1392,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dafe3a8757b027e2be6e4e5601ed563c55989fcf1546e933c66c8eb3a058d35" dependencies = [ - "bytes 1.10.1", + "bytes 1.11.1", "either", ] @@ -1418,7 +1410,7 @@ dependencies = [ "instant", "once_cell", "thiserror 1.0.69", - "tokio 1.49.0", + "tokio 1.51.0", ] [[package]] @@ -1430,7 +1422,7 @@ dependencies = [ "cached_proc_macro_types", "darling 0.14.4", "proc-macro2", - "quote 1.0.40", + "quote 1.0.45", "syn 1.0.109", ] @@ -1442,15 +1434,18 @@ checksum = "ade8366b8bd5ba243f0a58f036cc0ca8a2f069cff1a2351ef1cac6b083e16fc0" [[package]] name = "castaway" -version = "0.1.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2698f953def977c68f935bb0dfa959375ad4638570e969e2f1e9f433cbf1af6" +checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a" +dependencies = [ + "rustversion", +] [[package]] name = "cc" -version = "1.2.38" +version = "1.2.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80f41ae168f955c12fb8960b057d70d0ca153fb83182b57d86380443527be7e9" +checksum = "b7a4d3ec6524d28a329fc53654bbadc9bdd7b0431f5d65f1a56ffb28a1ee5283" dependencies = [ "find-msvc-tools", "jobserver", @@ -1459,13 +1454,10 @@ dependencies = [ ] [[package]] -name = "cexpr" -version = "0.6.0" +name = "cesu8" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" [[package]] name = "cfb" @@ -1480,22 +1472,27 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.3" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.42" +version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" +checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" dependencies = [ "iana-time-zone", "js-sys", "num-traits", - "serde", "wasm-bindgen", - "windows-link 0.2.0", + "windows-link", ] [[package]] @@ -1508,40 +1505,20 @@ dependencies = [ "inout", ] -[[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading", -] - -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "cmake" -version = "0.1.54" +version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" +checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" dependencies = [ "cc", ] [[package]] name = "coarsetime" -version = "0.1.36" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91849686042de1b41cd81490edc83afbcb0abe5a9b6f2c4114f23ce8cca1bcf4" +checksum = "e58eb270476aa4fc7843849f8a35063e8743b4dbcdf6dd0f8ea0886980c204c2" dependencies = [ "libc", "wasix", @@ -1560,11 +1537,11 @@ version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" dependencies = [ - "bytes 1.10.1", + "bytes 1.11.1", "futures-core", "memchr", - "pin-project-lite 0.2.16", - "tokio 1.49.0", + "pin-project-lite 0.2.17", + "tokio 1.51.0", "tokio-util", ] @@ -1586,7 +1563,7 @@ dependencies = [ "async-trait", "json5", "lazy_static", - "nom", + "nom 7.1.3", "pathdiff", "ron", "rust-ini", @@ -1623,7 +1600,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", "once_cell", "tiny-keccak", ] @@ -1634,11 +1611,20 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" +[[package]] +name = "constant_time_eq" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" + [[package]] name = "convert_case" -version = "0.4.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" +checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" +dependencies = [ + "unicode-segmentation", +] [[package]] name = "cookie" @@ -1730,15 +1716,14 @@ checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" [[package]] name = "crc-fast" -version = "1.3.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bf62af4cc77d8fe1c22dde4e721d87f2f54056139d8c412e1366b740305f56f" +checksum = "2fd92aca2c6001b1bf5ba0ff84ee74ec8501b52bbef0cac80bf25a6c1d87a83d" dependencies = [ "crc", "digest", - "libc", - "rand 0.9.2", - "regex", + "rustversion", + "spin 0.10.0", ] [[package]] @@ -1756,6 +1741,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + [[package]] name = "crossbeam-channel" version = "0.5.15" @@ -1831,9 +1822,9 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array 0.14.7", "rand_core 0.6.4", @@ -1859,8 +1850,8 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -1886,18 +1877,18 @@ checksum = "79fc3b6dd0b87ba36e565715bf9a2ced221311db47bd18011676f24a6066edbc" dependencies = [ "curl-sys", "libc", - "openssl-probe", + "openssl-probe 0.1.6", "openssl-sys", "schannel", - "socket2 0.6.0", + "socket2 0.6.3", "windows-sys 0.59.0", ] [[package]] name = "curl-sys" -version = "0.4.83+curl-8.15.0" +version = "0.4.87+curl-8.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5830daf304027db10c82632a464879d46a3f7c4ba17a31592657ad16c719b483" +checksum = "61a460380f0ef783703dcbe909107f39c162adeac050d73c850055118b5b6327" dependencies = [ "cc", "libc", @@ -1909,6 +1900,33 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest", + "fiat-crypto", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote 1.0.45", + "syn 2.0.117", +] + [[package]] name = "darling" version = "0.13.4" @@ -1941,12 +1959,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.21.3" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" dependencies = [ - "darling_core 0.21.3", - "darling_macro 0.21.3", + "darling_core 0.23.0", + "darling_macro 0.23.0", ] [[package]] @@ -1958,7 +1976,7 @@ dependencies = [ "fnv", "ident_case", "proc-macro2", - "quote 1.0.40", + "quote 1.0.45", "strsim 0.10.0", "syn 1.0.109", ] @@ -1972,7 +1990,7 @@ dependencies = [ "fnv", "ident_case", "proc-macro2", - "quote 1.0.40", + "quote 1.0.45", "strsim 0.10.0", "syn 1.0.109", ] @@ -1986,23 +2004,22 @@ dependencies = [ "fnv", "ident_case", "proc-macro2", - "quote 1.0.40", + "quote 1.0.45", "strsim 0.11.1", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] name = "darling_core" -version = "0.21.3" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" dependencies = [ - "fnv", "ident_case", "proc-macro2", - "quote 1.0.40", + "quote 1.0.45", "strsim 0.11.1", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -2012,7 +2029,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" dependencies = [ "darling_core 0.13.4", - "quote 1.0.40", + "quote 1.0.45", "syn 1.0.109", ] @@ -2023,7 +2040,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" dependencies = [ "darling_core 0.14.4", - "quote 1.0.40", + "quote 1.0.45", "syn 1.0.109", ] @@ -2034,19 +2051,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core 0.20.11", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] name = "darling_macro" -version = "0.21.3" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" dependencies = [ - "darling_core 0.21.3", - "quote 1.0.40", - "syn 2.0.106", + "darling_core 0.23.0", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -2064,9 +2081,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" +checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" [[package]] name = "data-url" @@ -2081,7 +2098,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72ff1266be84e4e04a81e2d1cbb998cb271b374fb73ce780245ef96c037c50cd" dependencies = [ "crossbeam-queue", - "tokio 1.49.0", + "tokio 1.51.0", ] [[package]] @@ -2139,19 +2156,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8aed3b3c608dc56cf36c45fe979d04eda51242e6703d8d0bb03426ef7c41db6a" dependencies = [ "proc-macro2", - "quote 1.0.40", + "quote 1.0.45", "syn 1.0.109", "synstructure 0.12.6", ] [[package]] name = "deranged" -version = "0.5.3" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d630bccd429a5bb5a64b5e94f693bfc48c9f8566418fda4c494cc94f911f87cc" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" dependencies = [ "powerfmt", - "serde", + "serde_core", ] [[package]] @@ -2161,19 +2178,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d65d7ce8132b7c0e54497a4d9a55a1c2a0912a0d786cf894472ba818fba45762" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] name = "derive-where" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef941ded77d15ca19b40374869ac6000af1c9f2a4c0f3d4c70926287e6364a8f" +checksum = "d08b3a0bcc0d079199cd476b2cae8435016ec11d1c0986c6901c5ac223041534" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -2181,12 +2198,33 @@ name = "derive_more" version = "0.99.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" +dependencies = [ + "proc-macro2", + "quote 1.0.45", + "syn 2.0.117", +] + +[[package]] +name = "derive_more" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" dependencies = [ "convert_case", "proc-macro2", - "quote 1.0.40", + "quote 1.0.45", "rustc_version", - "syn 2.0.106", + "syn 2.0.117", + "unicode-xid 0.2.6", ] [[package]] @@ -2206,7 +2244,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71b28680d8be17a570a2334922518be6adc3f58ecc880cbb404eaeb8624fd867" dependencies = [ "devise_core", - "quote 1.0.40", + "quote 1.0.45", ] [[package]] @@ -2215,11 +2253,11 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b035a542cf7abf01f2e3c4d5a7acbaebfefe120ae4efc7bde3df98186e4b8af7" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.11.0", "proc-macro2", "proc-macro2-diagnostics", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -2234,6 +2272,16 @@ dependencies = [ "subtle", ] +[[package]] +name = "dispatch2" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" +dependencies = [ + "bitflags 2.11.0", + "objc2", +] + [[package]] name = "displaydoc" version = "0.2.5" @@ -2241,8 +2289,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -2253,9 +2301,9 @@ checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" [[package]] name = "dtoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6add3b8cff394282be81f3fc1a0605db594ed69890078ca6e2cab1c408bcf04" +checksum = "4c3cf4824e2d5f025c7b531afcb2325364084a16806f6d47fbc1f5fbd9960590" [[package]] name = "dtoa-short" @@ -2322,14 +2370,38 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8 0.10.2", + "signature 2.2.0", +] + [[package]] name = "ed25519-compact" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9b3460f44bea8cd47f45a0c70892f1eff856d97cd55358b2f73f663789f6190" +checksum = "33ce99a9e19c84beb4cc35ece85374335ccc398240712114c85038319ed709bd" dependencies = [ "ct-codecs", - "getrandom 0.2.16", + "getrandom 0.3.4", +] + +[[package]] +name = "ed25519-dalek" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +dependencies = [ + "curve25519-dalek", + "ed25519", + "serde", + "sha2", + "subtle", + "zeroize", ] [[package]] @@ -2418,8 +2490,8 @@ checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" dependencies = [ "heck 0.5.0", "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -2438,8 +2510,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "685adfa4d6f3d765a26bc5dbc936577de9abf756c1feeb3089b01dd395034842" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -2471,8 +2543,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -2497,14 +2569,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.0", + "windows-sys 0.61.2", ] [[package]] name = "euclid" -version = "0.22.11" +version = "0.22.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad9cdb4b747e485a12abb0e6566612956c7a1bafa3bdb8d682c5b6d403589e48" +checksum = "f1a05365e3b1c6d1650318537c7460c6923f1abdd272ad6842baa2b509957a06" dependencies = [ "num-traits", ] @@ -2523,7 +2595,7 @@ checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" dependencies = [ "concurrent-queue", "parking", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", ] [[package]] @@ -2533,7 +2605,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" dependencies = [ "event-listener 5.4.1", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", ] [[package]] @@ -2562,9 +2634,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "a043dc74da1e37d6afe657061213aa6f425f855399a11d3463c6ecccc4dfda1f" [[package]] name = "fax" @@ -2582,8 +2654,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0aca10fb742cb43f9e7bb8467c91aa9bcb8e3ffbc6a6f7389bb93ffc920577d" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -2638,6 +2710,12 @@ dependencies = [ "serde_json", ] +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + [[package]] name = "figment" version = "0.10.19" @@ -2654,9 +2732,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.2" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ced73b1dacfc750a6db6c0a0c3a3853c8b41997e2e2c563dc90804ae6867959" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] name = "findshlibs" @@ -2678,9 +2756,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.1.2" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" dependencies = [ "crc32fast", "miniz_oxide", @@ -2768,7 +2846,7 @@ checksum = "4b8e3a1339ed45ad8fde94530c4bdcbd5f371a3c6bd3bf57682923792830aa37" dependencies = [ "arc-swap", "async-trait", - "bytes 1.10.1", + "bytes 1.11.1", "bytes-utils", "crossbeam-queue", "float-cmp", @@ -2779,7 +2857,7 @@ dependencies = [ "redis-protocol", "semver", "socket2 0.5.10", - "tokio 1.49.0", + "tokio 1.51.0", "tokio-stream", "tokio-util", "url", @@ -2792,12 +2870,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" - [[package]] name = "funty" version = "2.0.0" @@ -2816,9 +2888,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" dependencies = [ "futures-channel", "futures-core", @@ -2831,9 +2903,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" dependencies = [ "futures-core", "futures-sink", @@ -2841,15 +2913,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" [[package]] name = "futures-executor" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" dependencies = [ "futures-core", "futures-task", @@ -2858,24 +2930,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" - -[[package]] -name = "futures-lite" -version = "1.13.0" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" -dependencies = [ - "fastrand 1.9.0", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite 0.2.16", - "waker-fn", -] +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" [[package]] name = "futures-lite" @@ -2883,11 +2940,11 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" dependencies = [ - "fastrand 2.3.0", + "fastrand 2.4.0", "futures-core", "futures-io", "parking", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", ] [[package]] @@ -2898,31 +2955,31 @@ checksum = "45ec6fe3675af967e67c5536c0b9d44e34e6c52f86bedc4ea49c5317b8e94d06" dependencies = [ "futures-channel", "futures-task", - "tokio 1.49.0", + "tokio 1.51.0", ] [[package]] name = "futures-macro" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] name = "futures-sink" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" [[package]] name = "futures-task" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] name = "futures-timer" @@ -2932,9 +2989,9 @@ checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" [[package]] name = "futures-util" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ "futures-channel", "futures-core", @@ -2943,8 +3000,7 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project-lite 0.2.16", - "pin-utils", + "pin-project-lite 0.2.17", "slab", ] @@ -2967,21 +3023,7 @@ dependencies = [ "libc", "log", "rustversion", - "windows 0.48.0", -] - -[[package]] -name = "generator" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "605183a538e3e2a9c1038635cc5c2d194e2ee8fd0d1b66b8349fad7dbacce5a2" -dependencies = [ - "cc", - "cfg-if", - "libc", - "log", - "rustversion", - "windows 0.61.3", + "windows", ] [[package]] @@ -2997,10 +3039,11 @@ dependencies = [ [[package]] name = "generic-array" -version = "1.2.0" +version = "1.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c8444bc9d71b935156cc0ccab7f622180808af7867b1daae6547d773591703" +checksum = "eaf57c49a95fd1fe24b90b3033bee6dc7e8f1288d51494cb44e627c295e38542" dependencies = [ + "rustversion", "typenum", ] @@ -3015,41 +3058,54 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", "wasm-bindgen", ] [[package]] name = "getrandom" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "js-sys", "libc", - "r-efi", - "wasi 0.14.7+wasi-0.2.4", + "r-efi 5.3.0", + "wasip2", "wasm-bindgen", ] [[package]] -name = "getset" -version = "0.1.6" +name = "getrandom" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", + "wasip2", + "wasip3", +] + +[[package]] +name = "getset" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cf0fc11e47561d47397154977bc219f4cf809b2974facc3ccb3b89e2436f912" dependencies = [ "proc-macro-error2", "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -3084,9 +3140,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.31.1" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" [[package]] name = "git2" @@ -3147,46 +3203,47 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" dependencies = [ - "bytes 1.10.1", + "bytes 1.11.1", "fnv", "futures-core", "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.13.0", + "indexmap 2.13.1", "slab", - "tokio 1.49.0", + "tokio 1.51.0", "tokio-util", "tracing", ] [[package]] name = "h2" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" +checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" dependencies = [ "atomic-waker", - "bytes 1.10.1", + "bytes 1.11.1", "fnv", "futures-core", "futures-sink", - "http 1.3.1", - "indexmap 2.13.0", + "http 1.4.0", + "indexmap 2.13.1", "slab", - "tokio 1.49.0", + "tokio 1.51.0", "tokio-util", "tracing", ] [[package]] name = "half" -version = "2.6.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" dependencies = [ "cfg-if", "crunchy", + "zerocopy", ] [[package]] @@ -3223,10 +3280,6 @@ name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -dependencies = [ - "ahash 0.8.12", - "allocator-api2", -] [[package]] name = "hashbrown" @@ -3234,8 +3287,6 @@ version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ - "allocator-api2", - "equivalent", "foldhash 0.1.5", ] @@ -3257,9 +3308,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb" dependencies = [ "base64 0.22.1", - "bytes 1.10.1", + "bytes 1.11.1", "headers-core", - "http 1.3.1", + "http 1.4.0", "httpdate", "mime", "sha1", @@ -3271,7 +3322,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" dependencies = [ - "http 1.3.1", + "http 1.4.0", ] [[package]] @@ -3309,9 +3360,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hickory-proto" -version = "0.24.4" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92652067c9ce6f66ce53cc38d1169daa36e6e7eb7dd3b63b5103bd9d97117248" +checksum = "f8a6fe56c0038198998a6f217ca4e7ef3a5e51f46163bd6dd60b5c71ca6c6502" dependencies = [ "async-trait", "cfg-if", @@ -3323,32 +3374,33 @@ dependencies = [ "idna 1.1.0", "ipnet", "once_cell", - "rand 0.8.5", - "thiserror 1.0.69", + "rand 0.9.2", + "ring", + "thiserror 2.0.18", "tinyvec", - "tokio 1.49.0", + "tokio 1.51.0", "tracing", "url", ] [[package]] name = "hickory-resolver" -version = "0.24.4" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbb117a1ca520e111743ab2f6688eddee69db4e0ea242545a604dce8a66fd22e" +checksum = "dc62a9a99b0bfb44d2ab95a7208ac952d31060efc16241c87eaf36406fecf87a" dependencies = [ "cfg-if", "futures-util", "hickory-proto", "ipconfig", - "lru-cache", + "moka", "once_cell", "parking_lot", - "rand 0.8.5", + "rand 0.9.2", "resolv-conf", "smallvec", - "thiserror 1.0.69", - "tokio 1.49.0", + "thiserror 2.0.18", + "tokio 1.51.0", "tracing", ] @@ -3372,24 +3424,24 @@ dependencies = [ [[package]] name = "hmac-sha1-compact" -version = "1.1.5" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18492c9f6f9a560e0d346369b665ad2bdbc89fa9bceca75796584e79042694c3" +checksum = "b0b3ba31f6dc772cc8221ce81dbbbd64fa1e668255a6737d95eeace59b5a8823" [[package]] name = "hmac-sha256" -version = "1.1.12" +version = "1.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad6880c8d4a9ebf39c6e8b77007ce223f646a4d21ce29d99f70cb16420545425" +checksum = "ec9d92d097f4749b64e8cc33d924d9f40a2d4eb91402b458014b781f5733d60f" dependencies = [ "digest", ] [[package]] name = "hmac-sha512" -version = "1.1.7" +version = "1.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89e8d20b3799fa526152a5301a771eaaad80857f83e01b23216ceaafb2d9280" +checksum = "019ece39bbefc17f13f677a690328cb978dbf6790e141a3c24e66372cb38588b" dependencies = [ "digest", ] @@ -3415,8 +3467,8 @@ dependencies = [ "mac", "markup5ever", "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -3425,19 +3477,18 @@ version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ - "bytes 1.10.1", + "bytes 1.11.1", "fnv", "itoa", ] [[package]] name = "http" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" dependencies = [ - "bytes 1.10.1", - "fnv", + "bytes 1.11.1", "itoa", ] @@ -3447,9 +3498,9 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ - "bytes 1.10.1", + "bytes 1.11.1", "http 0.2.12", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", ] [[package]] @@ -3458,8 +3509,8 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ - "bytes 1.10.1", - "http 1.3.1", + "bytes 1.11.1", + "http 1.4.0", ] [[package]] @@ -3468,11 +3519,11 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ - "bytes 1.10.1", + "bytes 1.11.1", "futures-core", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", ] [[package]] @@ -3502,7 +3553,7 @@ version = "0.14.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" dependencies = [ - "bytes 1.10.1", + "bytes 1.11.1", "futures-channel", "futures-core", "futures-util", @@ -3512,9 +3563,9 @@ dependencies = [ "httparse", "httpdate", "itoa", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", "socket2 0.5.10", - "tokio 1.49.0", + "tokio 1.51.0", "tower-service", "tracing", "want", @@ -3522,24 +3573,23 @@ dependencies = [ [[package]] name = "hyper" -version = "1.7.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" +checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" dependencies = [ "atomic-waker", - "bytes 1.10.1", + "bytes 1.11.1", "futures-channel", "futures-core", - "h2 0.4.12", - "http 1.3.1", + "h2 0.4.13", + "http 1.4.0", "http-body 1.0.1", "httparse", "httpdate", "itoa", - "pin-project-lite 0.2.16", - "pin-utils", + "pin-project-lite 0.2.17", "smallvec", - "tokio 1.49.0", + "tokio 1.51.0", "want", ] @@ -3555,7 +3605,7 @@ dependencies = [ "log", "rustls 0.21.12", "rustls-native-certs 0.6.3", - "tokio 1.49.0", + "tokio 1.51.0", "tokio-rustls 0.24.1", ] @@ -3566,12 +3616,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" dependencies = [ "futures-util", - "http 1.3.1", - "hyper 1.7.0", + "http 1.4.0", + "hyper 1.9.0", "hyper-util", "rustls 0.22.4", "rustls-pki-types", - "tokio 1.49.0", + "tokio 1.51.0", "tokio-rustls 0.25.0", "tower-service", "webpki-roots 0.26.11", @@ -3583,14 +3633,14 @@ version = "0.27.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" dependencies = [ - "http 1.3.1", - "hyper 1.7.0", + "http 1.4.0", + "hyper 1.9.0", "hyper-util", - "rustls 0.23.32", - "rustls-native-certs 0.8.1", + "rustls 0.23.37", + "rustls-native-certs 0.8.3", "rustls-pki-types", - "tokio 1.49.0", - "tokio-rustls 0.26.3", + "tokio 1.51.0", + "tokio-rustls 0.26.4", "tower-service", ] @@ -3600,50 +3650,33 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ - "bytes 1.10.1", + "bytes 1.11.1", "hyper 0.14.32", "native-tls", - "tokio 1.49.0", + "tokio 1.51.0", "tokio-native-tls", ] -[[package]] -name = "hyper-tls" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" -dependencies = [ - "bytes 1.10.1", - "http-body-util", - "hyper 1.7.0", - "hyper-util", - "native-tls", - "tokio 1.49.0", - "tokio-native-tls", - "tower-service", -] - [[package]] name = "hyper-util" -version = "0.1.17" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ "base64 0.22.1", - "bytes 1.10.1", + "bytes 1.11.1", "futures-channel", - "futures-core", "futures-util", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", - "hyper 1.7.0", + "hyper 1.9.0", "ipnet", "libc", "percent-encoding", - "pin-project-lite 0.2.16", - "socket2 0.6.0", - "system-configuration 0.6.1", - "tokio 1.49.0", + "pin-project-lite 0.2.17", + "socket2 0.6.3", + "system-configuration 0.7.0", + "tokio 1.51.0", "tower-service", "tracing", "windows-registry", @@ -3651,9 +3684,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.64" +version = "0.1.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -3661,7 +3694,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.62.0", + "windows-core", ] [[package]] @@ -3675,12 +3708,13 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.0.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" dependencies = [ "displaydoc", "potential_utf", + "utf8_iter", "yoke", "zerofrom", "zerovec", @@ -3688,9 +3722,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.0.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" dependencies = [ "displaydoc", "litemap", @@ -3701,11 +3735,10 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.0.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" dependencies = [ - "displaydoc", "icu_collections", "icu_normalizer_data", "icu_properties", @@ -3716,42 +3749,38 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.0.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" [[package]] name = "icu_properties" -version = "2.0.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" dependencies = [ - "displaydoc", "icu_collections", "icu_locale_core", "icu_properties_data", "icu_provider", - "potential_utf", "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "2.0.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" [[package]] name = "icu_provider" -version = "2.0.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" dependencies = [ "displaydoc", "icu_locale_core", - "stable_deref_trait", - "tinystr", "writeable", "yoke", "zerofrom", @@ -3759,6 +3788,12 @@ dependencies = [ "zerovec", ] +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + [[package]] name = "ident_case" version = "1.0.1" @@ -3825,9 +3860,9 @@ checksum = "cd62e6b5e86ea8eeeb8db1de02880a6abc01a397b2ebb64b5d74ac255318f5cb" [[package]] name = "image" -version = "0.25.9" +version = "0.25.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6506c6c10786659413faa717ceebcb8f70731c0a60cbae39795fdf114519c1a" +checksum = "85ab80394333c02fe689eaf900ab500fbd0c2213da414687ebf995a65d5a6104" dependencies = [ "bytemuck", "byteorder-lite", @@ -3837,14 +3872,14 @@ dependencies = [ "image-webp 0.2.4", "moxcms", "num-traits", - "png 0.18.0", + "png 0.18.1", "qoi", "ravif", "rayon", "rgb", "tiff", "zune-core 0.5.1", - "zune-jpeg 0.5.11", + "zune-jpeg 0.5.15", ] [[package]] @@ -3875,9 +3910,9 @@ checksum = "edcd27d72f2f071c64249075f42e205ff93c9a4c5f6c6da53e79ed9f9832c285" [[package]] name = "imgref" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0263a3d970d5c054ed9312c0057b4f3bde9c0b33836d3637361d4a9e6e7a408" +checksum = "e7c5cedc30da3a610cac6b4ba17597bdf7152cf974e8aab3afb3d54455e371c8" [[package]] name = "impl_ops" @@ -3891,16 +3926,16 @@ version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ - "autocfg 1.5.0", + "autocfg", "hashbrown 0.12.3", "serde", ] [[package]] name = "indexmap" -version = "2.13.0" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +checksum = "45a8a2b9cb3e0b0c1803dbb0758ffac5de2f425b23c28f518faabd9d805342ff" dependencies = [ "equivalent", "hashbrown 0.16.1", @@ -3948,33 +3983,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] name = "ipconfig" -version = "0.3.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" +checksum = "4d40460c0ce33d6ce4b0630ad68ff63d6661961c48b6dba35e5a4d81cfb48222" dependencies = [ - "socket2 0.5.10", + "socket2 0.6.3", "widestring", - "windows-sys 0.48.0", - "winreg", + "windows-registry", + "windows-result", + "windows-sys 0.61.2", ] [[package]] name = "ipnet" -version = "2.11.0" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" +checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" [[package]] name = "iri-string" -version = "0.7.8" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20" dependencies = [ "memchr", "serde", @@ -3982,34 +4018,33 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.16" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" +checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ "hermit-abi 0.5.2", "libc", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "isahc" -version = "1.7.2" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "334e04b4d781f436dc315cb1e7515bd96826426345d498149e4bde36b67f8ee9" +checksum = "49980b382c0e59635b99bb2d9ef4c039a90aefa1b821d5d7a8526d4504e14594" dependencies = [ - "async-channel 1.9.0", + "async-channel 2.5.0", "castaway", "crossbeam-utils", "curl", "curl-sys", "encoding_rs", - "event-listener 2.5.3", - "futures-lite 1.13.0", + "event-listener 5.4.1", + "futures-lite", "http 0.2.12", "log", "mime", - "once_cell", - "polling 2.8.0", + "polling", "serde", "serde_json", "slab", @@ -4026,8 +4061,8 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d4e5d712dd664b11e778d1cfc06c79ba2700d6bc1771e44fb7b6a4656b487d" dependencies = [ - "generic-array 1.2.0", - "schemars 0.8.22", + "generic-array 1.3.5", + "schemars", "serde", "time", ] @@ -4052,27 +4087,62 @@ dependencies = [ [[package]] name = "itertools" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" dependencies = [ "either", ] [[package]] -name = "itertools" -version = "0.14.0" +name = "itoa" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" dependencies = [ - "either", + "cesu8", + "cfg-if", + "combine", + "jni-sys 0.3.1", + "log", + "thiserror 1.0.69", + "walkdir", + "windows-sys 0.45.0", ] [[package]] -name = "itoa" -version = "1.0.15" +name = "jni-sys" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258" +dependencies = [ + "jni-sys 0.4.1", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote 1.0.45", + "syn 2.0.117", +] [[package]] name = "jobserver" @@ -4080,16 +4150,18 @@ version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", "libc", ] [[package]] name = "js-sys" -version = "0.3.80" +version = "0.3.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852f13bec5eba4ba9afbeb93fd7c13fe56147f055939ae21c43a29a0ecb2702e" +checksum = "2e04e2ef80ce82e13552136fabeef8a5ed1f985a96805761cbb9a2c34e7664d9" dependencies = [ + "cfg-if", + "futures-util", "once_cell", "wasm-bindgen", ] @@ -4107,15 +4179,23 @@ dependencies = [ [[package]] name = "jsonwebtoken" -version = "9.3.1" +version = "10.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde" +checksum = "0529410abe238729a60b108898784df8984c87f6054c9c4fcacc47e4803c1ce1" dependencies = [ "base64 0.22.1", + "ed25519-dalek", + "getrandom 0.2.17", + "hmac", "js-sys", - "ring", + "p256 0.13.2", + "p384", + "rand 0.8.5", + "rsa 0.9.10", "serde", "serde_json", + "sha2", + "signature 2.2.0", ] [[package]] @@ -4136,7 +4216,7 @@ dependencies = [ "p256 0.13.2", "p384", "rand 0.8.5", - "rsa", + "rsa 0.7.2", "serde", "serde_json", "spki 0.6.0", @@ -4144,15 +4224,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "jxl-bitstream" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5855ff16398ffbcf81fee52c41ca65326499c8764b21bb9952c367ace98995fb" -dependencies = [ - "tracing", -] - [[package]] name = "jxl-bitstream" version = "1.1.0" @@ -4162,36 +4233,13 @@ dependencies = [ "tracing", ] -[[package]] -name = "jxl-coding" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da5b5093904e940bc11ef50e872c7bdf7b6e88653f012b925f8479daf212b5c9" -dependencies = [ - "jxl-bitstream 0.4.1", - "tracing", -] - [[package]] name = "jxl-coding" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd972bcd125e776f1eb241ac50e39f956095a1c2770c64736c968f8946bd9a3c" dependencies = [ - "jxl-bitstream 1.1.0", - "tracing", -] - -[[package]] -name = "jxl-color" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cb1c31e10054079df585633fc14fb9e4c96565c58c05b983c502e2472b57fa0" -dependencies = [ - "jxl-bitstream 0.4.1", - "jxl-coding 0.4.1", - "jxl-grid 0.4.2", - "jxl-threadpool 0.1.2", + "jxl-bitstream", "tracing", ] @@ -4201,28 +4249,12 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f316b1358c1711755b3ee8e8cb5c4a1dad12e796233088a7a513440782de80b2" dependencies = [ - "jxl-bitstream 1.1.0", - "jxl-coding 1.0.1", - "jxl-grid 0.6.1", - "jxl-image 0.13.0", + "jxl-bitstream", + "jxl-coding", + "jxl-grid", + "jxl-image", "jxl-oxide-common", - "jxl-threadpool 1.0.0", - "tracing", -] - -[[package]] -name = "jxl-frame" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e35b289aa0f24044167d83a1c29ae2b99210c5082ab7e3e90dacbcae818aa0a2" -dependencies = [ - "jxl-bitstream 0.4.1", - "jxl-coding 0.4.1", - "jxl-grid 0.4.2", - "jxl-image 0.9.0", - "jxl-modular 0.7.1", - "jxl-threadpool 0.1.2", - "jxl-vardct 0.7.0", + "jxl-threadpool", "tracing", ] @@ -4232,23 +4264,14 @@ version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d967c6fd669c7c01060b5022d8835fa82fd46b06ffc98b549f17600a097c2b3" dependencies = [ - "jxl-bitstream 1.1.0", - "jxl-coding 1.0.1", - "jxl-grid 0.6.1", - "jxl-image 0.13.0", - "jxl-modular 0.11.2", + "jxl-bitstream", + "jxl-coding", + "jxl-grid", + "jxl-image", + "jxl-modular", "jxl-oxide-common", - "jxl-threadpool 1.0.0", - "jxl-vardct 0.11.1", - "tracing", -] - -[[package]] -name = "jxl-grid" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70b96735a85299a6bce8664643fcb759f29ea73ce344a90b6f7de9b92a8e9b2d" -dependencies = [ + "jxl-threadpool", + "jxl-vardct", "tracing", ] @@ -4261,26 +4284,14 @@ dependencies = [ "tracing", ] -[[package]] -name = "jxl-image" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b31b17ed3bd0e3b65e7b06628f5930e009dda6cd17638cf5159a20a3feedec6" -dependencies = [ - "jxl-bitstream 0.4.1", - "jxl-color 0.7.1", - "jxl-grid 0.4.2", - "tracing", -] - [[package]] name = "jxl-image" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5f752d62577c702a94dbbce4045caf08cb58639e8a4d56464b40ecf33ffe565" dependencies = [ - "jxl-bitstream 1.1.0", - "jxl-grid 0.6.1", + "jxl-bitstream", + "jxl-grid", "jxl-oxide-common", "tracing", ] @@ -4292,27 +4303,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e35d032bcec660647828527ff42c6f5776d2fd44b8357f9f6d9ac6dc07218e46" dependencies = [ "brotli-decompressor", - "jxl-bitstream 1.1.0", - "jxl-frame 0.13.3", - "jxl-grid 0.6.1", - "jxl-image 0.13.0", - "jxl-modular 0.11.2", + "jxl-bitstream", + "jxl-frame", + "jxl-grid", + "jxl-image", + "jxl-modular", "jxl-oxide-common", - "jxl-threadpool 1.0.0", - "jxl-vardct 0.11.1", - "tracing", -] - -[[package]] -name = "jxl-modular" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da3b9fb8f46e63a14ecedefbd0f873b04162aaf8a09676b630c31bc8dadc4638" -dependencies = [ - "jxl-bitstream 0.4.1", - "jxl-coding 0.4.1", - "jxl-grid 0.4.2", - "jxl-threadpool 0.1.2", + "jxl-threadpool", + "jxl-vardct", "tracing", ] @@ -4322,27 +4320,11 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da758b2f989aafd9eeb39489fe43d7be5a3a0d2ad61cf1bad705eb6990a6053c" dependencies = [ - "jxl-bitstream 1.1.0", - "jxl-coding 1.0.1", - "jxl-grid 0.6.1", + "jxl-bitstream", + "jxl-coding", + "jxl-grid", "jxl-oxide-common", - "jxl-threadpool 1.0.0", - "tracing", -] - -[[package]] -name = "jxl-oxide" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba1ee3895e6c62b131994807b1ee6d179013613a86c01c203369af8d1e8d2f0" -dependencies = [ - "jxl-bitstream 0.4.1", - "jxl-color 0.7.1", - "jxl-frame 0.9.0", - "jxl-grid 0.4.2", - "jxl-image 0.9.0", - "jxl-render 0.8.2", - "jxl-threadpool 0.1.2", + "jxl-threadpool", "tracing", ] @@ -4355,15 +4337,15 @@ dependencies = [ "brotli-decompressor", "bytemuck", "image", - "jxl-bitstream 1.1.0", - "jxl-color 0.11.0", - "jxl-frame 0.13.3", - "jxl-grid 0.6.1", - "jxl-image 0.13.0", + "jxl-bitstream", + "jxl-color", + "jxl-frame", + "jxl-grid", + "jxl-image", "jxl-jbr", "jxl-oxide-common", - "jxl-render 0.12.3", - "jxl-threadpool 1.0.0", + "jxl-render", + "jxl-threadpool", "tracing", ] @@ -4373,25 +4355,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b62394c5021b3a9e7e0dbb2d639d555d019090c9946c39f6d3b09d390db4157b" dependencies = [ - "jxl-bitstream 1.1.0", -] - -[[package]] -name = "jxl-render" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "203a79b3025b86f875cc97a6f39e1fcc6314f915b2f6b69f767fca45fd482a11" -dependencies = [ - "jxl-bitstream 0.4.1", - "jxl-coding 0.4.1", - "jxl-color 0.7.1", - "jxl-frame 0.9.0", - "jxl-grid 0.4.2", - "jxl-image 0.9.0", - "jxl-modular 0.7.1", - "jxl-threadpool 0.1.2", - "jxl-vardct 0.7.0", - "tracing", + "jxl-bitstream", ] [[package]] @@ -4401,27 +4365,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa0c3100918bd3c41bb0f8ce1f4f1664e48f3032ff8eeab0d6a2cfc3276f462d" dependencies = [ "bytemuck", - "jxl-bitstream 1.1.0", - "jxl-coding 1.0.1", - "jxl-color 0.11.0", - "jxl-frame 0.13.3", - "jxl-grid 0.6.1", - "jxl-image 0.13.0", - "jxl-modular 0.11.2", + "jxl-bitstream", + "jxl-coding", + "jxl-color", + "jxl-frame", + "jxl-grid", + "jxl-image", + "jxl-modular", "jxl-oxide-common", - "jxl-threadpool 1.0.0", - "jxl-vardct 0.11.1", - "tracing", -] - -[[package]] -name = "jxl-threadpool" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad9c78eaf899cce165e266300f9963d8d376d4ed95cf4d12dd7066f05542cd88" -dependencies = [ - "rayon", - "rayon-core", + "jxl-threadpool", + "jxl-vardct", "tracing", ] @@ -4436,32 +4389,18 @@ dependencies = [ "tracing", ] -[[package]] -name = "jxl-vardct" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16af82a1ad770887cad720bfd3cc6a6d023faf377036989a24cf2c6538b649e0" -dependencies = [ - "jxl-bitstream 0.4.1", - "jxl-coding 0.4.1", - "jxl-grid 0.4.2", - "jxl-modular 0.7.1", - "jxl-threadpool 0.1.2", - "tracing", -] - [[package]] name = "jxl-vardct" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce72a18c6d3a47172ab6c479be2bdb56f22066b5d7092663f03b4490820b4511" dependencies = [ - "jxl-bitstream 1.1.0", - "jxl-coding 1.0.1", - "jxl-grid 0.6.1", - "jxl-modular 0.11.2", + "jxl-bitstream", + "jxl-coding", + "jxl-grid", + "jxl-modular", "jxl-oxide-common", - "jxl-threadpool 1.0.0", + "jxl-threadpool", "tracing", ] @@ -4514,9 +4453,15 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" dependencies = [ - "spin", + "spin 0.9.8", ] +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + [[package]] name = "lebe" version = "0.5.3" @@ -4539,24 +4484,24 @@ dependencies = [ "idna 0.3.0", "mime", "native-tls", - "nom", + "nom 7.1.3", "once_cell", "quoted_printable", "socket2 0.4.10", - "tokio 1.49.0", + "tokio 1.51.0", ] [[package]] name = "libc" -version = "0.2.175" +version = "0.2.184" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" +checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" [[package]] name = "libfuzzer-sys" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5037190e1f70cbeef565bd267599242926f724d3b8a9f510fd7e0b540cfa4404" +checksum = "f12a681b7dd8ce12bff52488013ba614b869148d54dd79836ab85aafdd53f08d" dependencies = [ "arbitrary", "cc", @@ -4574,27 +4519,17 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "libloading" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" -dependencies = [ - "cfg-if", - "windows-targets 0.53.3", -] - [[package]] name = "libm" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libnghttp2-sys" -version = "0.1.11+1.64.0" +version = "0.1.13+1.68.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b6c24e48a7167cffa7119da39d577fa482e66c688a4aac016bee862e1a713c4" +checksum = "492e00167f1418c15648144f42bbfc63099806ecee9bf8d09a6353d6b4856b3c" dependencies = [ "cc", "libc", @@ -4612,9 +4547,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.22" +version = "1.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b70e7a7df205e92a1a4cd9aaae7898dac0aa555503cc0a649494d0d60e7651d" +checksum = "fc3a226e576f50782b3305c5ccf458698f92798987f551c6a02efe8276721e22" dependencies = [ "cc", "libc", @@ -4628,15 +4563,6 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" -[[package]] -name = "linkify" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1986921c3c13e81df623c66a298d4b130c061bcb98a01f5b2d3ac402b1649a7f" -dependencies = [ - "memchr", -] - [[package]] name = "linkify" version = "0.8.1" @@ -4648,66 +4574,56 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" [[package]] name = "livekit-api" -version = "0.4.6" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a17951fa8d398241f4a9503b57a7b38b3f40fb9dc94954f17b9fe99683e6b9b" +checksum = "e2247e3127fc52f9cc30f2763726f0508120d0424bd5159464d731cb58e2bea1" dependencies = [ "base64 0.21.7", - "http 0.2.12", + "http 1.4.0", "jsonwebtoken", "livekit-protocol", "log", + "os_info", "parking_lot", "pbjson-types", "prost", "rand 0.9.2", - "reqwest 0.11.27", + "reqwest 0.12.28", "scopeguard", "serde", "serde_json", "sha2", - "thiserror 1.0.69", + "thiserror 2.0.18", "url", ] [[package]] name = "livekit-protocol" -version = "0.4.0" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45c90494efa508ec40228f870affec648826d23e1a9621a4430f67d187901eb4" +checksum = "6d080ff1e4806c4b57427db696dc093e1a6817de9500a262167259cf7bab646e" dependencies = [ "futures-util", - "livekit-runtime 0.4.0", + "livekit-runtime", "parking_lot", "pbjson", "pbjson-types", "prost", - "prost-types", "serde", - "thiserror 1.0.69", - "tokio 1.49.0", -] - -[[package]] -name = "livekit-runtime" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ae53eb874eb86e96e8ccffc31b5a00926d46174cbcb1c24ce4e57b1fcc5c8f6" -dependencies = [ - "tokio 1.49.0", - "tokio-stream", + "thiserror 2.0.18", + "tokio 1.51.0", ] [[package]] @@ -4716,25 +4632,24 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "532e84c6cdc5fe774f2b5d9912597b5f3bea561927a48296d03e24549d21c3f6" dependencies = [ - "tokio 1.49.0", + "tokio 1.51.0", "tokio-stream", ] [[package]] name = "lock_api" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg 1.5.0", "scopeguard", ] [[package]] name = "log" -version = "0.4.28" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" dependencies = [ "value-bag", ] @@ -4758,10 +4673,10 @@ dependencies = [ "fnv", "lazy_static", "proc-macro2", - "quote 1.0.40", + "quote 1.0.45", "regex-syntax", "rustc_version", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -4774,67 +4689,27 @@ dependencies = [ ] [[package]] -name = "loom" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" -dependencies = [ - "cfg-if", - "generator 0.7.5", - "scoped-tls", - "serde", - "serde_json", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "loom" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" -dependencies = [ - "cfg-if", - "generator 0.8.7", - "scoped-tls", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "loop9" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" -dependencies = [ - "imgref", -] - -[[package]] -name = "lru" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999beba7b6e8345721bd280141ed958096a2e4abdf74f67ff4ce49b4b54e47a" -dependencies = [ - "hashbrown 0.12.3", -] - -[[package]] -name = "lru" -version = "0.11.1" +name = "loom" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a83fb7698b3643a0e34f9ae6f2e8f0178c0fd42f8b59d493aa271ff3a5bf21" +checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" dependencies = [ - "hashbrown 0.14.5", + "cfg-if", + "generator", + "scoped-tls", + "serde", + "serde_json", + "tracing", + "tracing-subscriber", ] [[package]] -name = "lru" -version = "0.12.5" +name = "loop9" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" dependencies = [ - "hashbrown 0.15.5", + "imgref", ] [[package]] @@ -4847,13 +4722,10 @@ dependencies = [ ] [[package]] -name = "lru-cache" +name = "lru-slab" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" -dependencies = [ - "linked-hash-map", -] +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" [[package]] name = "lru_time_cache" @@ -4875,8 +4747,8 @@ checksum = "cc33f9f0351468d26fbc53d9ce00a096c8522ecb42f19b50f34f2c422f76d21d" dependencies = [ "macro_magic_core", "macro_magic_macros", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -4889,8 +4761,8 @@ dependencies = [ "derive-syn-parse", "macro_magic_core_macros", "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -4900,8 +4772,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b02abfe41815b5bd98dbd4260173db2c116dda171dc0fe7838cb206333b83308" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -4911,8 +4783,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73ea28ee64b88876bf45277ed9a5817c1817df061a74f2b988971a12570e5869" dependencies = [ "macro_magic_core", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -4978,15 +4850,15 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.5" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "memmap2" -version = "0.9.8" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843a98750cd611cc2965a8213b53b43e715f13c37a9e096c6408e69990961db7" +checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" dependencies = [ "libc", ] @@ -5025,13 +4897,13 @@ dependencies = [ [[package]] name = "mio" -version = "1.0.4" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" dependencies = [ "libc", - "wasi 0.11.1+wasi-snapshot-preview1", - "windows-sys 0.59.0", + "wasi", + "windows-sys 0.61.2", ] [[package]] @@ -5049,7 +4921,7 @@ dependencies = [ "log", "metrics", "thiserror 1.0.69", - "tokio 1.49.0", + "tokio 1.51.0", "tracing", "tracing-subscriber", ] @@ -5066,31 +4938,29 @@ dependencies = [ [[package]] name = "moka" -version = "0.12.10" +version = "0.12.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9321642ca94a4282428e6ea4af8cc2ca4eac48ac7a6a4ea8f33f76d0ce70926" +checksum = "957228ad12042ee839f93c8f257b62b4c0ab5eaae1d4fa60de53b27c9d7c5046" dependencies = [ - "async-lock 3.4.1", + "async-lock 3.4.2", "crossbeam-channel", "crossbeam-epoch", "crossbeam-utils", + "equivalent", "event-listener 5.4.1", "futures-util", - "loom 0.7.2", "parking_lot", "portable-atomic", - "rustc_version", "smallvec", "tagptr", - "thiserror 1.0.69", "uuid", ] [[package]] name = "mongocrypt" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22426d6318d19c5c0773f783f85375265d6a8f0fa76a733da8dc4355516ec63d" +checksum = "8da0cd419a51a5fb44819e290fbdb0665a54f21dead8923446a799c7f4d26ad9" dependencies = [ "bson", "mongocrypt-sys", @@ -5100,25 +4970,22 @@ dependencies = [ [[package]] name = "mongocrypt-sys" -version = "0.1.4+1.12.0" +version = "0.1.5+1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dda42df21d035f88030aad8e877492fac814680e1d7336a57b2a091b989ae388" +checksum = "224484c5d09285a7b8cb0a0c117e847ebd14cb6e4470ecf68cdb89c503b0edb9" [[package]] name = "mongodb" -version = "3.3.0" +version = "3.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622f272c59e54a3c85f5902c6b8e7b1653a6b6681f45e4c42d6581301119a4b8" +checksum = "2c5941683db2ab2697f71e58dc0319024e808d3b28e7cf20f4bfb445fe54a30b" dependencies = [ - "async-trait", - "base64 0.13.1", - "bitflags 1.3.2", + "base64 0.22.1", + "bitflags 2.11.0", "bson", - "chrono", "derive-where", - "derive_more", + "derive_more 2.1.1", "futures-core", - "futures-executor", "futures-io", "futures-util", "hex", @@ -5129,48 +4996,47 @@ dependencies = [ "md-5", "mongocrypt", "mongodb-internal-macros", - "once_cell", "pbkdf2", "percent-encoding", - "rand 0.8.5", + "rand 0.9.2", "rustc_version_runtime", - "rustls 0.23.32", + "rustls 0.23.37", "rustversion", "serde", "serde_bytes", "serde_with", "sha1", "sha2", - "socket2 0.5.10", + "socket2 0.6.3", "stringprep", "strsim 0.11.1", "take_mut", - "thiserror 1.0.69", - "tokio 1.49.0", - "tokio-rustls 0.26.3", + "thiserror 2.0.18", + "tokio 1.51.0", + "tokio-rustls 0.26.4", "tokio-util", "typed-builder", "uuid", - "webpki-roots 0.26.11", + "webpki-roots 1.0.6", ] [[package]] name = "mongodb-internal-macros" -version = "3.3.0" +version = "3.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63981427a0f26b89632fd2574280e069d09fb2912a3138da15de0174d11dd077" +checksum = "47021a12bbf0dffde9c890fa2d36ff6ae342c532016226b04a42301b2b912660" dependencies = [ "macro_magic", "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] name = "moxcms" -version = "0.7.5" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd32fa8935aeadb8a8a6b6b351e40225570a37c43de67690383d87ef170cd08" +checksum = "bb85c154ba489f01b25c0d36ae69a87e4a1c73a72631fc6c0eb6dde34a73e44b" dependencies = [ "num-traits", "pxfm", @@ -5182,15 +5048,15 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b" dependencies = [ - "bytes 1.10.1", + "bytes 1.11.1", "encoding_rs", "futures-util", - "http 1.3.1", + "http 1.4.0", "httparse", "memchr", "mime", - "spin", - "tokio 1.49.0", + "spin 0.9.8", + "tokio 1.51.0", "tokio-util", "version_check", ] @@ -5218,17 +5084,17 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.2.14" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +checksum = "465500e14ea162429d264d44189adc38b199b62b1c21eea9f69e4b73cb03bbf2" dependencies = [ "libc", "log", "openssl", - "openssl-probe", + "openssl-probe 0.2.1", "openssl-sys", "schannel", - "security-framework 2.11.1", + "security-framework 3.7.0", "security-framework-sys", "tempfile", ] @@ -5239,6 +5105,18 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" +[[package]] +name = "nix" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" +dependencies = [ + "bitflags 2.11.0", + "cfg-if", + "cfg_aliases", + "libc", +] + [[package]] name = "nom" version = "7.1.3" @@ -5249,6 +5127,15 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "nom" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405" +dependencies = [ + "memchr", +] + [[package]] name = "noop_proc_macro" version = "0.3.0" @@ -5257,20 +5144,20 @@ checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" [[package]] name = "ntapi" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +checksum = "c3b335231dfd352ffb0f8017f3b6027a4917f7df785ea2143d8af2adc66980ae" dependencies = [ "winapi", ] [[package]] name = "nu-ansi-term" -version = "0.50.1" +version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -5285,11 +5172,10 @@ dependencies = [ [[package]] name = "num-bigint-dig" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7" dependencies = [ - "byteorder", "lazy_static", "libm", "num-integer", @@ -5302,9 +5188,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.1.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" [[package]] name = "num-derive" @@ -5313,8 +5199,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -5332,7 +5218,7 @@ version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" dependencies = [ - "autocfg 1.5.0", + "autocfg", "num-integer", "num-traits", ] @@ -5354,7 +5240,7 @@ version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ - "autocfg 1.5.0", + "autocfg", "libm", ] @@ -5370,69 +5256,211 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.5.11" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" dependencies = [ - "num_enum_derive 0.5.11", + "num_enum_derive", ] [[package]] -name = "num_enum" +name = "num_enum_derive" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" +checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" dependencies = [ - "num_enum_derive 0.6.1", + "proc-macro-crate", + "proc-macro2", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] -name = "num_enum_derive" -version = "0.5.11" +name = "num_threads" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote 1.0.40", - "syn 1.0.109", + "libc", ] [[package]] -name = "num_enum_derive" -version = "0.6.1" +name = "objc2" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" +checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f" dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "objc2-encode", ] [[package]] -name = "num_threads" -version = "0.1.7" +name = "objc2-cloud-kit" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" +dependencies = [ + "bitflags 2.11.0", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-data" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" +dependencies = [ + "bitflags 2.11.0", + "dispatch2", + "objc2", +] + +[[package]] +name = "objc2-core-graphics" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" +dependencies = [ + "bitflags 2.11.0", + "dispatch2", + "objc2", + "objc2-core-foundation", + "objc2-io-surface", +] + +[[package]] +name = "objc2-core-image" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d563b38d2b97209f8e861173de434bd0214cf020e3423a52624cd1d989f006" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-location" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca347214e24bc973fc025fd0d36ebb179ff30536ed1f80252706db19ee452009" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-text" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" +dependencies = [ + "bitflags 2.11.0", + "objc2", + "objc2-core-foundation", + "objc2-core-graphics", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] +name = "objc2-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ + "bitflags 2.11.0", + "block2", "libc", + "objc2", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-io-surface" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" +dependencies = [ + "bitflags 2.11.0", + "objc2", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" +dependencies = [ + "bitflags 2.11.0", + "objc2", + "objc2-core-foundation", + "objc2-foundation", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" +dependencies = [ + "bitflags 2.11.0", + "block2", + "objc2", + "objc2-cloud-kit", + "objc2-core-data", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-core-image", + "objc2-core-location", + "objc2-core-text", + "objc2-foundation", + "objc2-quartz-core", + "objc2-user-notifications", +] + +[[package]] +name = "objc2-user-notifications" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9df9128cbbfef73cda168416ccf7f837b62737d748333bfe9ab71c245d76613e" +dependencies = [ + "objc2", + "objc2-foundation", ] [[package]] name = "object" -version = "0.36.7" +version = "0.37.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.21.3" +version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" +dependencies = [ + "critical-section", + "portable-atomic", +] [[package]] name = "opaque-debug" @@ -5442,11 +5470,11 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.73" +version = "0.10.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" +checksum = "951c002c75e16ea2c65b8c7e4d3d51d5530d8dfa7d060b4776828c88cfb18ecf" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.11.0", "cfg-if", "foreign-types", "libc", @@ -5462,8 +5490,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -5472,11 +5500,17 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" +[[package]] +name = "openssl-probe" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + [[package]] name = "openssl-sys" -version = "0.9.109" +version = "0.9.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" +checksum = "57d55af3b3e226502be1526dfdba67ab0e9c96fc293004e79576b2b9edb0dbdb" dependencies = [ "cc", "libc", @@ -5496,14 +5530,18 @@ dependencies = [ [[package]] name = "os_info" -version = "3.12.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0e1ac5fde8d43c34139135df8ea9ee9465394b2d8d20f032d38998f64afffc3" +checksum = "e4022a17595a00d6a369236fdae483f0de7f0a339960a53118b818238e132224" dependencies = [ + "android_system_properties", "log", - "plist", + "nix", + "objc2", + "objc2-foundation", + "objc2-ui-kit", "serde", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -5555,9 +5593,9 @@ checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -5565,15 +5603,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.11" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.6", + "windows-link", ] [[package]] @@ -5622,7 +5660,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18f596653ba4ac51bdecbb4ef6773bc7f56042dc13927910de1684ad3d32aa12" dependencies = [ - "bytes 1.10.1", + "bytes 1.11.1", "chrono", "pbjson", "pbjson-build", @@ -5633,9 +5671,9 @@ dependencies = [ [[package]] name = "pbkdf2" -version = "0.11.0" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ "digest", ] @@ -5659,8 +5697,8 @@ checksum = "4bab5b985dc082b345f812b7df84e1bef27e7207b39e448439ba8bd69c93f147" dependencies = [ "proc-macro2", "proc-macro2-diagnostics", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -5676,12 +5714,12 @@ dependencies = [ [[package]] name = "pem" -version = "3.0.5" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3" +checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" dependencies = [ "base64 0.22.1", - "serde", + "serde_core", ] [[package]] @@ -5710,20 +5748,19 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pest" -version = "2.8.2" +version = "2.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e0a3a33733faeaf8651dfee72dd0f388f0c8e5ad496a3478fa5a922f49cfa8" +checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662" dependencies = [ "memchr", - "thiserror 2.0.18", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.8.2" +version = "2.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc58706f770acb1dbd0973e6530a3cff4746fb721207feb3a8a6064cd0b6c663" +checksum = "11f486f1ea21e6c10ed15d5a7c77165d0ee443402f0780849d1768e7d9d6fe77" dependencies = [ "pest", "pest_generator", @@ -5731,22 +5768,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.8.2" +version = "2.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d4f36811dfe07f7b8573462465d5cb8965fffc2e71ae377a33aecf14c2c9a2f" +checksum = "8040c4647b13b210a963c1ed407c1ff4fdfa01c31d6d2a098218702e6664f94f" dependencies = [ "pest", "pest_meta", "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] name = "pest_meta" -version = "2.8.2" +version = "2.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42919b05089acbd0a5dcd5405fb304d17d1053847b81163d09c4ad18ce8e8420" +checksum = "89815c69d36021a140146f26659a81d6c2afa33d216d736dd4be5381a7362220" dependencies = [ "pest", "sha2", @@ -5759,7 +5796,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.13.0", + "indexmap 2.13.1", ] [[package]] @@ -5830,8 +5867,8 @@ dependencies = [ "phf_generator 0.11.3", "phf_shared 0.11.3", "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -5849,7 +5886,7 @@ version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" dependencies = [ - "siphasher 1.0.1", + "siphasher 1.0.2", ] [[package]] @@ -5860,22 +5897,22 @@ checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" [[package]] name = "pin-project" -version = "1.1.10" +version = "1.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.10" +version = "1.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -5886,9 +5923,9 @@ checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" [[package]] name = "pin-project-lite" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pin-utils" @@ -5898,12 +5935,12 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "piper" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" +checksum = "c835479a4443ded371d6c535cbfd8d31ad92c5d23ae9770a61bc155e4992a3c1" dependencies = [ "atomic-waker", - "fastrand 2.3.0", + "fastrand 2.4.0", "futures-io", ] @@ -5919,6 +5956,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der 0.7.10", + "pkcs8 0.10.2", + "spki 0.7.3", +] + [[package]] name = "pkcs8" version = "0.9.0" @@ -5945,19 +5993,6 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" -[[package]] -name = "plist" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "740ebea15c5d1428f910cd1a5f52cebf8d25006245ed8ade92702f4943d91e07" -dependencies = [ - "base64 0.22.1", - "indexmap 2.13.0", - "quick-xml", - "serde", - "time", -] - [[package]] name = "png" version = "0.17.16" @@ -5973,33 +6008,17 @@ dependencies = [ [[package]] name = "png" -version = "0.18.0" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97baced388464909d42d89643fe4361939af9b7ce7a31ee32a168f832a70f2a0" +checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.11.0", "crc32fast", "fdeflate", "flate2", "miniz_oxide", ] -[[package]] -name = "polling" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" -dependencies = [ - "autocfg 1.5.0", - "bitflags 1.3.2", - "cfg-if", - "concurrent-queue", - "libc", - "log", - "pin-project-lite 0.2.16", - "windows-sys 0.48.0", -] - [[package]] name = "polling" version = "3.11.0" @@ -6009,9 +6028,9 @@ dependencies = [ "cfg-if", "concurrent-queue", "hermit-abi 0.5.2", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", "rustix", - "windows-sys 0.61.0", + "windows-sys 0.61.2", ] [[package]] @@ -6028,15 +6047,15 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.11.1" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "potential_utf" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" dependencies = [ "zerovec", ] @@ -6079,7 +6098,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -6109,7 +6128,7 @@ checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", "proc-macro2", - "quote 1.0.40", + "quote 1.0.45", "syn 1.0.109", "version_check", ] @@ -6121,7 +6140,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ "proc-macro2", - "quote 1.0.40", + "quote 1.0.45", "version_check", ] @@ -6132,7 +6151,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" dependencies = [ "proc-macro2", - "quote 1.0.40", + "quote 1.0.45", ] [[package]] @@ -6143,15 +6162,15 @@ checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" dependencies = [ "proc-macro-error-attr2", "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] name = "proc-macro2" -version = "1.0.101" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] @@ -6163,8 +6182,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", "version_check", "yansi", ] @@ -6184,8 +6203,8 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52717f9a02b6965224f95ca2a81e2e0c5c43baacd28ca057577988930b6c3d5b" dependencies = [ - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -6208,7 +6227,7 @@ version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" dependencies = [ - "bytes 1.10.1", + "bytes 1.11.1", "prost-derive", ] @@ -6218,7 +6237,7 @@ version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" dependencies = [ - "bytes 1.10.1", + "bytes 1.11.1", "heck 0.5.0", "itertools 0.12.1", "log", @@ -6229,7 +6248,7 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 2.0.106", + "syn 2.0.117", "tempfile", ] @@ -6242,8 +6261,8 @@ dependencies = [ "anyhow", "itertools 0.12.1", "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -6257,12 +6276,9 @@ dependencies = [ [[package]] name = "pxfm" -version = "0.1.24" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83f9b339b02259ada5c0f4a389b7fb472f933aa17ce176fd2ad98f28bb401fde" -dependencies = [ - "num-traits", -] +checksum = "b5a041e753da8b807c9255f28de81879c78c876392ff2469cde94799b2896b9d" [[package]] name = "qoi" @@ -6292,12 +6308,59 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" [[package]] -name = "quick-xml" -version = "0.38.3" +name = "quinn" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +dependencies = [ + "bytes 1.11.1", + "cfg_aliases", + "pin-project-lite 0.2.17", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls 0.23.37", + "socket2 0.6.3", + "thiserror 2.0.18", + "tokio 1.51.0", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" +dependencies = [ + "aws-lc-rs", + "bytes 1.11.1", + "getrandom 0.3.4", + "lru-slab", + "rand 0.9.2", + "ring", + "rustc-hash", + "rustls 0.23.37", + "rustls-pki-types", + "slab", + "thiserror 2.0.18", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42a232e7487fc2ef313d96dde7948e7a3c05101870d8985e4fd8d26aedd27b89" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" dependencies = [ - "memchr", + "cfg_aliases", + "libc", + "once_cell", + "socket2 0.6.3", + "tracing", + "windows-sys 0.60.2", ] [[package]] @@ -6308,9 +6371,9 @@ checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" [[package]] name = "quote" -version = "1.0.40" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" dependencies = [ "proc-macro2", ] @@ -6328,29 +6391,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] -name = "radium" -version = "0.7.0" +name = "r-efi" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" [[package]] -name = "rand" -version = "0.6.5" +name = "radium" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" -dependencies = [ - "autocfg 0.1.8", - "libc", - "rand_chacha 0.1.1", - "rand_core 0.4.2", - "rand_hc", - "rand_isaac", - "rand_jitter", - "rand_os", - "rand_pcg", - "rand_xorshift", - "winapi", -] +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" [[package]] name = "rand" @@ -6370,17 +6420,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ "rand_chacha 0.9.0", - "rand_core 0.9.3", -] - -[[package]] -name = "rand_chacha" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" -dependencies = [ - "autocfg 0.1.8", - "rand_core 0.3.1", + "rand_core 0.9.5", ] [[package]] @@ -6400,103 +6440,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core 0.9.3", -] - -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -dependencies = [ - "rand_core 0.4.2", + "rand_core 0.9.5", ] -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" - [[package]] name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", ] [[package]] name = "rand_core" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" -dependencies = [ - "getrandom 0.3.3", -] - -[[package]] -name = "rand_hc" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_isaac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_jitter" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" -dependencies = [ - "libc", - "rand_core 0.4.2", - "winapi", -] - -[[package]] -name = "rand_os" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -dependencies = [ - "cloudabi", - "fuchsia-cprng", - "libc", - "rand_core 0.4.2", - "rdrand", - "wasm-bindgen", - "winapi", -] - -[[package]] -name = "rand_pcg" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" -dependencies = [ - "autocfg 0.1.8", - "rand_core 0.4.2", -] - -[[package]] -name = "rand_xorshift" -version = "0.1.1" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" dependencies = [ - "rand_core 0.3.1", + "getrandom 0.3.4", ] [[package]] @@ -6536,9 +6498,9 @@ dependencies = [ [[package]] name = "ravif" -version = "0.12.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef69c1990ceef18a116855938e74793a5f7496ee907562bd0857b6ac734ab285" +checksum = "e52310197d971b0f5be7fe6b57530dcd27beb35c1b013f29d66c1ad73fbbcc45" dependencies = [ "avif-serialize", "imgref", @@ -6569,15 +6531,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -dependencies = [ - "rand_core 0.3.1", -] - [[package]] name = "redis" version = "0.23.3" @@ -6585,16 +6538,16 @@ source = "git+https://github.com/revoltchat/redis-rs?rev=523b2937367e17bd0073722 dependencies = [ "async-std", "async-trait", - "bytes 1.10.1", + "bytes 1.11.1", "combine", "futures-util", "itoa", "percent-encoding", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", "ryu", "sha1_smol", "socket2 0.4.10", - "tokio 1.49.0", + "tokio 1.51.0", "tokio-util", "url", ] @@ -6621,41 +6574,41 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c31deddf734dc0a39d3112e73490e88b61a05e83e074d211f348404cee4d2c6" dependencies = [ - "bytes 1.10.1", + "bytes 1.11.1", "bytes-utils", "cookie-factory", "crc16", "log", - "nom", + "nom 7.1.3", ] [[package]] name = "redox_syscall" -version = "0.5.17" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.11.0", ] [[package]] name = "ref-cast" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -6683,15 +6636,15 @@ dependencies = [ [[package]] name = "regex-lite" -version = "0.1.7" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "943f41321c63ef1c92fd763bfe054d2668f7f225a5c29f0105903dc2fc04ba30" +checksum = "cab834c73d247e67f4fae452806d17d3c7501756d98c8808d7c9c7aa7d18f973" [[package]] name = "regex-syntax" -version = "0.8.6" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" [[package]] name = "reqwest" @@ -6700,7 +6653,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ "base64 0.21.7", - "bytes 1.10.1", + "bytes 1.11.1", "encoding_rs", "futures-core", "futures-util", @@ -6708,7 +6661,7 @@ dependencies = [ "http 0.2.12", "http-body 0.4.6", "hyper 0.14.32", - "hyper-tls 0.5.0", + "hyper-tls", "ipnet", "js-sys", "log", @@ -6716,14 +6669,14 @@ dependencies = [ "native-tls", "once_cell", "percent-encoding", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", "rustls-pemfile 1.0.4", "serde", "serde_json", "serde_urlencoded", "sync_wrapper 0.1.2", "system-configuration 0.5.1", - "tokio 1.49.0", + "tokio 1.51.0", "tokio-native-tls", "tower-service", "url", @@ -6735,37 +6688,70 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.23" +version = "0.12.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +dependencies = [ + "base64 0.22.1", + "bytes 1.11.1", + "futures-core", + "http 1.4.0", + "http-body 1.0.1", + "http-body-util", + "hyper 1.9.0", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite 0.2.17", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 1.0.2", + "tokio 1.51.0", + "tower", + "tower-http 0.6.8", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "reqwest" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" +checksum = "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801" dependencies = [ "base64 0.22.1", - "bytes 1.10.1", + "bytes 1.11.1", "encoding_rs", "futures-core", - "h2 0.4.12", - "http 1.3.1", + "h2 0.4.13", + "http 1.4.0", "http-body 1.0.1", "http-body-util", - "hyper 1.7.0", + "hyper 1.9.0", "hyper-rustls 0.27.7", - "hyper-tls 0.6.0", "hyper-util", "js-sys", "log", "mime", - "native-tls", "percent-encoding", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", + "quinn", + "rustls 0.23.37", "rustls-pki-types", + "rustls-platform-verifier", "serde", "serde_json", "serde_urlencoded", "sync_wrapper 1.0.2", - "tokio 1.49.0", - "tokio-native-tls", + "tokio 1.51.0", + "tokio-rustls 0.26.4", "tower", - "tower-http 0.6.6", + "tower-http 0.6.8", "tower-service", "url", "wasm-bindgen", @@ -6775,9 +6761,9 @@ dependencies = [ [[package]] name = "resolv-conf" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b3789b30bd25ba102de4beabd95d21ac45b69b1be7d14522bab988c526d6799" +checksum = "1e061d1b48cb8d38042de4ae0a7a6401009d6143dc80d2e2d6f31f0bdd6470c7" [[package]] name = "resvg" @@ -6807,7 +6793,7 @@ dependencies = [ "image", "imagesize", "infer", - "jxl-oxide 0.8.1", + "jxl-oxide", "kamadak-exif", "lazy_static", "moka", @@ -6825,7 +6811,7 @@ dependencies = [ "strum_macros", "tempfile", "thumbhash", - "tokio 1.49.0", + "tokio 1.51.0", "tower-http 0.5.2", "tracing", "tracing-subscriber", @@ -6847,7 +6833,7 @@ dependencies = [ "fred", "futures", "log", - "lru 0.7.8", + "lru", "lru_time_cache", "once_cell", "querystring", @@ -6863,16 +6849,16 @@ dependencies = [ "sentry", "serde", "serde_json", - "ulid 0.5.0", + "ulid 1.2.1", ] [[package]] name = "revolt-coalesced" version = "0.12.1" dependencies = [ - "indexmap 2.13.0", - "lru 0.16.3", - "tokio 1.49.0", + "indexmap 2.13.1", + "lru", + "tokio 1.51.0", ] [[package]] @@ -6901,7 +6887,7 @@ dependencies = [ "revolt-database", "revolt-files", "revolt-result", - "tokio 1.49.0", + "tokio 1.51.0", ] [[package]] @@ -6920,15 +6906,15 @@ dependencies = [ "deadqueue", "decancer", "futures", - "indexmap 1.9.3", + "indexmap 2.13.1", "isahc", "iso8601-timestamp", - "linkify 0.8.1", + "linkify", "livekit-api", "livekit-protocol", - "livekit-runtime 0.3.1", + "livekit-runtime", "log", - "lru 0.11.1", + "lru", "mongodb", "nanoid", "once_cell", @@ -6945,7 +6931,7 @@ dependencies = [ "revolt_optional_struct", "revolt_rocket_okapi", "rocket", - "schemars 0.8.22", + "schemars", "serde", "serde_json", "ulid 1.2.1", @@ -6959,29 +6945,28 @@ name = "revolt-delta" version = "0.12.1" dependencies = [ "amqprs", - "async-channel 1.9.0", + "async-channel 2.5.0", "async-std", "authifier", "bitfield", "chrono", "dashmap", - "env_logger", "futures", "impl_ops", "iso8601-timestamp", "lettre", - "linkify 0.6.0", + "linkify", "livekit-api", "livekit-protocol", "log", - "lru 0.7.8", + "lru", "nanoid", - "num_enum 0.5.11", + "num_enum", "once_cell", "rand 0.8.5", "redis-kiss", "regex", - "reqwest 0.11.27", + "reqwest 0.13.2", "revolt-config", "revolt-database", "revolt-models", @@ -6995,10 +6980,10 @@ dependencies = [ "rocket_cors", "rocket_empty", "rocket_prometheus", - "schemars 0.8.22", + "schemars", "serde", "serde_json", - "ulid 0.4.1", + "ulid 1.2.1", "url", "validator 0.16.1", "vergen", @@ -7013,18 +6998,18 @@ dependencies = [ "async-trait", "aws-config", "aws-sdk-s3", - "base64 0.22.1", + "base64 0.21.7", "ffprobe", "image", "imagesize", - "jxl-oxide 0.12.5", + "jxl-oxide", "resvg", "revolt-config", "revolt-result", "tempfile", "thiserror 2.0.18", "tiny-skia", - "tokio 1.49.0", + "tokio 1.51.0", "tracing", "typenum", "usvg", @@ -7039,7 +7024,7 @@ dependencies = [ "axum", "axum-extra", "lru_time_cache", - "reqwest 0.12.23", + "reqwest 0.13.2", "revolt-coalesced", "revolt-config", "revolt-database", @@ -7048,7 +7033,7 @@ dependencies = [ "revolt-result", "serde", "serde_json", - "tokio 1.49.0", + "tokio 1.51.0", "tower-http 0.5.2", "tracing", "utoipa", @@ -7067,7 +7052,7 @@ dependencies = [ "mime", "moka", "regex", - "reqwest 0.12.23", + "reqwest 0.13.2", "revolt-config", "revolt-files", "revolt-models", @@ -7076,7 +7061,7 @@ dependencies = [ "serde", "serde_json", "tempfile", - "tokio 1.49.0", + "tokio 1.51.0", "tracing", "tracing-subscriber", "utoipa", @@ -7087,16 +7072,16 @@ dependencies = [ name = "revolt-models" version = "0.12.1" dependencies = [ - "indexmap 1.9.3", + "indexmap 2.13.1", "iso8601-timestamp", - "num_enum 0.6.1", + "num_enum", "once_cell", "regex", "revolt-config", "revolt-permissions", "revolt_optional_struct", "rocket", - "schemars 0.8.22", + "schemars", "serde", "utoipa", "validator 0.16.1", @@ -7117,10 +7102,10 @@ dependencies = [ "async-trait", "auto_ops", "bson", - "num_enum 0.6.1", + "num_enum", "once_cell", "revolt-result", - "schemars 0.8.22", + "schemars", "serde", ] @@ -7144,7 +7129,7 @@ dependencies = [ "anyhow", "async-trait", "authifier", - "base64 0.22.1", + "base64 0.21.7", "fcm_v1", "isahc", "iso8601-timestamp", @@ -7162,7 +7147,7 @@ dependencies = [ "revolt_optional_struct", "serde", "serde_json", - "tokio 1.49.0", + "tokio 1.51.0", "ulid 1.2.1", "web-push", ] @@ -7193,7 +7178,7 @@ dependencies = [ "revolt_okapi", "revolt_rocket_okapi", "rocket", - "schemars 0.8.22", + "schemars", "sentry", "serde", "serde_json", @@ -7210,9 +7195,9 @@ dependencies = [ "futures", "livekit-api", "livekit-protocol", - "livekit-runtime 0.3.1", + "livekit-runtime", "log", - "lru 0.7.8", + "lru", "redis-kiss", "revolt-config", "revolt-database", @@ -7225,7 +7210,7 @@ dependencies = [ "sentry", "serde", "serde_json", - "ulid 0.5.0", + "ulid 1.2.1", ] [[package]] @@ -7236,20 +7221,21 @@ checksum = "edbe1f79cb41271d3cd8f932d75dddeba963c19dc93d1ee6cbe0391b495ab2f5" dependencies = [ "base64 0.21.7", "erased-serde", - "http 1.3.1", + "http 1.4.0", "http-body-util", - "hyper 1.7.0", + "hyper 1.9.0", "hyper-rustls 0.26.0", "hyper-util", + "openssl", "parking_lot", - "pem 3.0.5", + "pem 3.0.6", "ring", "rustls 0.22.4", "rustls-pemfile 2.2.0", "serde", "serde_json", "thiserror 1.0.69", - "tokio 1.49.0", + "tokio 1.51.0", ] [[package]] @@ -7265,7 +7251,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23bfdf7ae769c3042fe727f6e5c17363b02a64b4b33ad60c3e5f73b26df7835b" dependencies = [ "log", - "schemars 0.8.22", + "schemars", "serde", "serde_json", ] @@ -7291,7 +7277,7 @@ dependencies = [ "revolt_okapi", "revolt_rocket_okapi_codegen", "rocket", - "schemars 0.8.22", + "schemars", "serde", "serde_json", ] @@ -7304,7 +7290,7 @@ checksum = "cc6620569d8ac8f0a1690fcca13f488503807a60e96ebf729749b59aca1dbef9" dependencies = [ "darling 0.13.4", "proc-macro2", - "quote 1.0.40", + "quote 1.0.45", "rocket_http", "syn 1.0.109", ] @@ -7332,9 +7318,9 @@ dependencies = [ [[package]] name = "rgb" -version = "0.8.52" +version = "0.8.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c6a884d2998352bb4daf0183589aec883f16a6da1f4dde84d8e2e9a5409a1ce" +checksum = "47b34b781b31e5d73e9fbc8689c70551fd1ade9a19e3e28cfec8580a79290cc4" dependencies = [ "bytemuck", ] @@ -7347,7 +7333,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.16", + "getrandom 0.2.17", "libc", "untrusted", "windows-sys 0.52.0", @@ -7355,22 +7341,19 @@ dependencies = [ [[package]] name = "rmp" -version = "0.8.14" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4" +checksum = "4ba8be72d372b2c9b35542551678538b562e7cf86c3315773cae48dfbfe7790c" dependencies = [ - "byteorder", "num-traits", - "paste", ] [[package]] name = "rmp-serde" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db" +checksum = "72f81bee8c8ef9b577d1681a70ebbc962c232461e397b22c208c43c04b67a155" dependencies = [ - "byteorder", "rmp", "serde", ] @@ -7385,17 +7368,17 @@ dependencies = [ "async-trait", "atomic 0.5.3", "binascii", - "bytes 1.10.1", + "bytes 1.11.1", "either", "figment", "futures", - "indexmap 2.13.0", + "indexmap 2.13.1", "log", "memchr", "multer", "num_cpus", "parking_lot", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", "rand 0.8.5", "ref-cast", "rocket_codegen", @@ -7405,7 +7388,7 @@ dependencies = [ "state", "tempfile", "time", - "tokio 1.49.0", + "tokio 1.51.0", "tokio-stream", "tokio-util", "ubyte", @@ -7425,7 +7408,7 @@ dependencies = [ "revolt_rocket_okapi", "rocket", "rocket_empty", - "schemars 0.8.22", + "schemars", "serde", ] @@ -7437,11 +7420,11 @@ checksum = "575d32d7ec1a9770108c879fc7c47815a80073f96ca07ff9525a94fcede1dd46" dependencies = [ "devise", "glob", - "indexmap 2.13.0", + "indexmap 2.13.1", "proc-macro2", - "quote 1.0.40", + "quote 1.0.45", "rocket_http", - "syn 2.0.106", + "syn 2.0.117", "unicode-xid 0.2.6", "version_check", ] @@ -7484,19 +7467,19 @@ dependencies = [ "futures", "http 0.2.12", "hyper 0.14.32", - "indexmap 2.13.0", + "indexmap 2.13.1", "log", "memchr", "pear", "percent-encoding", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", "ref-cast", "serde", "smallvec", "stable-pattern", "state", "time", - "tokio 1.49.0", + "tokio 1.51.0", "uncased", ] @@ -7539,7 +7522,7 @@ dependencies = [ "num-integer", "num-iter", "num-traits", - "pkcs1", + "pkcs1 0.4.1", "pkcs8 0.9.0", "rand_core 0.6.4", "signature 1.6.4", @@ -7548,6 +7531,26 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rsa" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" +dependencies = [ + "const-oid 0.9.6", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1 0.7.5", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "signature 2.2.0", + "spki 0.7.3", + "subtle", + "zeroize", +] + [[package]] name = "rust-argon2" version = "1.0.1" @@ -7556,7 +7559,7 @@ checksum = "a5885493fdf0be6cdff808d1533ce878d21cfa49c7086fa00c66355cd9141bfc" dependencies = [ "base64 0.21.7", "blake2b_simd", - "constant_time_eq", + "constant_time_eq 0.3.1", "crossbeam-utils", ] @@ -7572,15 +7575,15 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" +checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" [[package]] name = "rustc-hash" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" [[package]] name = "rustc_version" @@ -7603,15 +7606,15 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.2" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.11.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.61.0", + "windows-sys 0.61.2", ] [[package]] @@ -7642,16 +7645,16 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.32" +version = "0.23.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40" +checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" dependencies = [ "aws-lc-rs", "log", "once_cell", "ring", "rustls-pki-types", - "rustls-webpki 0.103.6", + "rustls-webpki 0.103.10", "subtle", "zeroize", ] @@ -7662,7 +7665,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ - "openssl-probe", + "openssl-probe 0.1.6", "rustls-pemfile 1.0.4", "schannel", "security-framework 2.11.1", @@ -7670,14 +7673,14 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" +checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" dependencies = [ - "openssl-probe", + "openssl-probe 0.2.1", "rustls-pki-types", "schannel", - "security-framework 3.4.0", + "security-framework 3.7.0", ] [[package]] @@ -7700,13 +7703,41 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.12.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" dependencies = [ + "web-time", "zeroize", ] +[[package]] +name = "rustls-platform-verifier" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" +dependencies = [ + "core-foundation 0.10.1", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls 0.23.37", + "rustls-native-certs 0.8.3", + "rustls-platform-verifier-android", + "rustls-webpki 0.103.10", + "security-framework 3.7.0", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + [[package]] name = "rustls-webpki" version = "0.101.7" @@ -7730,9 +7761,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.6" +version = "0.103.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8572f3c2cb9934231157b45499fc41e1f58c589fdfb81a844ba873265e80f8eb" +checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef" dependencies = [ "aws-lc-rs", "ring", @@ -7752,7 +7783,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c85d1ccd519e61834798eb52c4e886e8c2d7d698dd3d6ce0b1b47eb8557f1181" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.11.0", "bytemuck", "core_maths", "log", @@ -7766,52 +7797,38 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.20" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] -name = "schannel" -version = "0.1.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" -dependencies = [ - "windows-sys 0.61.0", -] - -[[package]] -name = "schemars" -version = "0.8.22" +name = "same-file" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" dependencies = [ - "dyn-clone", - "indexmap 1.9.3", - "schemars_derive", - "serde", - "serde_json", + "winapi-util", ] [[package]] -name = "schemars" -version = "0.9.0" +name = "schannel" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" dependencies = [ - "dyn-clone", - "ref-cast", - "serde", - "serde_json", + "windows-sys 0.61.2", ] [[package]] name = "schemars" -version = "1.0.4" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0" +checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" dependencies = [ "dyn-clone", - "ref-cast", + "indexmap 1.9.3", + "indexmap 2.13.1", + "schemars_derive", "serde", "serde_json", ] @@ -7823,9 +7840,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d" dependencies = [ "proc-macro2", - "quote 1.0.40", + "quote 1.0.45", "serde_derive_internals", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -7917,7 +7934,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.11.0", "core-foundation 0.9.4", "core-foundation-sys", "libc", @@ -7926,11 +7943,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "3.4.0" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b369d18893388b345804dc0007963c99b7d665ae71d275812d828c6f089640" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.11.0", "core-foundation 0.10.1", "core-foundation-sys", "libc", @@ -7939,9 +7956,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.15.0" +version = "2.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" dependencies = [ "core-foundation-sys", "libc", @@ -7953,9 +7970,9 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4eb30575f3638fc8f6815f448d50cb1a2e255b0897985c8c59f4d37b72a07b06" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.11.0", "cssparser", - "derive_more", + "derive_more 0.99.20", "fxhash", "log", "new_debug_unreachable", @@ -7968,9 +7985,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" [[package]] name = "sentry" @@ -7987,7 +8004,7 @@ dependencies = [ "sentry-debug-images", "sentry-panic", "sentry-tracing", - "tokio 1.49.0", + "tokio 1.51.0", "ureq", ] @@ -8132,9 +8149,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.225" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6c24dee235d0da097043389623fb913daddf92c76e9f5a1db88607a0bcbd1d" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ "serde_core", "serde_derive", @@ -8161,22 +8178,22 @@ dependencies = [ [[package]] name = "serde_core" -version = "1.0.225" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "659356f9a0cb1e529b24c01e43ad2bdf520ec4ceaf83047b83ddcc2251f96383" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.225" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea936adf78b1f766949a4977b91d2f5595825bd6ec079aa9543ad2685fc4516" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -8186,22 +8203,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] name = "serde_json" -version = "1.0.145" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ - "indexmap 2.13.0", + "indexmap 2.13.1", "itoa", "memchr", - "ryu", "serde", "serde_core", + "zmij", ] [[package]] @@ -8238,34 +8255,24 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.14.1" +version = "3.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c522100790450cf78eeac1507263d0a350d4d5b30df0c8e1fe051a10c22b376e" +checksum = "dd5414fad8e6907dbdd5bc441a50ae8d6e26151a03b1de04d89a5576de61d01f" dependencies = [ - "base64 0.22.1", - "chrono", - "hex", - "indexmap 1.9.3", - "indexmap 2.13.0", - "schemars 0.9.0", - "schemars 1.0.4", - "serde", - "serde_derive", - "serde_json", + "serde_core", "serde_with_macros", - "time", ] [[package]] name = "serde_with_macros" -version = "3.14.1" +version = "3.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327ada00f7d64abaac1e55a6911e90cf665aa051b9a561c7006c157f4633135e" +checksum = "d3db8978e608f1fe7357e211969fd9abdcae80bac1ba7a3369bb7eb6b404eb65" dependencies = [ - "darling 0.21.3", + "darling 0.23.0", "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -8333,10 +8340,11 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.6" +version = "1.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" dependencies = [ + "errno", "libc", ] @@ -8362,9 +8370,9 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.7" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" [[package]] name = "simd_helpers" @@ -8372,7 +8380,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" dependencies = [ - "quote 1.0.40", + "quote 1.0.45", ] [[package]] @@ -8398,32 +8406,32 @@ checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" [[package]] name = "siphasher" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" +checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" [[package]] name = "slab" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "slotmap" -version = "1.0.7" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" +checksum = "bdd58c3c93c3d278ca835519292445cb4b0d4dc59ccfdf7ceadaab3f8aeb4038" dependencies = [ "version_check", ] [[package]] name = "sluice" -version = "0.5.5" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7400c0eff44aa2fcb5e31a5f24ba9716ed90138769e4977a2ba6014ae63eb5" +checksum = "160b744a45e8261307bcfe03c98e2f8274502207d534c9a64b675c4db1b6bd58" dependencies = [ - "async-channel 1.9.0", + "async-channel 2.5.0", "futures-core", "futures-io", ] @@ -8456,12 +8464,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.0" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -8470,6 +8478,12 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "spin" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" + [[package]] name = "spki" version = "0.6.0" @@ -8501,9 +8515,9 @@ dependencies = [ [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "state" @@ -8511,7 +8525,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b8c4a4445d81357df8b1a650d0d0d6fbbbfe99d064aa5e02f3e4022061476d8" dependencies = [ - "loom 0.5.6", + "loom", ] [[package]] @@ -8545,7 +8559,7 @@ dependencies = [ "phf_generator 0.11.3", "phf_shared 0.11.3", "proc-macro2", - "quote 1.0.40", + "quote 1.0.45", ] [[package]] @@ -8579,9 +8593,9 @@ checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ "heck 0.5.0", "proc-macro2", - "quote 1.0.40", + "quote 1.0.45", "rustversion", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -8597,7 +8611,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68c7541fff44b35860c1a7a47a7cadf3e4a304c457b58f9870d9706ece028afc" dependencies = [ "kurbo", - "siphasher 1.0.1", + "siphasher 1.0.2", ] [[package]] @@ -8618,18 +8632,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", - "quote 1.0.40", + "quote 1.0.45", "unicode-ident", ] [[package]] name = "syn" -version = "2.0.106" +version = "2.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" dependencies = [ "proc-macro2", - "quote 1.0.40", + "quote 1.0.45", "unicode-ident", ] @@ -8664,7 +8678,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ "proc-macro2", - "quote 1.0.40", + "quote 1.0.45", "syn 1.0.109", "unicode-xid 0.2.6", ] @@ -8676,8 +8690,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -8707,11 +8721,11 @@ dependencies = [ [[package]] name = "system-configuration" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.11.0", "core-foundation 0.9.4", "system-configuration-sys 0.6.0", ] @@ -8756,15 +8770,15 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.22.0" +version = "3.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84fa4d11fadde498443cca10fd3ac23c951f0dc59e080e9f4b93d4df4e4eea53" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ - "fastrand 2.3.0", - "getrandom 0.3.3", + "fastrand 2.4.0", + "getrandom 0.4.2", "once_cell", "rustix", - "windows-sys 0.61.0", + "windows-sys 0.61.2", ] [[package]] @@ -8812,8 +8826,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -8823,8 +8837,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -8844,23 +8858,23 @@ checksum = "8b7726e0245a7331bd0c9a1fb4fd99fd695bcd478ca569f0eda2ff2cb14e7a00" [[package]] name = "tiff" -version = "0.10.3" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af9605de7fee8d9551863fd692cce7637f548dbd9db9180fcc07ccc6d26c336f" +checksum = "b63feaf3343d35b6ca4d50483f94843803b0f51634937cc2ec519fc32232bc52" dependencies = [ "fax", "flate2", "half", "quick-error 2.0.1", "weezl", - "zune-jpeg 0.4.21", + "zune-jpeg 0.5.15", ] [[package]] name = "time" -version = "0.3.44" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" dependencies = [ "deranged", "itoa", @@ -8868,22 +8882,22 @@ dependencies = [ "num-conv", "num_threads", "powerfmt", - "serde", + "serde_core", "time-core", "time-macros", ] [[package]] name = "time-core" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" [[package]] name = "time-macros" -version = "0.2.24" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" dependencies = [ "num-conv", "time-core", @@ -8926,9 +8940,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" dependencies = [ "displaydoc", "zerovec", @@ -8936,9 +8950,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" dependencies = [ "tinyvec_macros", ] @@ -8962,30 +8976,30 @@ dependencies = [ [[package]] name = "tokio" -version = "1.49.0" +version = "1.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" +checksum = "2bd1c4c0fc4a7ab90fc15ef6daaa3ec3b893f004f915f2392557ed23237820cd" dependencies = [ - "bytes 1.10.1", + "bytes 1.11.1", "libc", "mio", "parking_lot", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", "signal-hook-registry", - "socket2 0.6.0", + "socket2 0.6.3", "tokio-macros", - "windows-sys 0.61.0", + "windows-sys 0.61.2", ] [[package]] name = "tokio-macros" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -8995,7 +9009,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ "native-tls", - "tokio 1.49.0", + "tokio 1.51.0", ] [[package]] @@ -9005,7 +9019,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ "rustls 0.21.12", - "tokio 1.49.0", + "tokio 1.51.0", ] [[package]] @@ -9016,42 +9030,42 @@ checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" dependencies = [ "rustls 0.22.4", "rustls-pki-types", - "tokio 1.49.0", + "tokio 1.51.0", ] [[package]] name = "tokio-rustls" -version = "0.26.3" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f63835928ca123f1bef57abbcd23bb2ba0ac9ae1235f1e65bda0d06e7786bd" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ - "rustls 0.23.32", - "tokio 1.49.0", + "rustls 0.23.37", + "tokio 1.51.0", ] [[package]] name = "tokio-stream" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" +checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" dependencies = [ "futures-core", - "pin-project-lite 0.2.16", - "tokio 1.49.0", + "pin-project-lite 0.2.17", + "tokio 1.51.0", ] [[package]] name = "tokio-util" -version = "0.7.16" +version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" dependencies = [ - "bytes 1.10.1", + "bytes 1.11.1", "futures-core", "futures-io", "futures-sink", - "pin-project-lite 0.2.16", - "tokio 1.49.0", + "pin-project-lite 0.2.17", + "tokio 1.51.0", ] [[package]] @@ -9090,7 +9104,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.13.0", + "indexmap 2.13.1", "toml_datetime", "winnow 0.5.40", ] @@ -9101,12 +9115,12 @@ version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 2.13.0", + "indexmap 2.13.1", "serde", "serde_spanned", "toml_datetime", "toml_write", - "winnow 0.7.13", + "winnow 0.7.15", ] [[package]] @@ -9129,15 +9143,15 @@ dependencies = [ [[package]] name = "tower" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" dependencies = [ "futures-core", "futures-util", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", "sync_wrapper 1.0.2", - "tokio 1.49.0", + "tokio 1.51.0", "tower-layer", "tower-service", "tracing", @@ -9149,29 +9163,29 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ - "bitflags 2.9.4", - "bytes 1.10.1", - "http 1.3.1", + "bitflags 2.11.0", + "bytes 1.11.1", + "http 1.4.0", "http-body 1.0.1", "http-body-util", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", "tower-layer", "tower-service", ] [[package]] name = "tower-http" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ - "bitflags 2.9.4", - "bytes 1.10.1", + "bitflags 2.11.0", + "bytes 1.11.1", "futures-util", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "iri-string", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", "tower", "tower-layer", "tower-service", @@ -9196,7 +9210,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "log", - "pin-project-lite 0.2.16", + "pin-project-lite 0.2.17", "tracing-attributes", "tracing-core", ] @@ -9208,8 +9222,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -9245,9 +9259,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.22" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" dependencies = [ "matchers", "nu-ansi-term", @@ -9284,7 +9298,7 @@ checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0" dependencies = [ "base64 0.13.1", "byteorder", - "bytes 1.10.1", + "bytes 1.11.1", "http 0.2.12", "httparse", "log", @@ -9297,29 +9311,29 @@ dependencies = [ [[package]] name = "typed-builder" -version = "0.20.1" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd9d30e3a08026c78f246b173243cf07b3696d274debd26680773b6773c2afc7" +checksum = "398a3a3c918c96de527dc11e6e846cd549d4508030b8a33e1da12789c856b81a" dependencies = [ "typed-builder-macro", ] [[package]] name = "typed-builder-macro" -version = "0.20.1" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c36781cc0e46a83726d9879608e4cf6c2505237e263a8eb8c24502989cfdb28" +checksum = "0e48cea23f68d1f78eb7bc092881b6bb88d3d6b5b7e6234f6f9c911da1ffb221" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] name = "typenum" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "ubyte" @@ -9336,17 +9350,6 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" -[[package]] -name = "ulid" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e95a59b292ca0cf9b45be2e52294d1ca6cb24eb11b08ef4376f73f1a00c549" -dependencies = [ - "chrono", - "lazy_static", - "rand 0.6.5", -] - [[package]] name = "ulid" version = "0.5.0" @@ -9389,9 +9392,9 @@ dependencies = [ [[package]] name = "unicase" -version = "2.8.1" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" +checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" [[package]] name = "unicase_serde" @@ -9423,36 +9426,36 @@ checksum = "260bc6647b3893a9a90668360803a15f96b85a5257b1c3a0c3daf6ae2496de42" [[package]] name = "unicode-ident" -version = "1.0.19" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-normalization" -version = "0.1.24" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8" dependencies = [ "tinyvec", ] [[package]] name = "unicode-properties" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" +checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d" [[package]] name = "unicode-script" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb421b350c9aff471779e262955939f565ec18b86c15364e6bdf0d662ca7c1f" +checksum = "383ad40bb927465ec0ce7720e033cb4ca06912855fc35db31b5755d0de75b1ee" [[package]] name = "unicode-segmentation" -version = "1.12.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" [[package]] name = "unicode-vo" @@ -9462,9 +9465,9 @@ checksum = "b1d386ff53b415b7fe27b50bb44679e2cc4660272694b7b6f3326d8480823a94" [[package]] name = "unicode-width" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "unicode-xid" @@ -9509,14 +9512,15 @@ dependencies = [ [[package]] name = "url" -version = "2.5.7" +version = "2.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" dependencies = [ "form_urlencoded", "idna 1.1.0", "percent-encoding", "serde", + "serde_derive", ] [[package]] @@ -9551,7 +9555,7 @@ dependencies = [ "roxmltree", "rustybuzz", "simplecss", - "siphasher 1.0.1", + "siphasher 1.0.2", "strict-num", "svgtypes", "tiny-skia-path", @@ -9579,7 +9583,7 @@ version = "4.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5afb1a60e207dca502682537fefcfd9921e71d0b83e9576060f09abc6efab23" dependencies = [ - "indexmap 2.13.0", + "indexmap 2.13.1", "serde", "serde_json", "utoipa-gen", @@ -9593,9 +9597,9 @@ checksum = "20c24e8ab68ff9ee746aad22d39b5535601e6416d1b0feeabf78be986a5c4392" dependencies = [ "proc-macro-error", "proc-macro2", - "quote 1.0.40", + "quote 1.0.45", "regex", - "syn 2.0.106", + "syn 2.0.117", "ulid 1.2.1", ] @@ -9613,11 +9617,11 @@ dependencies = [ [[package]] name = "uuid" -version = "1.19.0" +version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" +checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.4.2", "js-sys", "serde_core", "wasm-bindgen", @@ -9675,7 +9679,7 @@ dependencies = [ "lazy_static", "proc-macro-error", "proc-macro2", - "quote 1.0.40", + "quote 1.0.45", "regex", "syn 1.0.109", "validator_types", @@ -9699,9 +9703,9 @@ checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" [[package]] name = "value-bag" -version = "1.11.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "943ce29a8a743eb10d6082545d861b24f9d1b160b7d741e0f2cdf726bec909c5" +checksum = "7ba6f5989077681266825251a52748b8c1d8a4ad098cc37e440103d0ea717fc0" [[package]] name = "vcpkg" @@ -9745,6 +9749,16 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "want" version = "0.3.1" @@ -9761,37 +9775,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] -name = "wasi" -version = "0.14.7+wasi-0.2.4" +name = "wasip2" +version = "1.0.2+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" dependencies = [ - "wasip2", + "wit-bindgen", ] [[package]] -name = "wasip2" -version = "1.0.1+wasi-0.2.4" +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" dependencies = [ "wit-bindgen", ] [[package]] name = "wasix" -version = "0.12.21" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1fbb4ef9bbca0c1170e0b00dd28abc9e3b68669821600cad1caaed606583c6d" +checksum = "1757e0d1f8456693c7e5c6c629bdb54884e032aa0bb53c155f6a39f94440d332" dependencies = [ - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", ] [[package]] name = "wasm-bindgen" -version = "0.2.103" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab10a69fbd0a177f5f649ad4d8d3305499c42bab9aef2f7ff592d0ec8f833819" +checksum = "0551fc1bb415591e3372d0bc4780db7e587d84e2a7e79da121051c5c4b89d0b0" dependencies = [ "cfg-if", "once_cell", @@ -9800,65 +9814,82 @@ dependencies = [ "wasm-bindgen-shared", ] -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.103" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb702423545a6007bbc368fde243ba47ca275e549c8a28617f56f6ba53b1d1c" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", - "wasm-bindgen-shared", -] - [[package]] name = "wasm-bindgen-futures" -version = "0.4.53" +version = "0.4.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0b221ff421256839509adbb55998214a70d829d3a28c69b4a6672e9d2a42f67" +checksum = "03623de6905b7206edd0a75f69f747f134b7f0a2323392d664448bf2d3c5d87e" dependencies = [ - "cfg-if", "js-sys", - "once_cell", "wasm-bindgen", - "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.103" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc65f4f411d91494355917b605e1480033152658d71f722a90647f56a70c88a0" +checksum = "7fbdf9a35adf44786aecd5ff89b4563a90325f9da0923236f6104e603c7e86be" dependencies = [ - "quote 1.0.40", + "quote 1.0.45", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.103" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc003a991398a8ee604a401e194b6b3a39677b3173d6e74495eb51b82e99a32" +checksum = "dca9693ef2bab6d4e6707234500350d8dad079eb508dca05530c85dc3a529ff2" dependencies = [ + "bumpalo", "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", - "wasm-bindgen-backend", + "quote 1.0.45", + "syn 2.0.117", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.103" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "293c37f4efa430ca14db3721dfbe48d8c33308096bd44d80ebaa775ab71ba1cf" +checksum = "39129a682a6d2d841b6c429d0c51e5cb0ed1a03829d8b3d1e69a011e62cb3d3b" dependencies = [ "unicode-ident", ] +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap 2.13.1", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags 2.11.0", + "hashbrown 0.15.5", + "indexmap 2.13.1", + "semver", +] + [[package]] name = "web-push" version = "0.10.4" @@ -9869,12 +9900,12 @@ dependencies = [ "base64 0.13.1", "chrono", "ece", - "futures-lite 2.6.1", + "futures-lite", "http 0.2.12", "isahc", "jwt-simple", "log", - "pem 3.0.5", + "pem 3.0.6", "sec1_decode", "serde", "serde_derive", @@ -9883,9 +9914,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.80" +version = "0.3.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbe734895e869dc429d78c4b433f8d17d95f8d05317440b4fad5ab2d33e596dc" +checksum = "cd70027e39b12f0849461e08ffc50b9cd7688d942c1c8e3c7b22273236b4dd0a" dependencies = [ "js-sys", "wasm-bindgen", @@ -9911,35 +9942,44 @@ dependencies = [ "libwebp-sys", ] +[[package]] +name = "webpki-root-certs" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "804f18a4ac2676ffb4e8b5b5fa9ae38af06df08162314f96a68d2a363e21a8ca" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "webpki-roots" version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "webpki-roots 1.0.2", + "webpki-roots 1.0.6", ] [[package]] name = "webpki-roots" -version = "1.0.2" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2" +checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" dependencies = [ "rustls-pki-types", ] [[package]] name = "weezl" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a751b3277700db47d3e574514de2eced5e54dc8a5436a3bf7a0b248b2cee16f3" +checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88" [[package]] name = "widestring" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d" +checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471" [[package]] name = "winapi" @@ -9963,7 +10003,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.0", + "windows-sys 0.61.2", ] [[package]] @@ -9981,154 +10021,83 @@ dependencies = [ "windows-targets 0.48.5", ] -[[package]] -name = "windows" -version = "0.61.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" -dependencies = [ - "windows-collections", - "windows-core 0.61.2", - "windows-future", - "windows-link 0.1.3", - "windows-numerics", -] - -[[package]] -name = "windows-collections" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" -dependencies = [ - "windows-core 0.61.2", -] - -[[package]] -name = "windows-core" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" -dependencies = [ - "windows-implement", - "windows-interface", - "windows-link 0.1.3", - "windows-result 0.3.4", - "windows-strings 0.4.2", -] - [[package]] name = "windows-core" -version = "0.62.0" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57fe7168f7de578d2d8a05b07fd61870d2e73b4020e9f49aa00da8471723497c" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ "windows-implement", "windows-interface", - "windows-link 0.2.0", - "windows-result 0.4.0", - "windows-strings 0.5.0", -] - -[[package]] -name = "windows-future" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" -dependencies = [ - "windows-core 0.61.2", - "windows-link 0.1.3", - "windows-threading", + "windows-link", + "windows-result", + "windows-strings", ] [[package]] name = "windows-implement" -version = "0.60.0" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] name = "windows-interface" -version = "0.59.1" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] name = "windows-link" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" - -[[package]] -name = "windows-link" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" - -[[package]] -name = "windows-numerics" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" -dependencies = [ - "windows-core 0.61.2", - "windows-link 0.1.3", -] +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-registry" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" -dependencies = [ - "windows-link 0.1.3", - "windows-result 0.3.4", - "windows-strings 0.4.2", -] - -[[package]] -name = "windows-result" -version = "0.3.4" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" dependencies = [ - "windows-link 0.1.3", + "windows-link", + "windows-result", + "windows-strings", ] [[package]] name = "windows-result" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7084dcc306f89883455a206237404d3eaf961e5bd7e0f312f7c91f57eb44167f" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ - "windows-link 0.2.0", + "windows-link", ] [[package]] name = "windows-strings" -version = "0.4.2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ - "windows-link 0.1.3", + "windows-link", ] [[package]] -name = "windows-strings" -version = "0.5.0" +name = "windows-sys" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7218c655a553b0bed4426cf54b20d7ba363ef543b52d515b3e48d7fd55318dda" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "windows-link 0.2.0", + "windows-targets 0.42.2", ] [[package]] @@ -10160,11 +10129,35 @@ dependencies = [ [[package]] name = "windows-sys" -version = "0.61.0" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" dependencies = [ - "windows-link 0.2.0", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", ] [[package]] @@ -10200,29 +10193,26 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.3" +version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ - "windows-link 0.1.3", - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", ] [[package]] -name = "windows-threading" -version = "0.1.0" +name = "windows_aarch64_gnullvm" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" -dependencies = [ - "windows-link 0.1.3", -] +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_gnullvm" @@ -10238,9 +10228,15 @@ checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_gnullvm" -version = "0.53.0" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" @@ -10256,9 +10252,15 @@ checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_aarch64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" @@ -10274,9 +10276,9 @@ checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" [[package]] name = "windows_i686_gnullvm" @@ -10286,9 +10288,15 @@ checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_gnullvm" -version = "0.53.0" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" @@ -10304,9 +10312,15 @@ checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_i686_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" @@ -10322,9 +10336,15 @@ checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnu" -version = "0.53.0" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_gnullvm" @@ -10340,9 +10360,15 @@ checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" @@ -10358,9 +10384,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "windows_x86_64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" @@ -10373,9 +10399,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.7.13" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" dependencies = [ "memchr", ] @@ -10392,15 +10418,97 @@ dependencies = [ [[package]] name = "wit-bindgen" -version = "0.46.0" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck 0.5.0", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck 0.5.0", + "indexmap 2.13.1", + "prettyplease", + "syn 2.0.117", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote 1.0.45", + "syn 2.0.117", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags 2.11.0", + "indexmap 2.13.1", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap 2.13.1", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid 0.2.6", + "wasmparser", +] [[package]] name = "writeable" -version = "0.6.1" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" [[package]] name = "wyz" @@ -10449,11 +10557,10 @@ dependencies = [ [[package]] name = "yoke" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" dependencies = [ - "serde", "stable_deref_trait", "yoke-derive", "zerofrom", @@ -10461,13 +10568,13 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", "synstructure 0.13.2", ] @@ -10493,63 +10600,63 @@ dependencies = [ "serde", "serde_json", "time", - "tokio 1.49.0", + "tokio 1.51.0", "tower-service", "url", ] [[package]] name = "zerocopy" -version = "0.8.27" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" +checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.27" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" +checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] name = "zerofrom" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", "synstructure 0.13.2", ] [[package]] name = "zeroize" -version = "1.8.1" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" [[package]] name = "zerotrie" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" dependencies = [ "displaydoc", "yoke", @@ -10558,9 +10665,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.4" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" dependencies = [ "yoke", "zerofrom", @@ -10569,15 +10676,21 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.1" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", - "quote 1.0.40", - "syn 2.0.106", + "quote 1.0.45", + "syn 2.0.117", ] +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" + [[package]] name = "zune-core" version = "0.4.12" @@ -10610,9 +10723,9 @@ dependencies = [ [[package]] name = "zune-jpeg" -version = "0.5.11" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2959ca473aae96a14ecedf501d20b3608d2825ba280d5adb57d651721885b0c2" +checksum = "27bc9d5b815bc103f142aa054f561d9187d191692ec7c2d1e2b4737f8dbd7296" dependencies = [ "zune-core 0.5.1", ] diff --git a/Cargo.toml b/Cargo.toml index 10989fb15..23b4ceb00 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -resolver = "2" +resolver = "3" members = [ "crates/delta", @@ -20,24 +20,129 @@ lto = true [workspace.dependencies] # Async async-trait = "0.1.89" -tokio = { version = "1.49.0", features = ["macros", "rt"] } +tokio = "1.49.0" +async-channel = "2.3.1" +futures = "0.3.32" +async-std = "1.8.0" +async-tungstenite = "0.17.0" +futures-locks = "0.7.1" +async-lock = "2.8.0" +async-recursion = "1.0.4" # Error Handling anyhow = "1.0.100" thiserror = "2.0.18" +sentry = "0.31.5" +sentry-anyhow = "0.38.1" -# Other Utilities -uuid = { version = "1.19.0", features = ["v4"] } +# Data Validation +regex = "1.12.3" +validator = "0.16" + +# Data Types +uuid = "1.19.0" +ulid = "1.2.1" +nanoid = "0.4.0" +typenum = "1.17.0" +num_enum = "0.6.1" +bitfield = "0.13.2" + +# Time +chrono = "0.4.15" +iso8601-timestamp = "0.2.10" + +# Data Collections +lru = "0.16.3" +indexmap = "2.13.1" +dashmap = "5.2.0" +moka = "0.12.8" +lru_time_cache = "0.11.11" +deadqueue = "0.2.4" + +# Web scraping +scraper = "0.20.0" +encoding_rs = "0.8.34" + +# Mail +lettre = "0.10.0-alpha.4" + +# HTTP Requests +reqwest = "0.13.2" +isahc = "1.7" + +# Notifications +fcm_v1 = "0.3.0" +web-push = "0.10.0" +revolt_a2 = "0.10" + +# Parsing +logos = "0.15" + +# SVG rendering +usvg = "0.44.0" +resvg = "0.44.0" +tiny-skia = "0.11.4" + +# Logging +log = "0.4.29" +pretty_env_logger = "0.4.0" + +# Redis +redis-kiss = "0.1.4" +fred = "8.0.1" + +# Serialisation +bincode = "1.3.3" +serde_json = "1.0.79" +rmp-serde = "1.0.0" +serde = { version = "1", features = ["derive"] } +strum_macros = "0.26.4" + +# MongoDB +bson = { version = "2.1.0" } +mongodb = { version = "3.1.0" } + +# S3 +aws-config = "1.5.5" +aws-sdk-s3 = "1.46.0" # Axum (HTTP server) axum-macros = "0.4.1" axum_typed_multipart = "0.12.1" -axum = { version = "0.7.5", features = ["multipart"] } -tower-http = { version = "0.5.2", features = ["cors", "trace"] } +axum = "0.7.5" +axum-extra = "0.9" +tower-http = "0.5.2" + +# Rocket (HTTP server) +rocket = "0.5.1" +rocket_empty = "0.1.1" +revolt_rocket_okapi = "0.10.0" +rocket_cors = { git = "https://github.com/lawliet89/rocket_cors", rev = "072d90359b23e9b291df6b672c07c93de9c46011" } +rocket_authifier = "1.0.16" +rocket_prometheus = "0.10.0-rc.3" + +# Spec Generation +utoipa = "4.2.3" +revolt_okapi = "0.9.1" +schemars = "0.8.8" +utoipa-scalar = "0.1.0" # Image Processing -jxl-oxide = { version = "0.12.5", features = ["image"] } -image = "0.25.9" +jxl-oxide = "0.12.5" +sha2 = "0.10.8" +kamadak-exif = "0.5.4" +webp = "0.3.0" +image = "0.25.2" # avif encode requires dav1d system library: features = ["avif-native"] +thumbhash = "0.1.0" + +# File processing +revolt_clamav-client = "0.1.5" +simdutf8 = "0.1.4" + +# Content type processing +infer = "0.16.0" +ffprobe = "0.4.0" +imagesize = "0.13.0" # OpenTelemetry tracing = "0.1.44" @@ -47,4 +152,50 @@ tracing-subscriber = { version = "0.3.22", features = [ opentelemetry = { version = "0.31.0", features = ["logs"] } opentelemetry_sdk = { version = "0.31.0", features = ["logs"] } opentelemetry-otlp = { version = "0.31.0", features = ["logs"] } -opentelemetry-appender-tracing = { version = "0.31.1" } +opentelemetry-appender-tracing = "0.31.1" + +# Authifier +authifier = "1.0.16" + +# RabbitMQ +amqprs = "1.7.0" + +# Voice +livekit-api = "0.4.4" +livekit-protocol = "0.7.4" +livekit-runtime = "0.4.0" + +# Other Utilities +once_cell = "1.9.0" +config = "0.13.3" +cached = "0.44.0" +rand = "0.8.5" +base64 = "0.21.3" +decancer = "1.6.2" +linkify = "0.8.1" +url-escape = "0.1.1" +revolt_optional_struct = "0.2.0" +unicode-segmentation = "1.10.1" +querystring = "1.1.0" +tempfile = "3.12.0" +aes-gcm = "0.10.3" +auto_ops = "0.3.0" +url = "2.2.2" +impl_ops = "0.1.1" +lazy_static = "1.5.0" +mime = "0.3.17" + +# Build Dependencies +vergen = "7.5.0" + +# Local packages +revolt-coalesced = { version = "0.12.0", path = "crates/core/coalesced" } +revolt-config = { version = "0.12.0", path = "crates/core/config" } +revolt-database = { version = "0.12.0", path = "crates/core/database" } +revolt-files = { version = "0.12.0", path = "crates/core/files" } +revolt-models = { version = "0.12.0", path = "crates/core/models" } +revolt-parser = { version = "0.12.0", path = "crates/core/parser" } +revolt-permissions = { version = "0.12.0", path = "crates/core/permissions" } +revolt-presence = { version = "0.12.0", path = "crates/core/presence" } +revolt-ratelimits = { version = "0.12.0", path = "crates/core/ratelimits" } +revolt-result = { version = "0.12.0", path = "crates/core/result" } \ No newline at end of file diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index c5f42a476..1e1cc8cab 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -9,42 +9,38 @@ publish = false [dependencies] # util -log = "*" -sentry = "0.31.5" -lru = "0.7.6" -ulid = "0.5.0" -once_cell = "1.9.0" -redis-kiss = "0.1.4" -lru_time_cache = "0.11.11" -async-channel = "2.3.1" +log = { workspace = true } +sentry = { workspace = true } +lru = { workspace = true } +ulid = { workspace = true } +once_cell = { workspace = true } +redis-kiss = { workspace = true } +lru_time_cache = { workspace = true } +async-channel = { workspace = true } # parsing -querystring = "1.1.0" -regex = "1.11.1" +querystring = { workspace = true } +regex = { workspace = true } # serde -bincode = "1.3.3" -serde_json = "1.0.79" -rmp-serde = "1.0.0" -serde = "1.0.136" +bincode = { workspace = true } +serde_json = { workspace = true } +rmp-serde = { workspace = true } +serde = { workspace = true } # async -futures = "0.3.21" -async-tungstenite = { version = "0.17.0", features = ["async-std-runtime"] } -async-std = { version = "1.8.0", features = [ - "tokio1", - "tokio02", - "attributes", -] } +futures = { workspace = true } +async-tungstenite = { workspace = true, features = ["async-std-runtime"] } +async-std = { workspace = true } # core -authifier = { version = "1.0.16" } -revolt-result = { path = "../core/result" } -revolt-models = { path = "../core/models" } -revolt-config = { path = "../core/config" } -revolt-database = { path = "../core/database", features = ["voice"] } -revolt-permissions = { path = "../core/permissions" } -revolt-presence = { path = "../core/presence", features = ["redis-is-patched"] } +authifier = { workspace = true } +revolt-result = { workspace = true } +revolt-models = { workspace = true } +revolt-config = { workspace = true } +revolt-database = { workspace = true, features = ["voice"] } +revolt-permissions = { workspace = true } +revolt-presence = { workspace = true, features = ["redis-is-patched"] } # redis -fred = { version = "8.0.1", features = ["subscriber-client"] } +fred = { workspace = true, features = ["subscriber-client"] } diff --git a/crates/bonfire/src/events/state.rs b/crates/bonfire/src/events/state.rs index eae398019..daa22269a 100644 --- a/crates/bonfire/src/events/state.rs +++ b/crates/bonfire/src/events/state.rs @@ -1,7 +1,5 @@ use std::{ - collections::{HashMap, HashSet}, - sync::Arc, - time::Duration, + collections::{HashMap, HashSet}, num::NonZeroUsize, sync::Arc, time::Duration }; use async_std::sync::{Mutex, RwLock}; @@ -57,7 +55,7 @@ impl Default for Cache { members: Default::default(), servers: Default::default(), - seen_events: LruCache::new(20), + seen_events: LruCache::new(NonZeroUsize::new(20).unwrap()), } } } diff --git a/crates/core/coalesced/Cargo.toml b/crates/core/coalesced/Cargo.toml index 2e770bd72..e6277bd0a 100644 --- a/crates/core/coalesced/Cargo.toml +++ b/crates/core/coalesced/Cargo.toml @@ -15,12 +15,12 @@ cache = ["dep:lru"] default = ["tokio"] [dependencies] -tokio = { version = "1.47.0", features = ["sync"], optional = true } -indexmap = { version = "2.13.0", optional = true } -lru = { version = "0.16.3", optional = true } +tokio = { workspace = true, features = ["sync"], optional = true } +indexmap = { workspace = true, optional = true } +lru = { workspace = true, optional = true } [dev-dependencies] -tokio = { version = "1.47.0", features = [ +tokio = { workspace = true, features = [ "rt", "rt-multi-thread", "macros", diff --git a/crates/core/config/Cargo.toml b/crates/core/config/Cargo.toml index e74cbca40..7b33b5e9a 100644 --- a/crates/core/config/Cargo.toml +++ b/crates/core/config/Cargo.toml @@ -18,24 +18,24 @@ default = ["test", "sentry"] [dependencies] # Utility -config = "0.13.3" -cached = "0.44.0" -once_cell = "1.18.0" +config = { workspace = true } +cached = { workspace = true } +once_cell = { workspace = true } # Serde -serde = { version = "1", features = ["derive"] } +serde = { workspace = true } # Async -futures-locks = "0.7.1" -async-std = { version = "1.8.0", features = ["attributes"], optional = true } +futures-locks = { workspace = true } +async-std = { workspace = true, features = ["attributes"], optional = true } # Logging -log = "0.4.14" -pretty_env_logger = "0.4.0" +log = { workspace = true } +pretty_env_logger = { workspace = true } # Sentry -sentry = { version = "0.31.5", optional = true } -sentry-anyhow = { version = "0.38.1", optional = true } +sentry = { workspace = true, optional = true } +sentry-anyhow = { workspace = true, optional = true } # Core -revolt-result = { version = "0.12.1", path = "../result", optional = true } +revolt-result = { workspace = true, optional = true } diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index fafbccd46..ba5b7d1b9 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -32,80 +32,71 @@ default = ["mongodb", "async-std-runtime", "tasks"] [dependencies] # Core -revolt-config = { version = "0.12.1", path = "../config", features = [ - "report-macros", -] } -revolt-result = { version = "0.12.1", path = "../result" } -revolt-models = { version = "0.12.1", path = "../models", features = [ - "validator", -] } -revolt-presence = { version = "0.12.1", path = "../presence" } -revolt-permissions = { version = "0.12.1", path = "../permissions", features = [ - "serde", - "bson", -] } -revolt-parser = { version = "0.12.1", path = "../parser" } +revolt-config = { workspace = true, features = ["report-macros"] } +revolt-result = { workspace = true } +revolt-models = { workspace = true, features = ["validator"] } +revolt-presence = { workspace = true } +revolt-permissions = { workspace = true, features = ["serde", "bson"] } +revolt-parser = { workspace = true } # Utility -log = "0.4" -lru = "0.11.0" -rand = "0.8.5" -ulid = "1.0.0" -nanoid = "0.4.0" -base64 = "0.21.3" -once_cell = "1.17" -indexmap = "1.9.1" -decancer = "1.6.2" -deadqueue = "0.2.4" -linkify = { optional = true, version = "0.8.1" } -url-escape = { optional = true, version = "0.1.1" } -validator = { version = "0.16", features = ["derive"] } -isahc = { optional = true, version = "1.7", features = ["json"] } +log = { workspace = true } +lru = { workspace = true } +rand = { workspace = true } +ulid = { workspace = true } +nanoid = { workspace = true } +base64 = { workspace = true } +once_cell = { workspace = true } +indexmap = { workspace = true } +decancer = { workspace = true } +deadqueue = { workspace = true } +linkify = { workspace = true, optional = true } +url-escape = { workspace = true, optional = true } +validator = { workspace = true, features = ["derive"] } +isahc = { workspace = true, features = ["json"], optional = true } # Serialisation -serde_json = "1" -revolt_optional_struct = "0.2.0" -serde = { version = "1", features = ["derive"] } -iso8601-timestamp = { version = "0.2.10", features = ["serde", "bson"] } +serde_json = { workspace = true } +revolt_optional_struct = { workspace = true } +serde = { workspace = true } +iso8601-timestamp = { workspace = true, features = ["serde", "bson"] } # Events -redis-kiss = { version = "0.1.4" } +redis-kiss = { workspace = true } # Database -bson = { optional = true, version = "2.1.0" } -mongodb = { optional = true, version = "3.1.0" } +bson = { workspace = true, optional = true } +mongodb = { workspace = true, optional = true } # Database Migration -unicode-segmentation = "1.10.1" -regex = "1" +unicode-segmentation = { workspace = true } +regex = { workspace = true } # Async Language Features -futures = "0.3.19" -async-lock = "2.8.0" -async-trait = "0.1.51" -async-recursion = "1.0.4" +futures = { workspace = true } +async-lock = { workspace = true } +async-trait = { workspace = true } +async-recursion = { workspace = true } # Async -async-std = { version = "1.8.0", features = ["attributes"], optional = true } +async-std = { workspace = true, features = ["attributes"], optional = true } # Axum Impl -axum = { version = "0.7.5", optional = true } +axum = { workspace = true, optional = true } # Rocket Impl -schemars = { version = "0.8.8", optional = true } -rocket = { version = "0.5.1", default-features = false, features = [ - "json", -], optional = true } -revolt_okapi = { version = "0.9.1", optional = true } -revolt_rocket_okapi = { version = "0.10.0", optional = true } +schemars = { workspace = true, optional = true } +rocket = { workspace = true, features = ["json"], optional = true } +revolt_okapi = { workspace = true, optional = true } +revolt_rocket_okapi = { workspace = true, optional = true } # Authifier -authifier = { version = "1.0.16" } +authifier = { workspace = true } # RabbitMQ -amqprs = { version = "1.7.0" } +amqprs = { workspace = true } # Voice -livekit-api = { version = "0.4.4", optional = true } -livekit-protocol = { version = "0.4.0", optional = true } -livekit-runtime = { version = "0.3.1", features = ["tokio"], optional = true } +livekit-api = { workspace = true, optional = true } +livekit-protocol = { workspace = true, optional = true } +livekit-runtime = { workspace = true, features = ["tokio"], optional = true } diff --git a/crates/core/database/src/models/messages/ops/reference.rs b/crates/core/database/src/models/messages/ops/reference.rs index 6f30de6ff..56bf1da9c 100644 --- a/crates/core/database/src/models/messages/ops/reference.rs +++ b/crates/core/database/src/models/messages/ops/reference.rs @@ -249,7 +249,7 @@ impl AbstractMessages for ReferenceDb { let mut messages = self.messages.lock().await; if let Some(message) = messages.get_mut(id) { if let Some(users) = message.reactions.get_mut(emoji) { - users.remove(&user.to_string()); + users.swap_remove(&user.to_string()); } Ok(()) @@ -262,7 +262,7 @@ impl AbstractMessages for ReferenceDb { async fn clear_reaction(&self, id: &str, emoji: &str) -> Result<()> { let mut messages = self.messages.lock().await; if let Some(message) = messages.get_mut(id) { - message.reactions.remove(emoji); + message.reactions.swap_remove(emoji); Ok(()) } else { Err(create_error!(NotFound)) diff --git a/crates/core/files/Cargo.toml b/crates/core/files/Cargo.toml index 926b8c158..9f30649d4 100644 --- a/crates/core/files/Cargo.toml +++ b/crates/core/files/Cargo.toml @@ -16,33 +16,33 @@ tracing = { workspace = true } tokio = { workspace = true } async-trait = { workspace = true } -ffprobe = "0.4.0" -imagesize = "0.13.0" -tempfile = "3.12.0" +ffprobe = { workspace = true } +imagesize = { workspace = true } +tempfile = { workspace = true } -base64 = "0.22.1" -aes-gcm = "0.10.3" -typenum = "1.17.0" +base64 = { workspace = true } +aes-gcm = { workspace = true } +typenum = { workspace = true } -aws-config = "1.5.5" -aws-sdk-s3 = { version = "1.46.0", features = ["behavior-version-latest"] } +aws-config = { workspace = true } +aws-sdk-s3 = { workspace = true, features = ["behavior-version-latest"] } -revolt-config = { version = "0.12.1", path = "../config", features = [ +revolt-config = { workspace = true, features = [ "report-macros", ] } -revolt-result = { version = "0.12.1", path = "../result" } +revolt-result = { workspace = true } # image processing -jxl-oxide = { workspace = true } +jxl-oxide = { workspace = true, features = ["image"] } image = { workspace = true } # svg rendering -usvg = "0.44.0" -resvg = "0.44.0" -tiny-skia = "0.11.4" +usvg = { workspace = true } +resvg = { workspace = true } +tiny-skia = { workspace = true } # encoding -webp = "0.3.0" +webp = { workspace = true } [dev-dependencies] -uuid = { workspace = true } +uuid = { workspace = true, features = ["v4"] } diff --git a/crates/core/models/Cargo.toml b/crates/core/models/Cargo.toml index 34fd5a151..f8a4c6979 100644 --- a/crates/core/models/Cargo.toml +++ b/crates/core/models/Cargo.toml @@ -21,26 +21,26 @@ default = ["serde", "partials", "rocket"] [dependencies] # Core -revolt-config = { version = "0.12.1", path = "../config" } -revolt-permissions = { version = "0.12.1", path = "../permissions" } +revolt-config = { workspace = true } +revolt-permissions = { workspace = true } # Utility -regex = "1.11" -indexmap = "1.9.3" -once_cell = "1.17.1" -num_enum = "0.6.1" +regex = { workspace = true } +indexmap = { workspace = true } +once_cell = { workspace = true } +num_enum = { workspace = true } # Rocket -rocket = { optional = true, version = "0.5.0-rc.2", default-features = false } +rocket = { workspace = true, optional = true } # Serialisation -revolt_optional_struct = { version = "0.2.0", optional = true } -serde = { version = "1", features = ["derive"], optional = true } -iso8601-timestamp = { version = "0.2.11", features = ["schema", "bson"] } +revolt_optional_struct = { workspace = true, optional = true } +serde = { workspace = true, optional = true } +iso8601-timestamp = { workspace = true, features = ["schema", "bson"] } # Spec Generation -schemars = { version = "0.8.8", optional = true, features = ["indexmap1"] } -utoipa = { version = "4.2.3", optional = true } +schemars = { workspace = true, features = ["indexmap2"], optional = true } +utoipa = { workspace = true, optional = true } # Validation -validator = { version = "0.16.0", optional = true, features = ["derive"] } +validator = { workspace = true, features = ["derive"], optional = true } diff --git a/crates/core/parser/Cargo.toml b/crates/core/parser/Cargo.toml index 20d9e8c79..1bc35301c 100644 --- a/crates/core/parser/Cargo.toml +++ b/crates/core/parser/Cargo.toml @@ -8,4 +8,4 @@ description = "Revolt Backend: Message Parser" repository = "https://github.com/stoatchat/stoatchat" [dependencies] -logos = { version = "0.15" } +logos = { workspace = true } diff --git a/crates/core/permissions/Cargo.toml b/crates/core/permissions/Cargo.toml index f351e0593..838b10b29 100644 --- a/crates/core/permissions/Cargo.toml +++ b/crates/core/permissions/Cargo.toml @@ -18,23 +18,23 @@ try-from-primitive = ["dep:num_enum"] [dev-dependencies] # Async -async-std = { version = "1.8.0", features = ["attributes"] } +async-std = { workspace = true, features = ["attributes"] } [dependencies] # Core -revolt-result = { version = "0.12.1", path = "../result" } +revolt-result = { workspace = true } # Utility -auto_ops = "0.3.0" -once_cell = "1.17" -num_enum = { version = "0.6.1", optional = true } +auto_ops = { workspace = true } +once_cell = { workspace = true } +num_enum = { workspace = true, optional = true } # Async -async-trait = "0.1.51" +async-trait = { workspace = true } # Serialisation -serde = { version = "1", features = ["derive"], optional = true } -bson = { version = "2.1.0", optional = true } +serde = { workspace = true, optional = true } +bson = { workspace = true, optional = true } # Spec Generation -schemars = { version = "0.8.8", optional = true } +schemars = { workspace = true, optional = true } diff --git a/crates/core/presence/Cargo.toml b/crates/core/presence/Cargo.toml index 899fef51b..547dcd798 100644 --- a/crates/core/presence/Cargo.toml +++ b/crates/core/presence/Cargo.toml @@ -14,16 +14,16 @@ redis-is-patched = [] [dev-dependencies] # Async -async-std = { version = "1.8.0", features = ["attributes"] } +async-std = { workspace = true, features = ["attributes"] } # Config for loading Redis URI -revolt-config = { version = "0.12.1", path = "../config" } +revolt-config = { workspace = true } [dependencies] # Utility -log = "0.4.17" -rand = "0.8.5" -once_cell = "1.17.1" +log = { workspace = true } +rand = { workspace = true } +once_cell = { workspace = true } # Redis -redis-kiss = "0.1.4" +redis-kiss = { workspace = true } diff --git a/crates/core/ratelimits/Cargo.toml b/crates/core/ratelimits/Cargo.toml index 0bdca6bf8..0e862c808 100644 --- a/crates/core/ratelimits/Cargo.toml +++ b/crates/core/ratelimits/Cargo.toml @@ -18,17 +18,17 @@ axum = ["dep:axum", "revolt-database/axum-impl"] default = ["rocket", "axum"] [dependencies] -revolt-database = { version = "0.12.1", path = "../database" } -revolt-result = { version = "0.12.1", path = "../result" } -revolt-config = { version = "0.12.1", path = "../config" } +revolt-database = { workspace = true } +revolt-result = { workspace = true } +revolt-config = { workspace = true } -rocket = { version = "0.5.1", optional = true } -revolt_rocket_okapi = { version = "0.10.0", optional = true } +rocket = { workspace = true, optional = true } +revolt_rocket_okapi = { workspace = true, optional = true } -axum = { version = "0.7.5", optional = true, features = ["macros"] } +axum = { workspace = true, optional = true, features = ["macros"] } -serde = { version = "1", features = ["derive"] } -authifier = { version = "1.0.16" } -dashmap = "5.2.0" -async-trait = "0.1.81" -log = "0.4" +serde = { workspace = true } +authifier = { workspace = true } +dashmap = { workspace = true } +async-trait = { workspace = true } +log = { workspace = true } diff --git a/crates/core/result/Cargo.toml b/crates/core/result/Cargo.toml index de21e357c..9a1d1c134 100644 --- a/crates/core/result/Cargo.toml +++ b/crates/core/result/Cargo.toml @@ -22,21 +22,21 @@ default = ["serde", "sentry"] [dependencies] # Serialisation -serde_json = { version = "1", optional = true } -serde = { version = "1", features = ["derive"], optional = true } +serde_json = { workspace = true, optional = true } +serde = { workspace = true, optional = true } # Spec Generation -schemars = { version = "0.8.8", optional = true } -utoipa = { version = "4.2.3", optional = true } +schemars = { workspace = true, optional = true } +utoipa = { workspace = true, optional = true } # Rocket -rocket = { optional = true, version = "0.5.0-rc.2", default-features = false } -revolt_rocket_okapi = { version = "0.10.0", optional = true } -revolt_okapi = { version = "0.9.1", optional = true } +rocket = { workspace = true, optional = true } +revolt_rocket_okapi = { workspace = true, optional = true } +revolt_okapi = { workspace = true, optional = true } # utilities -log = "0.4" +log = { workspace = true } # Axum -axum = { version = "0.7.5", optional = true } +axum = { workspace = true, optional = true } -sentry = { version = "0.31.5", optional = true } +sentry = { workspace = true, optional = true } diff --git a/crates/daemons/crond/Cargo.toml b/crates/daemons/crond/Cargo.toml index 570729cd9..fe33d2b75 100644 --- a/crates/daemons/crond/Cargo.toml +++ b/crates/daemons/crond/Cargo.toml @@ -11,13 +11,13 @@ publish = false [dependencies] # Utility -log = "0.4" +log = { workspace = true } # Async -tokio = { version = "1" } +tokio = { workspace = true } # Core -revolt-database = { version = "0.12.1", path = "../../core/database" } -revolt-result = { version = "0.12.1", path = "../../core/result" } -revolt-config = { version = "0.12.1", path = "../../core/config" } -revolt-files = { version = "0.12.1", path = "../../core/files" } +revolt-database = { workspace = true } +revolt-result = { workspace = true } +revolt-config = { workspace = true } +revolt-files = { workspace = true } diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index 2a3d4fc10..b26c80e10 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -6,42 +6,35 @@ license = "AGPL-3.0-or-later" publish = false [dependencies] -revolt-result = { version = "0.12.1", path = "../../core/result" } -revolt-config = { version = "0.12.1", path = "../../core/config", features = [ - "report-macros", - "anyhow", -] } -revolt-database = { version = "0.12.1", path = "../../core/database" } -revolt-models = { version = "0.12.1", path = "../../core/models", features = [ - "validator", -] } -revolt-presence = { version = "0.12.1", path = "../../core/presence", features = [ - "redis-is-patched", -] } -revolt-parser = { version = "0.12.1", path = "../../core/parser" } +revolt-result = { workspace = true } +revolt-config = { workspace = true, features = ["report-macros", "anyhow"] } +revolt-database = { workspace = true } +revolt-models = { workspace = true, features = ["validator"] } +revolt-presence = { workspace = true, features = ["redis-is-patched"] } +revolt-parser = { workspace = true } -anyhow = { version = "1.0.98" } +anyhow = { workspace = true } -amqprs = { version = "1.7.0" } -fcm_v1 = "0.3.0" -web-push = "0.10.0" -isahc = { optional = true, version = "1.7", features = ["json"] } -revolt_a2 = { version = "0.10", default-features = false, features = ["ring"] } -redis-kiss = "0.1.4" -tokio = "1.39.2" -async-trait = "0.1.81" -ulid = "1.0.0" +amqprs = { workspace = true } +fcm_v1 = { workspace = true } +web-push = { workspace = true } +isahc = { workspace = true, features = ["json"], optional = true } +revolt_a2 = { workspace = true, features = ["ring"] } +redis-kiss = { workspace = true } +tokio = { workspace = true } +async-trait = { workspace = true } +ulid = { workspace = true } -authifier = "1.0.16" +authifier = { workspace = true } -log = "0.4.11" -pretty_env_logger = "0.4.0" +log = { workspace = true } +pretty_env_logger = { workspace = true } -regex = "1.12.3" +regex = { workspace = true } #serialization -serde_json = "1" -revolt_optional_struct = "0.2.0" -serde = { version = "1", features = ["derive"] } -iso8601-timestamp = { version = "0.2.10", features = ["serde", "bson"] } -base64 = "0.22.1" +serde_json = { workspace = true } +revolt_optional_struct = { workspace = true } +serde = { workspace = true } +iso8601-timestamp = { workspace = true, features = ["serde", "bson"] } +base64 = { workspace = true } diff --git a/crates/daemons/voice-ingress/Cargo.toml b/crates/daemons/voice-ingress/Cargo.toml index f41e4ec12..b8d15250b 100644 --- a/crates/daemons/voice-ingress/Cargo.toml +++ b/crates/daemons/voice-ingress/Cargo.toml @@ -9,41 +9,41 @@ publish = false [dependencies] # util -log = "*" -sentry = "0.31.5" -lru = "0.7.6" -ulid = "0.5.0" -redis-kiss = "0.1.4" -chrono = "0.4.15" +log = { workspace = true } +sentry = { workspace = true } +lru = { workspace = true } +ulid = { workspace = true } +redis-kiss = { workspace = true } +chrono = { workspace = true } # Serde -serde_json = "1.0.79" -rmp-serde = "1.0.0" -serde = "1.0.136" +serde_json = { workspace = true } +rmp-serde = { workspace = true } +serde = { workspace = true } # Http -rocket = { version = "0.5.0-rc.2", features = ["json"] } -rocket_empty = "0.1.1" +rocket = { workspace = true, features = ["json"] } +rocket_empty = { workspace = true } # Async -futures = "0.3.21" -async-std = { version = "1.8.0", features = [ +futures = { workspace = true } +async-std = { workspace = true, features = [ "tokio1", "tokio02", "attributes", ] } # Core -revolt-result = { path = "../../core/result" } -revolt-models = { path = "../../core/models" } -revolt-config = { path = "../../core/config" } -revolt-database = { path = "../../core/database", features = ["voice"] } -revolt-permissions = { path = "../../core/permissions" } +revolt-result = { workspace = true, features = ["rocket"] } +revolt-models = { workspace = true } +revolt-config = { workspace = true } +revolt-database = { workspace = true, features = ["voice"] } +revolt-permissions = { workspace = true } # Voice -livekit-api = "0.4.4" -livekit-protocol = "0.4.0" -livekit-runtime = { version = "0.3.1", features = ["tokio"] } +livekit-api = { workspace = true } +livekit-protocol = { workspace = true } +livekit-runtime = { workspace = true, features = ["tokio"] } # RabbitMQ -amqprs = { version = "1.7.0" } +amqprs = { workspace = true } diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index 47cd64ac2..2919ff566 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -10,84 +10,83 @@ publish = false [dependencies] # Test -rand = "0.8.5" -redis-kiss = "0.1.4" +rand = { workspace = true } +redis-kiss = { workspace = true } # Utility -lru = "0.7.0" -url = "2.2.2" -log = "0.4.11" -dashmap = "5.2.0" -linkify = "0.6.0" -once_cell = "1.17.1" -env_logger = "0.7.1" +lru = { workspace = true } +url = { workspace = true } +log = { workspace = true } +dashmap = { workspace = true } +linkify = { workspace = true } +once_cell = { workspace = true } # Lang. Utilities -regex = "1" -num_enum = "0.5.1" -impl_ops = "0.1.1" -bitfield = "0.13.2" +regex = { workspace = true } +num_enum = { workspace = true } +impl_ops = { workspace = true } +bitfield = { workspace = true } # ID / key generation -ulid = "0.4.1" -nanoid = "0.4.0" +ulid = { workspace = true } +nanoid = { workspace = true } # serde -serde_json = "1.0.57" -serde = { version = "1.0.115", features = ["derive"] } -validator = { version = "0.16", features = ["derive"] } -iso8601-timestamp = { version = "0.2.11", features = [] } +serde_json = { workspace = true } +serde = { workspace = true } +validator = { workspace = true, features = ["derive"] } +iso8601-timestamp = { workspace = true } # async -futures = "0.3.8" -chrono = "0.4.15" -async-channel = "1.6.1" -reqwest = { version = "0.11.4", features = ["json"] } -async-std = { version = "1.8.0", features = [ +futures = { workspace = true } +chrono = { workspace = true } +async-channel = { workspace = true } +reqwest = { workspace = true, features = ["json"] } +async-std = { workspace = true, features = [ "tokio1", "tokio02", "attributes", ] } # internal util -lettre = "0.10.0-alpha.4" +lettre = { workspace = true } # web -rocket = { version = "0.5.1", default-features = false, features = ["json"] } -rocket_cors = { git = "https://github.com/lawliet89/rocket_cors", rev = "072d90359b23e9b291df6b672c07c93de9c46011" } -rocket_empty = { version = "0.1.1", features = ["schema"] } -rocket_authifier = { version = "1.0.16" } -rocket_prometheus = "0.10.0-rc.3" +rocket = { workspace = true, features = ["json"] } +rocket_cors = { workspace = true } +rocket_empty = { workspace = true, features = ["schema"] } +rocket_authifier = { workspace = true } +rocket_prometheus = { workspace = true } # spec generation -schemars = "0.8.8" -revolt_rocket_okapi = { version = "0.10.0", features = ["swagger"] } +schemars = { workspace = true } +revolt_rocket_okapi = { workspace = true, features = ["swagger"] } # rabbit -amqprs = { version = "1.7.0" } +amqprs = { workspace = true } # core -authifier = "1.0.16" -revolt-config = { path = "../core/config" } -revolt-database = { path = "../core/database", features = [ +authifier = { workspace = true } +revolt-config = { workspace = true } +revolt-database = { workspace = true, features = [ "rocket-impl", "redis-is-patched", "voice", ] } -revolt-models = { path = "../core/models", features = [ +revolt-models = { workspace = true, features = [ "schemas", "validator", "rocket", ] } -revolt-presence = { path = "../core/presence" } -revolt-result = { path = "../core/result", features = ["rocket", "okapi"] } -revolt-permissions = { path = "../core/permissions", features = ["schemas"] } -revolt-ratelimits = { path = "../core/ratelimits", features = ["rocket"] } +revolt-presence = { workspace = true } +revolt-result = { workspace = true, features = ["rocket", "okapi"] } +revolt-permissions = { workspace = true, features = ["schemas"] } +revolt-ratelimits = { workspace = true, features = ["rocket"] } # voice -livekit-api = "0.4.4" -livekit-protocol = "0.4.0" +livekit-api = { workspace = true } +livekit-protocol = { workspace = true } [build-dependencies] -vergen = "7.5.0" +vergen = { workspace = true } diff --git a/crates/delta/src/routes/channels/message_bulk_delete.rs b/crates/delta/src/routes/channels/message_bulk_delete.rs index fdd538ff9..72578ee47 100644 --- a/crates/delta/src/routes/channels/message_bulk_delete.rs +++ b/crates/delta/src/routes/channels/message_bulk_delete.rs @@ -1,4 +1,5 @@ -use chrono::Utc; +use std::time::Duration; + use revolt_database::{ util::{permissions::DatabasePermissionQuery, reference::Reference}, Database, Message, User, @@ -36,10 +37,9 @@ pub async fn bulk_delete_messages( if ulid::Ulid::from_string(id) .map_err(|_| create_error!(InvalidOperation))? .datetime() - .signed_duration_since(Utc::now()) - .num_days() - .abs() - > 7 + .elapsed() + .expect("Time went backwards") + > Duration::from_hours(7 * 24) // 7 days { return Err(create_error!(InvalidOperation)); } diff --git a/crates/delta/src/routes/channels/message_send.rs b/crates/delta/src/routes/channels/message_send.rs index 51dd57136..7406b6058 100644 --- a/crates/delta/src/routes/channels/message_send.rs +++ b/crates/delta/src/routes/channels/message_send.rs @@ -1,4 +1,5 @@ -use chrono::{Duration, Utc}; +use std::time::Duration; + use redis_kiss::{get_connection, redis, AsyncCommands}; use revolt_database::util::permissions::DatabasePermissionQuery; use revolt_database::{ @@ -111,8 +112,12 @@ pub async fn message_send( // Disallow mentions for new users (TRUST-0: <12 hours age) in public servers let allow_mentions = if let Some(server) = query.server_ref() { if server.discoverable { - (Utc::now() - ulid::Ulid::from_string(&user.id).unwrap().datetime()) - >= Duration::hours(12) + (ulid::Ulid::from_string(&user.id) + .unwrap() + .datetime() + .elapsed() + .expect("Time went backwards")) + >= Duration::from_hours(12) } else { true } diff --git a/crates/services/autumn/Cargo.toml b/crates/services/autumn/Cargo.toml index 521d91b72..762c4ee35 100644 --- a/crates/services/autumn/Cargo.toml +++ b/crates/services/autumn/Cargo.toml @@ -7,62 +7,57 @@ publish = false [dependencies] # ID generation -ulid = "1.1.3" -nanoid = "0.4.0" +ulid = { workspace = true } +nanoid = { workspace = true } # Media processing -webp = "0.3.0" -sha2 = "0.10.8" -jxl-oxide = "0.8.1" -kamadak-exif = "0.5.4" +webp = { workspace = true } +sha2 = { workspace = true } +jxl-oxide = { workspace = true } +kamadak-exif = { workspace = true } # revolt_little_exif = "0.5.1" -image = { version = "0.25.2" } # avif encode requires dav1d system library: features = ["avif-native"] -thumbhash = "0.1.0" +image = { workspace = true } +thumbhash = { workspace = true } # File processing -revolt_clamav-client = { version = "0.1.5" } -simdutf8 = { version = "0.1.4", features = ["aarch64_neon"] } +revolt_clamav-client = { workspace = true } +simdutf8 = { workspace = true, features = ["aarch64_neon"] } # Content type processing -infer = "0.16.0" -ffprobe = "0.4.0" -imagesize = "0.13.0" +infer = { workspace = true } +ffprobe = { workspace = true } +imagesize = { workspace = true } # Utility -lazy_static = "1.5.0" -moka = { version = "0.12.8", features = ["future"] } +lazy_static = { workspace = true } +moka = { workspace = true, features = ["future"] } # Serialisation -strum_macros = "0.26.4" -serde_json = "1.0.68" -serde = { version = "1.0", features = ["derive"] } +strum_macros = { workspace = true } +serde_json = { workspace = true } +serde = { workspace = true } # Async runtime -tokio = { version = "1.0", features = ["full"] } +tokio = { workspace = true, features = ["full"] } # Logging -tracing = "0.1" -tracing-subscriber = { version = "0.3", features = ["env-filter"] } +tracing = { workspace = true } +tracing-subscriber = { workspace = true } # Core crates -revolt-files = { version = "0.12.1", path = "../../core/files" } -revolt-config = { version = "0.12.1", path = "../../core/config" } -revolt-database = { version = "0.12.1", path = "../../core/database", features = [ - "axum-impl", -] } -revolt-result = { version = "0.12.1", path = "../../core/result", features = [ - "utoipa", - "axum", -] } -revolt-ratelimits = { version = "0.12.1", path = "../../core/ratelimits", features = ["axum"] } +revolt-files = { workspace = true } +revolt-config = { workspace = true } +revolt-database = { workspace = true, features = ["axum-impl"] } +revolt-result = { workspace = true, features = ["utoipa", "axum"] } +revolt-ratelimits = { workspace = true, features = ["axum"] } # Axum / web server -tempfile = "3.12.0" -axum-macros = "0.4.1" -axum_typed_multipart = "0.12.1" -axum = { version = "0.7.5", features = ["multipart"] } -tower-http = { version = "0.5.2", features = ["cors"] } +tempfile = { workspace = true } +axum-macros = { workspace = true } +axum_typed_multipart = { workspace = true } +axum = { workspace = true, features = ["multipart"] } +tower-http = { workspace = true, features = ["cors"] } # OpenAPI & documentation generation -utoipa-scalar = { version = "0.1.0", features = ["axum"] } -utoipa = { version = "4.2.3", features = ["axum_extras", "ulid"] } +utoipa-scalar = { workspace = true, features = ["axum"] } +utoipa = { workspace = true, features = ["axum_extras", "ulid"] } diff --git a/crates/services/gifbox/Cargo.toml b/crates/services/gifbox/Cargo.toml index ae689d8e9..6e7b467ca 100644 --- a/crates/services/gifbox/Cargo.toml +++ b/crates/services/gifbox/Cargo.toml @@ -7,43 +7,34 @@ publish = false [dependencies] # Serialisation -serde = { version = "1.0", features = ["derive", "rc"] } -serde_json = "1.0.68" +serde = { workspace = true, features = ["rc"] } +serde_json = { workspace = true } # Async runtime -tokio = { version = "1.0", features = ["full"] } +tokio = { workspace = true, features = [] } # Web requests -reqwest = { version = "0.12", features = ["json"] } +reqwest = { workspace = true, features = ["json", "query"] } # Core crates -revolt-config = { version = "0.12.1", path = "../../core/config" } -revolt-models = { version = "0.12.1", path = "../../core/models" } -revolt-result = { version = "0.12.1", path = "../../core/result", features = [ - "utoipa", - "axum", -] } -revolt-coalesced = { version = "0.12.1", path = "../../core/coalesced", features = [ - "queue", -] } -revolt-database = { version = "0.12.1", path = "../../core/database", features = [ - "axum-impl", -] } -revolt-ratelimits = { version = "0.12.1", path = "../../core/ratelimits", features = [ - "axum", -] } +revolt-config = { workspace = true } +revolt-models = { workspace = true } +revolt-result = { workspace = true, features = ["utoipa", "axum"] } +revolt-coalesced = { workspace = true, features = ["queue"] } +revolt-database = { workspace = true, features = ["axum-impl"] } +revolt-ratelimits = { workspace = true, features = ["axum"] } # Axum / web server -axum = { version = "0.7.5" } -axum-extra = { version = "0.9", features = ["typed-header"] } -tower-http = { version = "0.5.2", features = ["cors"] } +axum = { workspace = true } +axum-extra = { workspace = true, features = ["typed-header"] } +tower-http = { workspace = true, features = ["cors"] } # OpenAPI & documentation generation -utoipa-scalar = { version = "0.1.0", features = ["axum"] } -utoipa = { version = "4.2.3", features = ["axum_extras", "ulid"] } +utoipa-scalar = { workspace = true, features = ["axum"] } +utoipa = { workspace = true, features = ["axum_extras", "ulid"] } # Logging -tracing = "0.1" +tracing = { workspace = true } # Utils -lru_time_cache = "0.11.11" +lru_time_cache = { workspace = true } diff --git a/crates/services/january/Cargo.toml b/crates/services/january/Cargo.toml index b2bc30e62..78ec07ad0 100644 --- a/crates/services/january/Cargo.toml +++ b/crates/services/january/Cargo.toml @@ -7,44 +7,41 @@ publish = false [dependencies] # Utility -mime = "0.3.17" -regex = "1.11.0" -tempfile = "3.13.0" -lazy_static = "1.5.0" -moka = { version = "0.12.8", features = ["future"] } +mime = { workspace = true } +regex = { workspace = true } +tempfile = { workspace = true } +lazy_static = { workspace = true } +moka = { workspace = true, features = ["future"] } # Web scraping -scraper = "0.20.0" -encoding_rs = "0.8.34" +scraper = { workspace = true } +encoding_rs = { workspace = true } # Serialisation -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0.68" +serde = { workspace = true } +serde_json = { workspace = true } # Async runtime -async-recursion = "1.1.1" -tokio = { version = "1.0", features = ["full"] } +async-recursion = { workspace = true } +tokio = { workspace = true, features = [] } # Web requests -reqwest = { version = "0.12", features = ["json"] } +reqwest = { workspace = true, features = ["json"] } # Logging -tracing = "0.1" -tracing-subscriber = { version = "0.3", features = ["env-filter"] } +tracing = { workspace = true } +tracing-subscriber = { workspace = true, features = ["env-filter"] } # Core crates -revolt-config = { version = "0.12.1", path = "../../core/config" } -revolt-models = { version = "0.12.1", path = "../../core/models" } -revolt-result = { version = "0.12.1", path = "../../core/result", features = [ - "utoipa", - "axum", -] } -revolt-files = { version = "0.12.1", path = "../../core/files" } +revolt-config = { workspace = true } +revolt-models = { workspace = true } +revolt-result = { workspace = true, features = ["utoipa", "axum"] } +revolt-files = { workspace = true } # Axum / web server -axum = { version = "0.7.5" } -axum-extra = { version = "0.9", features = ["typed-header"] } +axum = { workspace = true } +axum-extra = { workspace = true, features = ["typed-header"] } # OpenAPI & documentation generation -utoipa-scalar = { version = "0.1.0", features = ["axum"] } -utoipa = { version = "4.2.3", features = ["axum_extras", "ulid"] } +utoipa-scalar = { workspace = true, features = ["axum"] } +utoipa = { workspace = true, features = ["axum_extras", "ulid"] } diff --git a/release-please-config.json b/release-please-config.json index 14710a302..f43b09c30 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -30,76 +30,21 @@ "path": "crates/core/config/Cargo.toml", "jsonpath": "$.package.version" }, - { - "type": "toml", - "path": "crates/core/config/Cargo.toml", - "jsonpath": "$.dependencies['revolt-result'].version" - }, { "type": "toml", "path": "crates/core/database/Cargo.toml", "jsonpath": "$.package.version" }, - { - "type": "toml", - "path": "crates/core/database/Cargo.toml", - "jsonpath": "$.dependencies['revolt-config'].version" - }, - { - "type": "toml", - "path": "crates/core/database/Cargo.toml", - "jsonpath": "$.dependencies['revolt-result'].version" - }, - { - "type": "toml", - "path": "crates/core/database/Cargo.toml", - "jsonpath": "$.dependencies['revolt-models'].version" - }, - { - "type": "toml", - "path": "crates/core/database/Cargo.toml", - "jsonpath": "$.dependencies['revolt-presence'].version" - }, - { - "type": "toml", - "path": "crates/core/database/Cargo.toml", - "jsonpath": "$.dependencies['revolt-permissions'].version" - }, - { - "type": "toml", - "path": "crates/core/database/Cargo.toml", - "jsonpath": "$.dependencies['revolt-parser'].version" - }, { "type": "toml", "path": "crates/core/files/Cargo.toml", "jsonpath": "$.package.version" }, - { - "type": "toml", - "path": "crates/core/files/Cargo.toml", - "jsonpath": "$.dependencies['revolt-config'].version" - }, - { - "type": "toml", - "path": "crates/core/files/Cargo.toml", - "jsonpath": "$.dependencies['revolt-result'].version" - }, { "type": "toml", "path": "crates/core/models/Cargo.toml", "jsonpath": "$.package.version" }, - { - "type": "toml", - "path": "crates/core/models/Cargo.toml", - "jsonpath": "$.dependencies['revolt-config'].version" - }, - { - "type": "toml", - "path": "crates/core/models/Cargo.toml", - "jsonpath": "$.dependencies['revolt-permissions'].version" - }, { "type": "toml", "path": "crates/core/parser/Cargo.toml", @@ -110,41 +55,16 @@ "path": "crates/core/permissions/Cargo.toml", "jsonpath": "$.package.version" }, - { - "type": "toml", - "path": "crates/core/permissions/Cargo.toml", - "jsonpath": "$.dependencies['revolt-result'].version" - }, { "type": "toml", "path": "crates/core/presence/Cargo.toml", "jsonpath": "$.package.version" }, - { - "type": "toml", - "path": "crates/core/presence/Cargo.toml", - "jsonpath": "$['dev-dependencies']['revolt-config'].version" - }, { "type": "toml", "path": "crates/core/ratelimits/Cargo.toml", "jsonpath": "$.package.version" }, - { - "type": "toml", - "path": "crates/core/ratelimits/Cargo.toml", - "jsonpath": "$.dependencies['revolt-database'].version" - }, - { - "type": "toml", - "path": "crates/core/ratelimits/Cargo.toml", - "jsonpath": "$.dependencies['revolt-result'].version" - }, - { - "type": "toml", - "path": "crates/core/ratelimits/Cargo.toml", - "jsonpath": "$.dependencies['revolt-config'].version" - }, { "type": "toml", "path": "crates/core/result/Cargo.toml", @@ -155,61 +75,11 @@ "path": "crates/daemons/crond/Cargo.toml", "jsonpath": "$.package.version" }, - { - "type": "toml", - "path": "crates/daemons/crond/Cargo.toml", - "jsonpath": "$.dependencies['revolt-database'].version" - }, - { - "type": "toml", - "path": "crates/daemons/crond/Cargo.toml", - "jsonpath": "$.dependencies['revolt-result'].version" - }, - { - "type": "toml", - "path": "crates/daemons/crond/Cargo.toml", - "jsonpath": "$.dependencies['revolt-config'].version" - }, - { - "type": "toml", - "path": "crates/daemons/crond/Cargo.toml", - "jsonpath": "$.dependencies['revolt-files'].version" - }, { "type": "toml", "path": "crates/daemons/pushd/Cargo.toml", "jsonpath": "$.package.version" }, - { - "type": "toml", - "path": "crates/daemons/pushd/Cargo.toml", - "jsonpath": "$.dependencies['revolt-result'].version" - }, - { - "type": "toml", - "path": "crates/daemons/pushd/Cargo.toml", - "jsonpath": "$.dependencies['revolt-config'].version" - }, - { - "type": "toml", - "path": "crates/daemons/pushd/Cargo.toml", - "jsonpath": "$.dependencies['revolt-database'].version" - }, - { - "type": "toml", - "path": "crates/daemons/pushd/Cargo.toml", - "jsonpath": "$.dependencies['revolt-models'].version" - }, - { - "type": "toml", - "path": "crates/daemons/pushd/Cargo.toml", - "jsonpath": "$.dependencies['revolt-presence'].version" - }, - { - "type": "toml", - "path": "crates/daemons/pushd/Cargo.toml", - "jsonpath": "$.dependencies['revolt-parser'].version" - }, { "type": "toml", "path": "crates/daemons/voice-ingress/Cargo.toml", @@ -220,31 +90,6 @@ "path": "crates/services/autumn/Cargo.toml", "jsonpath": "$.package.version" }, - { - "type": "toml", - "path": "crates/services/autumn/Cargo.toml", - "jsonpath": "$.dependencies['revolt-files'].version" - }, - { - "type": "toml", - "path": "crates/services/autumn/Cargo.toml", - "jsonpath": "$.dependencies['revolt-config'].version" - }, - { - "type": "toml", - "path": "crates/services/autumn/Cargo.toml", - "jsonpath": "$.dependencies['revolt-database'].version" - }, - { - "type": "toml", - "path": "crates/services/autumn/Cargo.toml", - "jsonpath": "$.dependencies['revolt-result'].version" - }, - { - "type": "toml", - "path": "crates/services/autumn/Cargo.toml", - "jsonpath": "$.dependencies['revolt-ratelimits'].version" - }, { "type": "toml", "path": "crates/services/gifbox/Cargo.toml", @@ -252,58 +97,58 @@ }, { "type": "toml", - "path": "crates/services/gifbox/Cargo.toml", - "jsonpath": "$.dependencies['revolt-config'].version" + "path": "crates/services/january/Cargo.toml", + "jsonpath": "$.package.version" }, { "type": "toml", - "path": "crates/services/gifbox/Cargo.toml", - "jsonpath": "$.dependencies['revolt-models'].version" + "path": "Cargo.toml", + "jsonpath": "$.workspace.dependencies['revolt-coalesced'].version" }, { "type": "toml", - "path": "crates/services/gifbox/Cargo.toml", - "jsonpath": "$.dependencies['revolt-result'].version" + "path": "Cargo.toml", + "jsonpath": "$.workspace.dependencies['revolt-config'].version" }, { "type": "toml", - "path": "crates/services/gifbox/Cargo.toml", - "jsonpath": "$.dependencies['revolt-coalesced'].version" + "path": "Cargo.toml", + "jsonpath": "$.workspace.dependencies['revolt-database'].version" }, { "type": "toml", - "path": "crates/services/gifbox/Cargo.toml", - "jsonpath": "$.dependencies['revolt-database'].version" + "path": "Cargo.toml", + "jsonpath": "$.workspace.dependencies['revolt-files'].version" }, { "type": "toml", - "path": "crates/services/gifbox/Cargo.toml", - "jsonpath": "$.dependencies['revolt-ratelimits'].version" + "path": "Cargo.toml", + "jsonpath": "$.workspace.dependencies['revolt-models'].version" }, { "type": "toml", - "path": "crates/services/january/Cargo.toml", - "jsonpath": "$.package.version" + "path": "Cargo.toml", + "jsonpath": "$.workspace.dependencies['revolt-parser'].version" }, { "type": "toml", - "path": "crates/services/january/Cargo.toml", - "jsonpath": "$.dependencies['revolt-config'].version" + "path": "Cargo.toml", + "jsonpath": "$.workspace.dependencies['revolt-permissions'].version" }, { "type": "toml", - "path": "crates/services/january/Cargo.toml", - "jsonpath": "$.dependencies['revolt-models'].version" + "path": "Cargo.toml", + "jsonpath": "$.workspace.dependencies['revolt-presence'].version" }, { "type": "toml", - "path": "crates/services/january/Cargo.toml", - "jsonpath": "$.dependencies['revolt-result'].version" + "path": "Cargo.toml", + "jsonpath": "$.workspace.dependencies['revolt-ratelimits'].version" }, { "type": "toml", - "path": "crates/services/january/Cargo.toml", - "jsonpath": "$.dependencies['revolt-files'].version" + "path": "Cargo.toml", + "jsonpath": "$.workspace.dependencies['revolt-result'].version" } ] } From 057f2bb8b359f8b942741a30ff54eeb8fbe3e0b1 Mon Sep 17 00:00:00 2001 From: Infiland <88491175+Infiland@users.noreply.github.com> Date: Sat, 18 Apr 2026 05:15:54 +0200 Subject: [PATCH 146/211] fix: add reconnection policy to Redis subscriber to prevent ghost state (#708) * fix: add reconnection policy to Redis subscriber to prevent ghost state - Add ReconnectPolicy::new_exponential(0, 100, 30_000, 2) to the subscriber builder, unlimited retries with exponential backoff (100ms min, 30s max) - Add on_reconnect handler that signals the listener loop to force a subscription reset, re-subscribing to all topics on the new connection - Add warn-level logging to on_error for all Redis subscriber errors (previously only Canceled was handled, others were silently ignored) Signed-off-by: Infiland * Update websocket.rs Signed-off-by: Infiland <88491175+Infiland@users.noreply.github.com> * Auto-manage subscriptions on reconnect Call subscriber.manage_subscriptions() so the subscriber will automatically re-subscribe tracked channels after a Redis reconnect. Remove the manual reconnect channel and on_reconnect handler along with the select branch that forced SubscriptionStateChange::Reset. Signed-off-by: Infiland <88491175+Infiland@users.noreply.github.com> --------- Signed-off-by: Infiland Signed-off-by: Infiland <88491175+Infiland@users.noreply.github.com> --- crates/bonfire/src/websocket.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/crates/bonfire/src/websocket.rs b/crates/bonfire/src/websocket.rs index ec4202dc4..b5611bd05 100644 --- a/crates/bonfire/src/websocket.rs +++ b/crates/bonfire/src/websocket.rs @@ -5,7 +5,7 @@ use authifier::AuthifierEvent; use fred::{ error::RedisErrorKind, interfaces::{ClientLike, EventInterface, PubsubInterface}, - types::RedisConfig, + types::{ReconnectPolicy, RedisConfig}, }; use futures::{ channel::oneshot, @@ -225,9 +225,9 @@ async fn listener( .unwrap_or(REDIS_URI.to_string()); let redis_config = RedisConfig::from_url(&url).unwrap(); - let subscriber = match report_internal_error!( - fred::types::Builder::from_config(redis_config).build_subscriber_client() - ) { + let mut builder = fred::types::Builder::from_config(redis_config); + builder.set_policy(ReconnectPolicy::new_exponential(8, 100, 30_000, 2)); + let subscriber = match report_internal_error!(builder.build_subscriber_client()) { Ok(subscriber) => subscriber, Err(_) => return, }; @@ -236,16 +236,21 @@ async fn listener( return; } + // Let Fred automatically re-subscribe to tracked channels on reconnect. + subscriber.manage_subscriptions(); + // Handle Redis connection dropping let (clean_up_s, clean_up_r) = async_channel::bounded(1); let clean_up_s = Arc::new(Mutex::new(clean_up_s)); subscriber.on_error(move |err| { + warn!("Redis subscriber error: {:?}", err); if let RedisErrorKind::Canceled = err.kind() { let clean_up_s = clean_up_s.clone(); spawn(async move { clean_up_s.lock().await.send(()).await.ok(); }); } + // Transient errors (IO, timeout) are handled by the reconnect policy. Ok(()) }); @@ -522,4 +527,4 @@ async fn worker( } } } -} +} \ No newline at end of file From 89171e9bd0f15711157e78c6eec0fe7b480de93a Mon Sep 17 00:00:00 2001 From: Angelo Kontaxis Date: Thu, 23 Apr 2026 07:48:26 +0100 Subject: [PATCH 147/211] fix: dont send notification in fcm (#721) * fix: dont send notification in fcm Signed-off-by: Zomatree * fix: add notification type to fcm Signed-off-by: Zomatree * fix: switch to structured notification data Signed-off-by: Zomatree --------- Signed-off-by: Zomatree --- .../pushd/src/consumers/outbound/fcm.rs | 183 ++++++++++++------ 1 file changed, 129 insertions(+), 54 deletions(-) diff --git a/crates/daemons/pushd/src/consumers/outbound/fcm.rs b/crates/daemons/pushd/src/consumers/outbound/fcm.rs index 196a9eeac..9ff70fc82 100644 --- a/crates/daemons/pushd/src/consumers/outbound/fcm.rs +++ b/crates/daemons/pushd/src/consumers/outbound/fcm.rs @@ -5,9 +5,8 @@ use amqprs::{channel::Channel as AmqpChannel, consumer::AsyncConsumer, BasicProp use anyhow::{anyhow, bail, Result}; use async_trait::async_trait; use fcm_v1::{ - android::{AndroidConfig, AndroidMessagePriority}, auth::{Authenticator, ServiceAccountKey}, - message::{Message, Notification}, + message::Message, Client, Error as FcmError, }; use revolt_config::config; @@ -15,6 +14,102 @@ use revolt_database::{events::rabbit::*, Database}; use revolt_models::v0::{Channel, PushNotification}; use serde_json::Value; +/// Custom notification data +#[derive(Debug, Clone, PartialEq)] +pub enum NotificationData { + FRReceived { + id: String, + username: String, + }, + FRAccepted { + id: String, + username: String, + }, + Generic { + title: String, + body: String, + image: Option, + }, + Message { + title: String, + body: String, + image: String, + tag: String, + }, + DmCallStartEnd { + initiator_id: String, + channel_id: String, + started_at: String, + ended: bool, + duration: usize, + }, +} + +impl NotificationData { + pub fn get_type(&self) -> &str { + match self { + NotificationData::FRReceived { .. } => "push.fr.receive", + NotificationData::FRAccepted { .. } => "push.fr.accept", + NotificationData::Generic { .. } => "push.generic", + NotificationData::Message { .. } => "push.message", + NotificationData::DmCallStartEnd { .. } => "push.dm.call", + } + } + + pub fn into_payload(self) -> HashMap { + let mut data = HashMap::new(); + data.insert( + "type".to_string(), + Value::String(self.get_type().to_string()), + ); + + match self { + NotificationData::FRReceived { id, username } => { + data.insert("id".to_string(), Value::String(id)); + data.insert("username".to_string(), Value::String(username)); + } + NotificationData::FRAccepted { id, username } => { + data.insert("id".to_string(), Value::String(id)); + data.insert("username".to_string(), Value::String(username)); + } + NotificationData::Generic { title, body, image } => { + data.insert("title".to_string(), Value::String(title)); + data.insert("body".to_string(), Value::String(body)); + + if let Some(image) = image { + data.insert("image".to_string(), Value::String(image)); + } + } + NotificationData::Message { + title, + body, + image, + tag, + } => { + data.insert("title".to_string(), Value::String(title)); + data.insert("body".to_string(), Value::String(body)); + data.insert("image".to_string(), Value::String(image)); + data.insert("tag".to_string(), Value::String(tag)); + } + NotificationData::DmCallStartEnd { + initiator_id, + channel_id, + started_at, + ended, + duration, + } => { + data.insert("initiator_id".to_string(), Value::String(initiator_id)); + data.insert("channel_id".to_string(), Value::String(channel_id)); + data.insert("started_at".to_string(), Value::String(started_at)); + data.insert("ended".to_string(), Value::Bool(ended)); + data.insert("duration".to_string(), Value::Number(duration.into())); + } + } + + data + } +} + pub struct FcmOutboundConsumer { db: Database, client: Client, @@ -93,17 +188,14 @@ impl FcmOutboundConsumer { .clone() .ok_or_else(|| anyhow!("missing name"))?; - let mut data = HashMap::new(); - data.insert( - "type".to_string(), - Value::String("push.fr.receive".to_string()), - ); - data.insert("id".to_string(), Value::String(alert.from_user.id)); - data.insert("username".to_string(), Value::String(name)); + let data = NotificationData::FRReceived { + id: alert.from_user.id, + username: name, + }; let msg = Message { token: Some(payload.token), - data: Some(data), + data: Some(data.into_payload()), ..Default::default() }; @@ -121,30 +213,29 @@ impl FcmOutboundConsumer { .clone() .ok_or_else(|| anyhow!("missing name"))?; - let mut data: HashMap = HashMap::new(); - data.insert( - "type".to_string(), - Value::String("push.fr.accept".to_string()), - ); - data.insert("id".to_string(), Value::String(alert.accepted_user.id)); - data.insert("username".to_string(), Value::String(name)); + let data = NotificationData::FRAccepted { + id: alert.accepted_user.id, + username: name, + }; let msg = Message { token: Some(payload.token), - data: Some(data), + data: Some(data.into_payload()), ..Default::default() }; resp = self.client.send(&msg).await; } PayloadKind::Generic(alert) => { + let data = NotificationData::Generic { + title: alert.title, + body: alert.body, + image: alert.icon, + }; + let msg = Message { token: Some(payload.token), - notification: Some(Notification { - title: Some(alert.title), - body: Some(alert.body), - image: alert.icon, - }), + data: Some(data.into_payload()), ..Default::default() }; @@ -152,19 +243,16 @@ impl FcmOutboundConsumer { } PayloadKind::MessageNotification(alert) => { - let title = self.format_title(&alert); + let data = NotificationData::Message { + title: self.format_title(&alert), + body: alert.body, + image: alert.icon, + tag: alert.tag, + }; let msg = Message { token: Some(payload.token), - notification: Some(Notification { - title: Some(title), - body: Some(alert.body), - image: Some(alert.icon), - }), - android: Some(AndroidConfig { - collapse_key: Some(alert.tag), - ..Default::default() - }), + data: Some(data.into_payload()), ..Default::default() }; @@ -172,30 +260,17 @@ impl FcmOutboundConsumer { } PayloadKind::DmCallStartEnd(alert) => { - let mut data: HashMap = HashMap::new(); - data.insert( - "initiator_id".to_string(), - Value::String(alert.initiator_id), - ); - data.insert("channel_id".to_string(), Value::String(alert.channel_id)); - data.insert( - "started_at".to_string(), - Value::String(alert.started_at.unwrap_or_else(|| "".to_string())), - ); - data.insert("ended".to_string(), Value::Bool(alert.ended)); + let data = NotificationData::DmCallStartEnd { + initiator_id: alert.initiator_id, + channel_id: alert.channel_id, + started_at: alert.started_at.unwrap_or_else(|| "".to_string()), + ended: alert.ended, + duration: config().await.api.livekit.call_ring_duration, + }; let msg = Message { token: Some(payload.token), - notification: None, - data: Some(data), - android: Some(AndroidConfig { - priority: Some(AndroidMessagePriority::High), - ttl: Some(format!( - "{}s", - config().await.api.livekit.call_ring_duration - )), - ..Default::default() - }), + data: Some(data.into_payload()), ..Default::default() }; From ed4fd5ebfe6d0ea534a0898da4afdc1f4e2cd6c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0spik?= Date: Fri, 24 Apr 2026 06:39:13 +0300 Subject: [PATCH 148/211] fix: update message length validation to remove upper limit (#723) Signed-off-by: ispik --- crates/core/models/src/v0/messages.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/core/models/src/v0/messages.rs b/crates/core/models/src/v0/messages.rs index 2b03d2114..cb8f3f246 100644 --- a/crates/core/models/src/v0/messages.rs +++ b/crates/core/models/src/v0/messages.rs @@ -261,7 +261,7 @@ auto_derived!( pub nonce: Option, /// Message content to send - #[cfg_attr(feature = "validator", validate(length(min = 0, max = 2000)))] + #[cfg_attr(feature = "validator", validate(length(min = 0)))] pub content: Option, /// Attachments to include in message pub attachments: Option>, @@ -345,7 +345,7 @@ auto_derived!( #[cfg_attr(feature = "validator", derive(Validate))] pub struct DataEditMessage { /// New message content - #[cfg_attr(feature = "validator", validate(length(min = 1, max = 2000)))] + #[cfg_attr(feature = "validator", validate(length(min = 1)))] pub content: Option, /// Embeds to include in the message #[cfg_attr(feature = "validator", validate(length(min = 0, max = 10)))] From e93769786c7669485a659ee471630740d3cea702 Mon Sep 17 00:00:00 2001 From: jarvarvarvis <53998846+jarvarvarvis@users.noreply.github.com> Date: Fri, 24 Apr 2026 04:02:28 +0000 Subject: [PATCH 149/211] feat: automatically sanitise usernames on create/update (#689) * feat: automatically sanitise usernames on create/update Signed-off-by: higgs01 <6546697+higgs01@users.noreply.github.com> * test: add tests for validation and sanitasion Signed-off-by: higgs01 <6546697+higgs01@users.noreply.github.com> * fix: Return only the sanitised string in sanitise_username (#424) * fix: Use as_str for role.id in insert_role * Run rustfmt for code changes Signed-off-by: jarvarvarvis * feat: Make minimum username length configurable in Revolt.toml (#424) * fix: Remove redundant call to is_match with blocked username regex Signed-off-by: jarvarvarvis * Update crates/core/database/src/models/users/model.rs Co-authored-by: Tom Signed-off-by: jarvarvarvis <53998846+jarvarvarvis@users.noreply.github.com> * Update crates/core/database/src/models/users/model.rs Co-authored-by: Tom Signed-off-by: jarvarvarvis <53998846+jarvarvarvis@users.noreply.github.com> * Update crates/core/database/src/models/users/model.rs Co-authored-by: Tom Signed-off-by: jarvarvarvis <53998846+jarvarvarvis@users.noreply.github.com> * Update crates/core/database/src/models/users/model.rs Co-authored-by: Tom Signed-off-by: jarvarvarvis <53998846+jarvarvarvis@users.noreply.github.com> * fix: Implement suggested changes and clean up last 4 commits Signed-off-by: jarvarvarvis * fix: Disallow stoat as username, update create_user test Signed-off-by: jarvarvarvis * fix: Use sanitised username to find updated discriminator Signed-off-by: jarvarvarvis * feat: Sanitise revolt.chat in username Signed-off-by: jarvarvarvis * fix: Implement discussed changes Signed-off-by: jarvarvarvis * test: Fix create_user test Signed-off-by: jarvarvarvis * fix: don't overflow the stack not entirely sure why this fixes it and I don't like it. But work it does. Signed-off-by: IAmTomahawkx * fix: revert odd file mode change Signed-off-by: jarvarvarvis --------- Signed-off-by: higgs01 <6546697+higgs01@users.noreply.github.com> Signed-off-by: jarvarvarvis Signed-off-by: jarvarvarvis <53998846+jarvarvarvis@users.noreply.github.com> Signed-off-by: IAmTomahawkx Co-authored-by: higgs01 <6546697+higgs01@users.noreply.github.com> Co-authored-by: Tom --- Cargo.lock | 8 +- Cargo.toml | 4 +- crates/core/config/Revolt.toml | 2 + crates/core/config/src/lib.rs | 1 + .../src/models/servers/ops/mongodb.rs | 2 +- .../core/database/src/models/users/model.rs | 189 ++++++++++++++---- 6 files changed, 166 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7322d38f2..ce648f79b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2113,9 +2113,13 @@ dependencies = [ [[package]] name = "decancer" -version = "1.6.5" +version = "3.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080b09f6adad25c23d8c47c54e52e59b0dc09d079c4b23e0f147dac440359d0d" +checksum = "a9244323129647178bf41ac861a2cdb9d9c81b9b09d3d0d1de9cd302b33b8a1d" +dependencies = [ + "lazy_static", + "regex", +] [[package]] name = "der" diff --git a/Cargo.toml b/Cargo.toml index 23b4ceb00..f10bfb261 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -171,7 +171,7 @@ config = "0.13.3" cached = "0.44.0" rand = "0.8.5" base64 = "0.21.3" -decancer = "1.6.2" +decancer = "3.3.3" linkify = "0.8.1" url-escape = "0.1.1" revolt_optional_struct = "0.2.0" @@ -198,4 +198,4 @@ revolt-parser = { version = "0.12.0", path = "crates/core/parser" } revolt-permissions = { version = "0.12.0", path = "crates/core/permissions" } revolt-presence = { version = "0.12.0", path = "crates/core/presence" } revolt-ratelimits = { version = "0.12.0", path = "crates/core/ratelimits" } -revolt-result = { version = "0.12.0", path = "crates/core/result" } \ No newline at end of file +revolt-result = { version = "0.12.0", path = "crates/core/result" } diff --git a/crates/core/config/Revolt.toml b/crates/core/config/Revolt.toml index 3bb331118..30a4622ef 100644 --- a/crates/core/config/Revolt.toml +++ b/crates/core/config/Revolt.toml @@ -78,6 +78,8 @@ call_ring_duration = 30 [api.livekit.nodes] [api.users] +# Minimum allowed length of usernames +min_username_length = 2 [pushd] # this changes the names of the queues to not overlap diff --git a/crates/core/config/src/lib.rs b/crates/core/config/src/lib.rs index b9e60a4f8..a49b1cdf4 100644 --- a/crates/core/config/src/lib.rs +++ b/crates/core/config/src/lib.rs @@ -231,6 +231,7 @@ pub struct LiveKitNode { #[derive(Deserialize, Debug, Clone)] pub struct ApiUsers { pub early_adopter_cutoff: Option, + pub min_username_length: usize, } #[derive(Deserialize, Debug, Clone)] diff --git a/crates/core/database/src/models/servers/ops/mongodb.rs b/crates/core/database/src/models/servers/ops/mongodb.rs index ecdff53bf..d8ef26f2a 100644 --- a/crates/core/database/src/models/servers/ops/mongodb.rs +++ b/crates/core/database/src/models/servers/ops/mongodb.rs @@ -77,7 +77,7 @@ impl AbstractServers for MongoDb { }, doc! { "$set": { - "roles.".to_owned() + &role.id: to_document(role) + "roles.".to_owned() + role.id.as_str(): to_document(role) .map_err(|_| create_database_error!("to_document", "role"))? } }, diff --git a/crates/core/database/src/models/users/model.rs b/crates/core/database/src/models/users/model.rs index 0c2b6cee8..bea37fac0 100644 --- a/crates/core/database/src/models/users/model.rs +++ b/crates/core/database/src/models/users/model.rs @@ -7,6 +7,7 @@ use futures::future::join_all; use iso8601_timestamp::Timestamp; use once_cell::sync::Lazy; use rand::seq::SliceRandom; +use regex::{Regex, RegexBuilder}; use revolt_config::{config, FeaturesLimits}; use revolt_models::v0::{self, UserBadges, UserFlags}; use revolt_presence::filter_online; @@ -163,6 +164,13 @@ pub static DISCRIMINATOR_SEARCH_SPACE: Lazy> = Lazy::new(|| { set.into_iter().collect() }); +static BLOCKED_USERNAME_PATTERNS: Lazy = Lazy::new(|| { + RegexBuilder::new("`{3}|(discord|rvlt|guilded|stt)\\.gg|(revolt|stoat)\\.chat|https?:\\/\\/") + .case_insensitive(true) + .build() + .unwrap() +}); + #[allow(clippy::derivable_impls)] impl Default for User { fn default() -> Self { @@ -198,11 +206,13 @@ impl User { I: Into>, D: Into>, { - let username = User::validate_username(username)?; + let new_username = User::sanitise_username(&username).await?; + User::validate_username(&new_username)?; + let mut user = User { id: account_id.into().unwrap_or_else(|| Ulid::new().to_string()), - discriminator: User::find_discriminator(db, &username, None).await?, - username, + discriminator: User::find_discriminator(db, &new_username, None).await?, + username: new_username.clone(), last_acknowledged_policy_change: Timestamp::now_utc(), ..Default::default() }; @@ -278,39 +288,40 @@ impl User { } } - /// Sanitise and validate a username can be used - pub fn validate_username(username: String) -> Result { - // Copy the username for validation + /// Validate a username + /// + /// This will check if the username is a blocked name or contains a blocked pattern. + fn validate_username(username: &str) -> Result<()> { let username_lowercase = username.to_lowercase(); - // Block homoglyphs - if decancer::cure(&username_lowercase).into_str() != username_lowercase { + const BLOCKED_USERNAMES: &[&str] = &["admin", "revolt", "stoat"]; + + if BLOCKED_USERNAMES.contains(&username_lowercase.as_str()) + || BLOCKED_USERNAME_PATTERNS.is_match(username) + { return Err(create_error!(InvalidUsername)); } - // Ensure the username itself isn't blocked - const BLOCKED_USERNAMES: &[&str] = &["admin", "revolt"]; - - for username in BLOCKED_USERNAMES { - if username_lowercase == *username { - return Err(create_error!(InvalidUsername)); - } - } + Ok(()) + } - // Ensure none of the following substrings show up in the username - const BLOCKED_SUBSTRINGS: &[&str] = &[ - "```", - "discord.gg", - "rvlt.gg", - "guilded.gg", - "https://", - "http://", - ]; - - for substr in BLOCKED_SUBSTRINGS { - if username_lowercase.contains(substr) { - return Err(create_error!(InvalidUsername)); - } + /// Sanitise a username + /// + /// This will clean up Unicode homoglyphs and pad to the min username length with underscores. + async fn sanitise_username(username: &str) -> Result { + let options = decancer::Options::default().retain_capitalization(); + let mut username = decancer::cure(username, options) + .map_err(|_| create_error!(InvalidUsername))? + .to_string(); + + let config = revolt_config::config().await; + let username_length_diff = config + .api + .users + .min_username_length + .saturating_sub(username.len()); + if username_length_diff > 0 { + username.push_str(&"_".repeat(username_length_diff)) } Ok(username) @@ -416,12 +427,14 @@ impl User { /// Update a user's username pub async fn update_username(&mut self, db: &Database, username: String) -> Result<()> { - let username = User::validate_username(username)?; - if self.username.to_lowercase() == username.to_lowercase() { + let new_username = User::sanitise_username(&username).await?; + User::validate_username(&new_username)?; + + if self.username.to_lowercase() == new_username.to_lowercase() { self.update( db, PartialUser { - username: Some(username), + username: Some(new_username), ..Default::default() }, vec![], @@ -434,12 +447,12 @@ impl User { discriminator: Some( User::find_discriminator( db, - &username, + &new_username, Some((self.discriminator.to_string(), self.id.clone())), ) .await?, ), - username: Some(username), + username: Some(new_username), ..Default::default() }, vec![], @@ -825,3 +838,109 @@ impl User { badges } } + +#[cfg(test)] +mod tests { + use crate::User; + + #[test] + fn username_validation_blocked_names() { + let username_admin = "Admin"; + let username_revolt = "Revolt"; + let username_stoat = "Stoat"; + let username_allowed = "Allowed"; + + assert!(User::validate_username(username_admin).is_err()); + assert!(User::validate_username(username_revolt).is_err()); + assert!(User::validate_username(username_stoat).is_err()); + assert!(User::validate_username(username_allowed).is_ok()); + } + + #[test] + fn username_validation_blocked_patterns() { + let username_grave = "```_test"; + let username_discord = "discord.gg_test"; + let username_rvlt = "rvlt.gg_test"; + let username_guilded = "guilded.gg_test"; + let username_stt = "stt.gg_test"; + let username_revolt = "revolt.chat_test"; + let username_stoat = "stoat.chat_test"; + let username_http = "http://_test"; + let username_https = "https://_test"; + + assert!(User::validate_username(username_grave).is_err()); + assert!(User::validate_username(username_discord).is_err()); + assert!(User::validate_username(username_rvlt).is_err()); + assert!(User::validate_username(username_guilded).is_err()); + assert!(User::validate_username(username_stt).is_err()); + assert!(User::validate_username(username_revolt).is_err()); + assert!(User::validate_username(username_stoat).is_err()); + assert!(User::validate_username(username_http).is_err()); + assert!(User::validate_username(username_https).is_err()); + } + + #[async_std::test] + async fn username_sanitisation_clean() { + let username_clean = "Test"; + + let username_clean_sanitised = User::sanitise_username(username_clean).await; + + assert!(username_clean_sanitised.is_ok()); + assert_eq!(username_clean, username_clean_sanitised.unwrap()); + } + + #[async_std::test] + async fn username_sanitisation_homoglyphs() { + let username_homoglyphs = "𝔽𝕌Ňℕy"; + + let username_homoglyphs_sanitised = + User::sanitise_username(username_homoglyphs).await.unwrap(); + + assert_ne!(username_homoglyphs, username_homoglyphs_sanitised); + assert_eq!("funny", username_homoglyphs_sanitised); + } + + #[async_std::test] + async fn username_sanitisation_padding() { + let username_padding = "a"; + + let username = User::sanitise_username(username_padding).await.unwrap(); + + assert_eq!("a_", username); + } + + #[async_std::test] + async fn create_user() { + use revolt_result::Result; + + database_test!(|db| async move { + let mut created_clean = User::create(&db, "Test".to_string(), None, None) + .await + .unwrap(); + + assert_eq!("Test", created_clean.username); + + created_clean + .update_username(&db, "Test2".to_string()) + .await + .unwrap(); + + assert_eq!("Test2", created_clean.username); + + let created_invalid_result: Result<_> = + User::create(&db, "stoat.chat".to_string(), None, None).await; + + assert!(created_invalid_result.is_err()); + + let mut updated_invalid = User::create(&db, "Test".to_string(), None, None) + .await + .unwrap(); + + let updated_invalid_update_result = updated_invalid + .update_username(&db, "http://test".to_string()) + .await; + + assert!(updated_invalid_update_result.is_err()); + }); + } +} From 279f5d5fd7af2df55902c706859ec07f569cdb1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0spik?= Date: Mon, 27 Apr 2026 08:47:52 +0300 Subject: [PATCH 150/211] fix: add new_user_hours to configuration limits (#729) Signed-off-by: ispik --- crates/delta/src/routes/root.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/delta/src/routes/root.rs b/crates/delta/src/routes/root.rs index 6fd37a19b..14ead75cb 100644 --- a/crates/delta/src/routes/root.rs +++ b/crates/delta/src/routes/root.rs @@ -92,6 +92,8 @@ pub struct GlobalLimits { /// restrict server creation to these users. /// if blank, all users can create servers pub restrict_server_creation: Vec, + /// New user hours + new_user_hours: i64, } /// # User Limits @@ -231,6 +233,7 @@ pub async fn root() -> Result> { .limits .global .restrict_server_creation, + new_user_hours: config.features.limits.global.new_user_hours as i64, }, new_user: UserLimits::from_feature_limits(config.features.limits.new_user), default: UserLimits::from_feature_limits(config.features.limits.default), From 841985d3b994df1c6eefab2fc7ecbd77ab22c493 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0spik?= Date: Sun, 3 May 2026 03:04:28 +0300 Subject: [PATCH 151/211] feat: add role icon support (#724) Signed-off-by: ispik --- .../core/database/src/models/files/model.rs | 20 +++++++++++++++++++ .../core/database/src/models/servers/model.rs | 7 +++++++ .../src/models/servers/ops/mongodb.rs | 1 + crates/core/database/src/util/bridge/v0.rs | 16 ++++++++++----- crates/core/models/src/v0/servers.rs | 9 +++++++++ crates/delta/src/routes/servers/roles_edit.rs | 20 ++++++++++++++++--- 6 files changed, 65 insertions(+), 8 deletions(-) diff --git a/crates/core/database/src/models/files/model.rs b/crates/core/database/src/models/files/model.rs index 5ea78f9b2..1aaf8b824 100644 --- a/crates/core/database/src/models/files/model.rs +++ b/crates/core/database/src/models/files/model.rs @@ -70,6 +70,7 @@ auto_derived!( LegacyGroupIcon, ChannelIcon, ServerIcon, + RoleIcon, } /// Information about what the file was used for @@ -239,4 +240,23 @@ impl File { ) .await } + + /// Use a file for a role icon + pub async fn use_role_icon( + db: &Database, + id: &str, + parent: &str, + uploader_id: &str, + ) -> Result { + db.find_and_use_attachment( + id, + "icons", + FileUsedFor { + id: parent.to_owned(), + object_type: FileUsedForType::RoleIcon, + }, + uploader_id.to_owned(), + ) + .await + } } diff --git a/crates/core/database/src/models/servers/model.rs b/crates/core/database/src/models/servers/model.rs index 183dd3d2d..50c45c59e 100644 --- a/crates/core/database/src/models/servers/model.rs +++ b/crates/core/database/src/models/servers/model.rs @@ -86,6 +86,9 @@ auto_derived_partial!( /// Ranking of this role #[serde(default)] pub rank: i64, + /// Custom icon attachment + #[serde(skip_serializing_if = "Option::is_none")] + pub icon: Option, }, "PartialRole" ); @@ -129,6 +132,7 @@ auto_derived!( /// Optional fields on server object pub enum FieldsRole { Colour, + Icon, } ); @@ -305,6 +309,7 @@ impl Role { colour: self.colour, hoist: Some(self.hoist), rank: Some(self.rank), + icon: self.icon, } } @@ -318,6 +323,7 @@ impl Role { colour: None, hoist: false, permissions: Default::default(), + icon: None, }; db.insert_role(&server.id, &role).await?; @@ -367,6 +373,7 @@ impl Role { pub fn remove_field(&mut self, field: &FieldsRole) { match field { FieldsRole::Colour => self.colour = None, + FieldsRole::Icon => self.icon = None, } } diff --git a/crates/core/database/src/models/servers/ops/mongodb.rs b/crates/core/database/src/models/servers/ops/mongodb.rs index d8ef26f2a..964de4103 100644 --- a/crates/core/database/src/models/servers/ops/mongodb.rs +++ b/crates/core/database/src/models/servers/ops/mongodb.rs @@ -172,6 +172,7 @@ impl IntoDocumentPath for FieldsRole { fn as_path(&self) -> Option<&'static str> { Some(match self { FieldsRole::Colour => "colour", + FieldsRole::Icon => "icon", }) } } diff --git a/crates/core/database/src/util/bridge/v0.rs b/crates/core/database/src/util/bridge/v0.rs index 2e6377952..45b80e55f 100644 --- a/crates/core/database/src/util/bridge/v0.rs +++ b/crates/core/database/src/util/bridge/v0.rs @@ -190,7 +190,7 @@ impl From for Channel { role_permissions, nsfw, voice, - slowmode + slowmode, } => Channel::TextChannel { id, server, @@ -202,7 +202,7 @@ impl From for Channel { role_permissions, nsfw, voice: voice.map(|voice| voice.into()), - slowmode + slowmode, }, } } @@ -256,7 +256,7 @@ impl From for crate::Channel { role_permissions, nsfw, voice, - slowmode + slowmode, } => crate::Channel::TextChannel { id, server, @@ -268,7 +268,7 @@ impl From for crate::Channel { role_permissions, nsfw, voice: voice.map(|voice| voice.into()), - slowmode + slowmode, }, } } @@ -307,7 +307,7 @@ impl From for crate::PartialChannel { default_permissions: value.default_permissions, last_message_id: value.last_message_id, voice: value.voice.map(|voice| voice.into()), - slowmode: value.slowmode + slowmode: value.slowmode, } } } @@ -926,6 +926,7 @@ impl From for Role { colour: value.colour, hoist: value.hoist, rank: value.rank, + icon: value.icon.map(|f| f.into()), } } } @@ -939,6 +940,7 @@ impl From for crate::Role { colour: value.colour, hoist: value.hoist, rank: value.rank, + icon: value.icon.map(|f| f.into()), } } } @@ -952,6 +954,7 @@ impl From for PartialRole { colour: value.colour, hoist: value.hoist, rank: value.rank, + icon: value.icon.map(|f| f.into()), } } } @@ -965,6 +968,7 @@ impl From for crate::PartialRole { colour: value.colour, hoist: value.hoist, rank: value.rank, + icon: value.icon.map(|f| f.into()), } } } @@ -973,6 +977,7 @@ impl From for FieldsRole { fn from(value: crate::FieldsRole) -> Self { match value { crate::FieldsRole::Colour => FieldsRole::Colour, + crate::FieldsRole::Icon => FieldsRole::Icon, } } } @@ -981,6 +986,7 @@ impl From for crate::FieldsRole { fn from(value: FieldsRole) -> Self { match value { FieldsRole::Colour => crate::FieldsRole::Colour, + FieldsRole::Icon => crate::FieldsRole::Icon, } } } diff --git a/crates/core/models/src/v0/servers.rs b/crates/core/models/src/v0/servers.rs index d9835443c..2aab765e6 100644 --- a/crates/core/models/src/v0/servers.rs +++ b/crates/core/models/src/v0/servers.rs @@ -106,6 +106,9 @@ auto_derived_partial!( /// Ranking of this role #[cfg_attr(feature = "serde", serde(default))] pub rank: i64, + /// Role icon + #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + pub icon: Option, }, "PartialRole" ); @@ -123,6 +126,7 @@ auto_derived!( /// Optional fields on server object pub enum FieldsRole { Colour, + Icon, } /// Channel category @@ -278,6 +282,11 @@ auto_derived!( /// /// **Removed** - no effect, use the edit server role positions route pub rank: Option, + /// Role icon + /// + /// Provide an Autumn attachment Id. + #[cfg_attr(feature = "validator", validate(length(min = 1, max = 128)))] + pub icon: Option, /// Fields to remove from role object #[cfg_attr(feature = "serde", serde(default))] pub remove: Vec, diff --git a/crates/delta/src/routes/servers/roles_edit.rs b/crates/delta/src/routes/servers/roles_edit.rs index 0a122c1fb..e46932ef3 100644 --- a/crates/delta/src/routes/servers/roles_edit.rs +++ b/crates/delta/src/routes/servers/roles_edit.rs @@ -1,7 +1,7 @@ use revolt_database::{ util::{permissions::DatabasePermissionQuery, reference::Reference}, voice::{sync_voice_permissions, VoiceClient}, - Database, PartialRole, User + Database, File, PartialRole, User, }; use revolt_models::v0; use revolt_permissions::{calculate_server_permissions, ChannelPermission}; @@ -47,14 +47,27 @@ pub async fn edit( name, colour, hoist, + icon, remove, .. } = data; + if remove.contains(&v0::FieldsRole::Icon) { + if let Some(existing_icon) = &role.icon { + db.mark_attachment_as_deleted(&existing_icon.id).await?; + } + } + + let mut final_icon = None; + if let Some(icon_id) = icon { + final_icon = Some(File::use_role_icon(db, &icon_id, &role_id, &user.id).await?); + } + let partial = PartialRole { name, colour, hoist, + icon: final_icon, ..Default::default() }; @@ -69,8 +82,9 @@ pub async fn edit( for channel_id in &server.channels { let channel = Reference::from_unchecked(channel_id).as_channel(db).await?; - sync_voice_permissions(db, voice_client, &channel, Some(&server), Some(&role_id)).await?; - }; + sync_voice_permissions(db, voice_client, &channel, Some(&server), Some(&role_id)) + .await?; + } Ok(Json(role.into())) } else { From 5378cd22b4c7d85f44c31a6af0dda00941b80d5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0spik?= Date: Tue, 5 May 2026 21:57:42 +0300 Subject: [PATCH 152/211] fix: use correct response for NoEffect errors (#732) Signed-off-by: ispik --- crates/core/result/src/axum.rs | 6 ++---- crates/core/result/src/rocket.rs | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/crates/core/result/src/axum.rs b/crates/core/result/src/axum.rs index 23b09f7b3..f465854bf 100644 --- a/crates/core/result/src/axum.rs +++ b/crates/core/result/src/axum.rs @@ -36,9 +36,7 @@ impl IntoResponse for Error { ErrorType::NotInGroup => StatusCode::NOT_FOUND, ErrorType::AlreadyPinned => StatusCode::BAD_REQUEST, ErrorType::NotPinned => StatusCode::BAD_REQUEST, - ErrorType::InSlowmode { - retry_after: _, - } => StatusCode::TOO_MANY_REQUESTS, + ErrorType::InSlowmode { retry_after: _ } => StatusCode::TOO_MANY_REQUESTS, ErrorType::CantCreateServers => StatusCode::FORBIDDEN, ErrorType::UnknownServer => StatusCode::NOT_FOUND, @@ -78,7 +76,7 @@ impl IntoResponse for Error { ErrorType::DuplicateNonce => StatusCode::CONFLICT, ErrorType::VosoUnavailable => StatusCode::BAD_REQUEST, ErrorType::NotFound => StatusCode::NOT_FOUND, - ErrorType::NoEffect => StatusCode::OK, + ErrorType::NoEffect => StatusCode::BAD_REQUEST, ErrorType::FailedValidation { .. } => StatusCode::BAD_REQUEST, ErrorType::LiveKitUnavailable => StatusCode::BAD_REQUEST, ErrorType::NotConnected => StatusCode::BAD_REQUEST, diff --git a/crates/core/result/src/rocket.rs b/crates/core/result/src/rocket.rs index 5d2904d03..649375e28 100644 --- a/crates/core/result/src/rocket.rs +++ b/crates/core/result/src/rocket.rs @@ -42,9 +42,7 @@ impl<'r> Responder<'r, 'static> for Error { ErrorType::NotInGroup => Status::NotFound, ErrorType::AlreadyPinned => Status::BadRequest, ErrorType::NotPinned => Status::BadRequest, - ErrorType::InSlowmode { - retry_after: _, - } => Status::TooManyRequests, + ErrorType::InSlowmode { retry_after: _ } => Status::TooManyRequests, ErrorType::InvalidFlagValue => Status::BadRequest, ErrorType::CantCreateServers => Status::Forbidden, @@ -84,7 +82,7 @@ impl<'r> Responder<'r, 'static> for Error { ErrorType::NotAuthenticated => Status::Unauthorized, ErrorType::DuplicateNonce => Status::Conflict, ErrorType::NotFound => Status::NotFound, - ErrorType::NoEffect => Status::Ok, + ErrorType::NoEffect => Status::BadRequest, ErrorType::FailedValidation { .. } => Status::BadRequest, ErrorType::LiveKitUnavailable => Status::BadRequest, ErrorType::NotAVoiceChannel => Status::BadRequest, From 6b41db984bb491b2e58324309cc70d8c14e0b814 Mon Sep 17 00:00:00 2001 From: Tom Date: Wed, 6 May 2026 16:25:31 -0700 Subject: [PATCH 153/211] feat: blacklist private ip ranges and add january domain blocklist (#731) Signed-off-by: IAmTomahawkx --- Cargo.lock | 221 ++++++++++++++++++- crates/core/config/Revolt.toml | 2 + crates/core/config/src/lib.rs | 6 + crates/services/january/Cargo.toml | 2 + crates/services/january/src/requests.rs | 84 ++++++- crates/services/january/src/website_embed.rs | 3 +- 6 files changed, 299 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ce648f79b..3f452c4dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -288,7 +288,7 @@ dependencies = [ "futures-lite", "parking", "polling", - "rustix", + "rustix 1.1.4", "slab", "windows-sys 0.61.2", ] @@ -328,7 +328,7 @@ dependencies = [ "cfg-if", "event-listener 5.4.1", "futures-lite", - "rustix", + "rustix 1.1.4", ] [[package]] @@ -354,7 +354,7 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix", + "rustix 1.1.4", "signal-hook-registry", "slab", "windows-sys 0.61.2", @@ -3450,6 +3450,15 @@ dependencies = [ "digest", ] +[[package]] +name = "home" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "hostname" version = "0.3.1" @@ -4576,6 +4585,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + [[package]] name = "linux-raw-sys" version = "0.12.1" @@ -5466,6 +5481,12 @@ dependencies = [ "portable-atomic", ] +[[package]] +name = "oorandom" +version = "11.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" + [[package]] name = "opaque-debug" version = "0.3.1" @@ -5682,6 +5703,106 @@ dependencies = [ "digest", ] +[[package]] +name = "pdk-classy" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fa3e632c61a7f8ad1a77c4f52d9a85a89c577881f44e89b33e28163af38e515" +dependencies = [ + "bincode", + "futures", + "getrandom 0.2.17", + "http 0.2.12", + "log", + "pdk-proxy-wasm-stub", + "protobuf", + "proxy-wasm", + "serde", + "serde_derive", + "thiserror 1.0.69", +] + +[[package]] +name = "pdk-core" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60f2b1d1c8876b54d03d35a18fba1e5172ed8d7f1c379001c11b62c909fdf654" +dependencies = [ + "anyhow", + "log", + "pdk-classy", + "pdk-macros", + "pdk-script", + "protobuf", + "protobuf-codegen", + "rmp-serde", + "serde", + "serde_derive", + "serde_json", + "sha2", + "url", +] + +[[package]] +name = "pdk-ip-filter-lib" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dab00d1dfe7b232fcb5424c3af23721993b439a51960f1f3152760228f492ec" +dependencies = [ + "anyhow", + "ipnet", + "pdk-core", + "thiserror 1.0.69", +] + +[[package]] +name = "pdk-macros" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da346bb3e02aad6b6bf31e6e38798c0f3cdf8bd0319fe97d44addc5a0ea5de92" +dependencies = [ + "proc-macro2", + "quote 1.0.45", + "syn 1.0.109", +] + +[[package]] +name = "pdk-pel" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c60996708c43b91581ea9e6fa324af7eae5a9b8146dd96cacf2868e9260b654" +dependencies = [ + "base64 0.22.1", + "getrandom 0.2.17", + "serde_json", + "thiserror 1.0.69", + "uuid", +] + +[[package]] +name = "pdk-proxy-wasm-stub" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469571b12631b71dce33890917bec59f58c53f9d3b05b748d5aa873c950e1702" + +[[package]] +name = "pdk-script" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8842ea2908eb9b94ed7daa522cc75fcd5fe3738a20d7ecde67cb7829dbf129e" +dependencies = [ + "log", + "num-traits", + "oorandom", + "pdk-classy", + "pdk-pel", + "roxmltree", + "serde", + "serde_json", + "thiserror 1.0.69", + "url", +] + [[package]] name = "pear" version = "0.2.9" @@ -6033,7 +6154,7 @@ dependencies = [ "concurrent-queue", "hermit-abi 0.5.2", "pin-project-lite 0.2.17", - "rustix", + "rustix 1.1.4", "windows-sys 0.61.2", ] @@ -6278,6 +6399,67 @@ dependencies = [ "prost", ] +[[package]] +name = "protobuf" +version = "3.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d65a1d4ddae7d8b5de68153b48f6aa3bba8cb002b243dbdbc55a5afbc98f99f4" +dependencies = [ + "once_cell", + "protobuf-support", + "thiserror 1.0.69", +] + +[[package]] +name = "protobuf-codegen" +version = "3.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d3976825c0014bbd2f3b34f0001876604fe87e0c86cd8fa54251530f1544ace" +dependencies = [ + "anyhow", + "once_cell", + "protobuf", + "protobuf-parse", + "regex", + "tempfile", + "thiserror 1.0.69", +] + +[[package]] +name = "protobuf-parse" +version = "3.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4aeaa1f2460f1d348eeaeed86aea999ce98c1bded6f089ff8514c9d9dbdc973" +dependencies = [ + "anyhow", + "indexmap 2.13.1", + "log", + "protobuf", + "protobuf-support", + "tempfile", + "thiserror 1.0.69", + "which", +] + +[[package]] +name = "protobuf-support" +version = "3.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e36c2f31e0a47f9280fb347ef5e461ffcd2c52dd520d8e216b52f93b0b0d7d6" +dependencies = [ + "thiserror 1.0.69", +] + +[[package]] +name = "proxy-wasm" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8d35d9e2bc5104e2e954b149aa1d5f9fa3bb27f73b45b2706020fed101db685" +dependencies = [ + "hashbrown 0.16.1", + "log", +] + [[package]] name = "pxfm" version = "0.1.28" @@ -7055,6 +7237,7 @@ dependencies = [ "lazy_static", "mime", "moka", + "pdk-ip-filter-lib", "regex", "reqwest 0.13.2", "revolt-config", @@ -7068,6 +7251,7 @@ dependencies = [ "tokio 1.51.0", "tracing", "tracing-subscriber", + "url", "utoipa", "utoipa-scalar", ] @@ -7608,6 +7792,19 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags 2.11.0", + "errno", + "libc", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + [[package]] name = "rustix" version = "1.1.4" @@ -7617,7 +7814,7 @@ dependencies = [ "bitflags 2.11.0", "errno", "libc", - "linux-raw-sys", + "linux-raw-sys 0.12.1", "windows-sys 0.61.2", ] @@ -8781,7 +8978,7 @@ dependencies = [ "fastrand 2.4.0", "getrandom 0.4.2", "once_cell", - "rustix", + "rustix 1.1.4", "windows-sys 0.61.2", ] @@ -9979,6 +10176,18 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88" +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix 0.38.44", +] + [[package]] name = "widestring" version = "1.2.1" diff --git a/crates/core/config/Revolt.toml b/crates/core/config/Revolt.toml index 30a4622ef..aee3a8414 100644 --- a/crates/core/config/Revolt.toml +++ b/crates/core/config/Revolt.toml @@ -132,6 +132,8 @@ pkcs8 = "" key_id = "" team_id = "" +[january] +blocked_domains = [] [files] # Encryption key for stored files diff --git a/crates/core/config/src/lib.rs b/crates/core/config/src/lib.rs index a49b1cdf4..b0cfa4555 100644 --- a/crates/core/config/src/lib.rs +++ b/crates/core/config/src/lib.rs @@ -302,6 +302,11 @@ impl Pushd { } } +#[derive(Deserialize, Debug, Clone)] +pub struct January { + pub blocked_domains: Vec, +} + #[derive(Deserialize, Debug, Clone)] pub struct FilesLimit { pub min_file_size: usize, @@ -421,6 +426,7 @@ pub struct Settings { pub hosts: Hosts, pub api: Api, pub pushd: Pushd, + pub january: January, pub files: Files, pub features: Features, pub sentry: Sentry, diff --git a/crates/services/january/Cargo.toml b/crates/services/january/Cargo.toml index 78ec07ad0..7059cca05 100644 --- a/crates/services/january/Cargo.toml +++ b/crates/services/january/Cargo.toml @@ -27,6 +27,8 @@ tokio = { workspace = true, features = [] } # Web requests reqwest = { workspace = true, features = ["json"] } +pdk-ip-filter-lib = "1.8.0" +url = { workspace = true } # Logging tracing = { workspace = true } diff --git a/crates/services/january/src/requests.rs b/crates/services/january/src/requests.rs index cf681171a..b2b754308 100644 --- a/crates/services/january/src/requests.rs +++ b/crates/services/january/src/requests.rs @@ -1,12 +1,13 @@ use encoding_rs::{Encoding, UTF_8_INIT}; use lazy_static::lazy_static; use mime::Mime; +use pdk_ip_filter_lib::IpFilter; use regex::Regex; use reqwest::{ header::{self, CONTENT_TYPE}, redirect, Client, Response, }; -use revolt_config::report_internal_error; +use revolt_config::{config, report_internal_error}; use revolt_files::{create_thumbnail, decode_image, image_size_vec, is_valid_image, video_size}; use revolt_models::v0::{Embed, Image, ImageSize, Video}; use revolt_result::{create_error, Error, Result}; @@ -14,6 +15,7 @@ use std::{ io::{Cursor, Write}, time::Duration, }; +use url::{Host, Url}; lazy_static! { /// Request client @@ -23,7 +25,7 @@ lazy_static! { .redirect(redirect::Policy::custom(|attempt| { if attempt.previous().len() > 5 { // TODO config attempt.error("too many redirects") - } else if attempt.url().host_str() == Some("jan.revolt.chat") { // TODO config + } else if attempt.url().host_str() == Some("proxy.stoatusercontent.com") { // TODO config attempt.stop() } else { attempt.follow() @@ -33,10 +35,10 @@ lazy_static! { .expect("reqwest Client"); /// Spoof User Agent as Discord - static ref RE_USER_AGENT_SPOOFING_AS_DISCORD: Regex = Regex::new("^(?:(?:https?:)?//)?(?:(?:vx|fx)?twitter|(?:fixv|fixup)?x|(?:old\\.|new\\.|www\\.)reddit).com").expect("valid regex"); + static ref RE_USER_AGENT_SPOOFING_AS_DISCORD: Regex = Regex::new("^(?:(?:vx|fx)?twitter|(?:fixv|fixup)?x|(?:old\\.|new\\.|www\\.)reddit).com").expect("valid regex"); /// Regex for matching new Reddit URLs - static ref RE_URL_NEW_REDDIT: Regex = Regex::new("^(?:(?:https?:)?//)?(?:(?:new\\.|www\\.)?reddit).com").expect("valid regex"); + static ref RE_URL_NEW_REDDIT: Regex = Regex::new("^(?:(?:new\\.|www\\.)?reddit).com").expect("valid regex"); /// Cache for proxy results static ref PROXY_CACHE: moka::future::Cache)>> = moka::future::Cache::builder() @@ -59,6 +61,28 @@ lazy_static! { .max_capacity(10_000) // Cache up to 10k embeds .time_to_live(Duration::from_secs(60)) // For up to 1 minute .build(); + + static ref IP_BLOCKLIST: IpFilter = IpFilter::block(&[ + "10.0.0.0/8", // something something modern problem require modern solutions + "192.168.0.0/16", + "172.16.0.0/16", + "172.17.0.0/16", + "172.18.0.0/16", + "172.19.0.0/16", + "172.20.0.0/16", + "172.21.0.0/16", + "172.22.0.0/16", + "172.23.0.0/16", + "172.24.0.0/16", + "172.25.0.0/16", + "172.26.0.0/16", + "172.27.0.0/16", + "172.28.0.0/16", + "172.29.0.0/16", + "172.30.0.0/16", + "172.31.0.0/16", + "172.32.0.0/16"] + ).unwrap(); } /// Information about a successful request @@ -73,7 +97,7 @@ impl Request { if let Some(hit) = PROXY_CACHE.get(url).await { hit } else { - let Request { response, mime } = Request::new(url).await?; + let Request { response, mime } = Request::new_from_str(url).await?; if matches!(mime.type_(), mime::IMAGE | mime::VIDEO) { let bytes = report_internal_error!(response.bytes().await); @@ -135,7 +159,7 @@ impl Request { let request = if let Some(request) = request { request } else { - let request = Request::new(url).await?; + let request = Request::new_from_str(url).await?; if matches!(request.mime.type_(), mime::IMAGE) { request } else { @@ -173,7 +197,7 @@ impl Request { let response = if let Some(Request { response, .. }) = request { response } else { - let Request { response, mime } = Request::new(url).await?; + let Request { response, mime } = Request::new_from_str(url).await?; if matches!(mime.type_(), mime::VIDEO) { response } else { @@ -212,7 +236,7 @@ impl Request { if let Some(hit) = EMBED_CACHE.get(&url).await { Ok(hit) } else { - let request = Request::new(&url).await?; + let request = Request::new_from_str(&url).await?; let embed = match (request.mime.type_(), request.mime.subtype()) { (_, mime::HTML) => { let content_type = request @@ -255,15 +279,19 @@ impl Request { } /// Send a new request to a service - pub async fn new(url: &str) -> Result { + pub async fn new(url: Url) -> Result { + let url_host_str = url.host_str().ok_or(create_error!(ProxyError))?.to_string(); + + Request::url_is_blacklisted(&url).await?; + let response = CLIENT .get(url) .header( "User-Agent", - if RE_USER_AGENT_SPOOFING_AS_DISCORD.is_match(url) { + if RE_USER_AGENT_SPOOFING_AS_DISCORD.is_match(&url_host_str) { "Mozilla/5.0 (compatible; Discordbot/2.0; +https://discordapp.com)" } else { - "Mozilla/5.0 (compatible; January/2.0; +https://github.com/revoltchat/backend)" + "Mozilla/5.0 (compatible; January/2.0; +https://github.com/stoatchat/stoatchat)" }, ) .header("Accept-Language", "en-US,en;q=0.5") @@ -290,12 +318,44 @@ impl Request { Ok(Request { response, mime }) } + pub async fn new_from_str(url: &str) -> Result { + let proper_url = Url::parse(url).map_err(|_| create_error!(ProxyError))?; + Request::new(proper_url).await + } + /// Check if something exists - pub async fn exists(url: &str) -> bool { + pub async fn exists(url: Url) -> bool { if let Ok(response) = CLIENT.head(url).send().await { response.status().is_success() } else { false } } + + pub async fn exists_from_str(url: &str) -> Result { + let proper_url = Url::parse(url).map_err(|_| create_error!(ProxyError))?; + Ok(Request::exists(proper_url).await) + } + + pub async fn url_is_blacklisted(url: &Url) -> Result<()> { + if let Some(host) = url.host() { + match host { + Host::Ipv4(ipv4) => { + let url_str = ipv4.to_string(); + if !IP_BLOCKLIST.is_allowed(&url_str) { + return Err(create_error!(InvalidOperation)); + } + } + Host::Domain(domain) => { + let config = config().await; + if config.january.blocked_domains.iter().any(|x| x == domain) { + return Err(create_error!(InvalidOperation)); + } + } + _ => (), + } + }; + + Ok(()) + } } diff --git a/crates/services/january/src/website_embed.rs b/crates/services/january/src/website_embed.rs index 25de15372..6ab1af580 100644 --- a/crates/services/january/src/website_embed.rs +++ b/crates/services/january/src/website_embed.rs @@ -236,11 +236,12 @@ pub async fn populate_special(original_url: String, metadata: &mut WebsiteMetada metadata.site_name.take(); // Verify the video exists - if !crate::requests::Request::exists(&format!( + if !crate::requests::Request::exists_from_str(&format!( "http://img.youtube.com/vi/{}/sddefault.jpg", id )) .await + .unwrap_or(false) { return; } From 21d82018cf84ab0fdd10613d254b9562aea8eea3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0spik?= Date: Thu, 7 May 2026 02:35:20 +0300 Subject: [PATCH 154/211] feat: add legal links to root payload (#733) Signed-off-by: ispik --- crates/core/config/Revolt.toml | 6 ++++++ crates/core/config/src/lib.rs | 11 +++++++++++ crates/delta/src/routes/root.rs | 18 ++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/crates/core/config/Revolt.toml b/crates/core/config/Revolt.toml index aee3a8414..2440bb316 100644 --- a/crates/core/config/Revolt.toml +++ b/crates/core/config/Revolt.toml @@ -317,6 +317,12 @@ emojis = 500_000 # default: 5 process_message_delay_limit = 5 +[features.legal_links] +# URLs for legal documents +terms_of_service = "" +privacy_policy = "" +guidelines = "" + [sentry] # Configuration for Sentry error reporting api = "" diff --git a/crates/core/config/src/lib.rs b/crates/core/config/src/lib.rs index b0cfa4555..3dc2771a3 100644 --- a/crates/core/config/src/lib.rs +++ b/crates/core/config/src/lib.rs @@ -382,6 +382,16 @@ pub struct FeaturesLimitsCollection { pub roles: HashMap, } +#[derive(Deserialize, Debug, Clone)] +pub struct LegalLinks { + /// Terms of Service URL + pub terms_of_service: String, + /// Privacy Policy URL + pub privacy_policy: String, + /// Guidelines URL + pub guidelines: String, +} + #[derive(Deserialize, Debug, Clone)] pub struct FeaturesAdvanced { #[serde(default)] @@ -399,6 +409,7 @@ impl Default for FeaturesAdvanced { #[derive(Deserialize, Debug, Clone)] pub struct Features { pub limits: FeaturesLimitsCollection, + pub legal_links: LegalLinks, pub webhooks_enabled: bool, pub mass_mentions_send_notifications: bool, pub mass_mentions_enabled: bool, diff --git a/crates/delta/src/routes/root.rs b/crates/delta/src/routes/root.rs index 14ead75cb..c0fb4faeb 100644 --- a/crates/delta/src/routes/root.rs +++ b/crates/delta/src/routes/root.rs @@ -57,6 +57,8 @@ pub struct RevoltFeatures { pub livekit: VoiceFeature, /// Limits pub limits: LimitsConfig, + /// Legal links + pub legal_links: LegalLinks, } /// # Limits For Users @@ -70,6 +72,17 @@ pub struct LimitsConfig { pub default: UserLimits, } +/// # Legal links +#[derive(Serialize, JsonSchema, Debug)] +pub struct LegalLinks { + /// Terms of Service URL + pub terms_of_service: String, + /// Privacy Policy URL + pub privacy_policy: String, + /// Guidelines URL + pub guidelines: String, +} + /// # Global limits #[derive(Serialize, JsonSchema, Debug)] pub struct GlobalLimits { @@ -238,6 +251,11 @@ pub async fn root() -> Result> { new_user: UserLimits::from_feature_limits(config.features.limits.new_user), default: UserLimits::from_feature_limits(config.features.limits.default), }, + legal_links: LegalLinks { + terms_of_service: config.features.legal_links.terms_of_service, + privacy_policy: config.features.legal_links.privacy_policy, + guidelines: config.features.legal_links.guidelines, + }, }, ws: config.hosts.events, app: config.hosts.app, From 356491e934b274f9e895df883dd63ef0b3123510 Mon Sep 17 00:00:00 2001 From: Tom Date: Wed, 6 May 2026 21:33:52 -0700 Subject: [PATCH 155/211] fix: january ip redirects & domain resolver (#738) * fix: properly block private ip ranges I'm a dunce and forgot that domains do in fact resolve to ips. * fix: reimplement max redirects * fix: remove my debug error * fix: actually check redirect urls kind of the whole point of this thing. --- crates/services/january/src/requests.rs | 119 +++++++++++++++--------- 1 file changed, 73 insertions(+), 46 deletions(-) diff --git a/crates/services/january/src/requests.rs b/crates/services/january/src/requests.rs index b2b754308..bec5bc1db 100644 --- a/crates/services/january/src/requests.rs +++ b/crates/services/january/src/requests.rs @@ -10,9 +10,10 @@ use reqwest::{ use revolt_config::{config, report_internal_error}; use revolt_files::{create_thumbnail, decode_image, image_size_vec, is_valid_image, video_size}; use revolt_models::v0::{Embed, Image, ImageSize, Video}; -use revolt_result::{create_error, Error, Result}; +use revolt_result::{create_error, Error, Result, ToRevoltError}; use std::{ io::{Cursor, Write}, + str::FromStr, time::Duration, }; use url::{Host, Url}; @@ -22,15 +23,7 @@ lazy_static! { static ref CLIENT: Client = reqwest::Client::builder() .timeout(Duration::from_secs(10)) // TODO config .connect_timeout(Duration::from_secs(5)) // TODO config - .redirect(redirect::Policy::custom(|attempt| { - if attempt.previous().len() > 5 { // TODO config - attempt.error("too many redirects") - } else if attempt.url().host_str() == Some("proxy.stoatusercontent.com") { // TODO config - attempt.stop() - } else { - attempt.follow() - } - })) + .redirect(redirect::Policy::none()) .build() .expect("reqwest Client"); @@ -63,25 +56,14 @@ lazy_static! { .build(); static ref IP_BLOCKLIST: IpFilter = IpFilter::block(&[ - "10.0.0.0/8", // something something modern problem require modern solutions + "10.0.0.0/8", "192.168.0.0/16", - "172.16.0.0/16", - "172.17.0.0/16", - "172.18.0.0/16", - "172.19.0.0/16", - "172.20.0.0/16", - "172.21.0.0/16", - "172.22.0.0/16", - "172.23.0.0/16", - "172.24.0.0/16", - "172.25.0.0/16", - "172.26.0.0/16", - "172.27.0.0/16", - "172.28.0.0/16", - "172.29.0.0/16", - "172.30.0.0/16", - "172.31.0.0/16", - "172.32.0.0/16"] + "127.0.0.0/8", + "172.16.0.0/12", + "169.254.0.0/16", + "::1", + "fc00::/7" + ] ).unwrap(); } @@ -280,11 +262,14 @@ impl Request { /// Send a new request to a service pub async fn new(url: Url) -> Result { + let mut url = url; let url_host_str = url.host_str().ok_or(create_error!(ProxyError))?.to_string(); Request::url_is_blacklisted(&url).await?; + let mut redirect_count = 0; - let response = CLIENT + loop { + let response = CLIENT .get(url) .header( "User-Agent", @@ -299,23 +284,42 @@ impl Request { .await .map_err(|_| create_error!(ProxyError))?; - if !response.status().is_success() { - tracing::error!("{:?}", response); - return Err(create_error!(ProxyError)); - } + if response.status().is_redirection() { + redirect_count += 1; - let content_type = response - .headers() - .get(CONTENT_TYPE) - .ok_or(create_error!(ProxyError))? - .to_str() - .map_err(|_| create_error!(ProxyError))?; + if redirect_count > 5 { + return Err(create_error!(ProxyError)); + } + if let Some(location) = response.headers().get("location") { + let location = location.to_str().map_err(|_| create_error!(ProxyError))?; + url = Url::from_str(location).to_internal_error()?; - let mime: mime::Mime = content_type - .parse() - .map_err(|_| create_error!(ProxyError))?; + if !Request::url_is_blacklisted(&url).await? { + continue; + } + } else { + return Err(create_error!(ProxyError)); + } + } + + if !response.status().is_success() { + tracing::error!("{:?}", response); + return Err(create_error!(ProxyError)); + } - Ok(Request { response, mime }) + let content_type = response + .headers() + .get(CONTENT_TYPE) + .ok_or(create_error!(ProxyError))? + .to_str() + .map_err(|_| create_error!(ProxyError))?; + + let mime: mime::Mime = content_type + .parse() + .map_err(|_| create_error!(ProxyError))?; + + return Ok(Request { response, mime }); + } } pub async fn new_from_str(url: &str) -> Result { @@ -337,7 +341,7 @@ impl Request { Ok(Request::exists(proper_url).await) } - pub async fn url_is_blacklisted(url: &Url) -> Result<()> { + pub async fn url_is_blacklisted(url: &Url) -> Result { if let Some(host) = url.host() { match host { Host::Ipv4(ipv4) => { @@ -347,15 +351,38 @@ impl Request { } } Host::Domain(domain) => { + let mut domain = domain.to_string(); + let config = config().await; - if config.january.blocked_domains.iter().any(|x| x == domain) { + + // First step: TLDs and blocked domains + if !domain.contains(".") // lazily block TLDs + || config.january.blocked_domains.iter().any(|x| x == &domain) + { return Err(create_error!(InvalidOperation)); } + + if !domain.contains(":") { + domain += ":80"; + } + + // Second step: resolve the IP and check the blocklist + if let Ok(mut resolved_ip) = tokio::net::lookup_host(domain.clone()).await { + if let Some(resolved_ip) = resolved_ip.next() { + if !IP_BLOCKLIST.is_allowed(&resolved_ip.ip().to_string()) { + return Err(create_error!(InvalidOperation)); + } + } else { + return Err(create_error!(InvalidOperation)); + } + } else { + return Err(create_error!(ProxyError)); + } } _ => (), } }; - Ok(()) + Ok(false) } } From df276ac40b60cf94bc58468690ffeb31be674312 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0spik?= Date: Sat, 9 May 2026 00:37:35 +0300 Subject: [PATCH 156/211] chore: update emoji list (#740) Signed-off-by: ispik --- .../src/models/emojis/unicode_emoji.txt | 5230 ++++++++++++----- 1 file changed, 3662 insertions(+), 1568 deletions(-) diff --git a/crates/core/database/src/models/emojis/unicode_emoji.txt b/crates/core/database/src/models/emojis/unicode_emoji.txt index bc8036e38..06e8bf749 100644 --- a/crates/core/database/src/models/emojis/unicode_emoji.txt +++ b/crates/core/database/src/models/emojis/unicode_emoji.txt @@ -1,1590 +1,247 @@ -💯 -🔢 -😀 -😃 -😄 -😁 -😆 -😆 -😅 -🤣 -😂 -🙂 -🙃 -😉 -😊 -😇 -🥰 -😍 -🤩 -😘 -😗 -☺️ -😚 -😙 -🥲 -😋 -😛 -😜 -🤪 -😝 -🤑 -🤗 -🤭 -🤫 -🤔 -🤐 -🤨 -😐 -😑 -😶 -😏 -😒 -🙄 -😬 -🤥 -😌 -😔 -😪 -🤤 -😴 -😷 -🤒 -🤕 -🤢 -🤮 -🤧 -🥵 -🥶 -🥴 -😵 -🤯 -🤠 -🥳 -🥸 -😎 -🤓 -🧐 -😕 -😟 -🙁 -☹️ -😮 -😯 -😲 -😳 -🥺 -😦 -😧 -😨 -😰 -😥 -😢 -😭 -😱 -😖 -😣 -😞 -😓 -😩 -😫 -🥱 -😤 -😡 -😡 -😠 -🤬 -😈 -👿 -💀 -☠️ -💩 -💩 -💩 -🤡 -👹 -👺 -👻 -👽 -👾 -🤖 -😺 -😸 -😹 -😻 -😼 -😽 -🙀 -😿 -😾 -🙈 -🙉 -🙊 -💋 -💌 -💘 -💝 -💖 -💗 -💓 -💞 -💕 -💟 -❣️ -💔 -❤️ -🧡 -💛 -💚 -💙 -💜 -🤎 -🖤 -🤍 -💢 -💥 -💥 -💫 -💦 -💨 -🕳️ -💣 -💬 -👁️‍🗨️ -🗨️ -🗯️ -💭 -💤 -👋 -🤚 -🖐️ -✋ -✋ -🖖 -👌 -🤌 -🤏 -✌️ -🤞 -🤟 -🤘 -🤙 -👈 -👉 -👆 -🖕 -🖕 -👇 + +*️⃣ +0️⃣ +1️⃣ +2️⃣ +3️⃣ +4️⃣ +5️⃣ +6️⃣ +7️⃣ +8️⃣ +9️⃣ +©️ +®️ +‼️ +⁉️ +™️ +ℹ️ +↔️ +↕️ +↖️ +↗️ +↘️ +↙️ +↩️ +↪️ +⌚ +⌛ +⌨️ +⏏️ +⏩ +⏪ +⏫ +⏬ +⏭️ +⏮️ +⏯️ +⏰ +⏱️ +⏲️ +⏳ +⏸️ +⏹️ +⏺️ +Ⓜ️ +▪️ +▫️ +▶️ +◀️ +◻️ +◼️ +◽ +◾ +☀️ +☁️ +☂️ +☃️ +☄️ +☎️ +☑️ +☔ +☕ +☘️ ☝️ -👍 -👍 -👎 -👎 -✊ -✊ -👊 -👊 -👊 -🤛 -🤜 -👏 -🙌 -👐 -🤲 -🤝 -🙏 +☝🏻 +☝🏼 +☝🏽 +☝🏾 +☝🏿 +☠️ +☢️ +☣️ +☦️ +☪️ +☮️ +☯️ +☸️ +☹️ +☺️ +♀️ +♂️ +♈ +♉ +♊ +♋ +♌ +♍ +♎ +♏ +♐ +♑ +♒ +♓ +♟️ +♠️ +♣️ +♥️ +♦️ +♨️ +♻️ +♾️ +♿ +⚒️ +⚓ +⚔️ +⚕️ +⚖️ +⚗️ +⚙️ +⚛️ +⚜️ +⚠️ +⚡ +⚧️ +⚪ +⚫ +⚰️ +⚱️ +⚽ +⚾ +⛄ +⛅ +⛈️ +⛎ +⛏️ +⛑️ +⛓️ +⛓️‍💥 +⛔ +⛩️ +⛪ +⛰️ +⛱️ +⛲ +⛳ +⛴️ +⛵ +⛷️ +⛸️ +⛹️ +⛹️‍♀️ +⛹️‍♂️ +⛹🏻 +⛹🏻‍♀️ +⛹🏻‍♂️ +⛹🏼 +⛹🏼‍♀️ +⛹🏼‍♂️ +⛹🏽 +⛹🏽‍♀️ +⛹🏽‍♂️ +⛹🏾 +⛹🏾‍♀️ +⛹🏾‍♂️ +⛹🏿 +⛹🏿‍♀️ +⛹🏿‍♂️ +⛺ +⛽ +✂️ +✅ +✈️ +✉️ +✊ +✊🏻 +✊🏼 +✊🏽 +✊🏾 +✊🏿 +✋ +✋🏻 +✋🏼 +✋🏽 +✋🏾 +✋🏿 +✌️ +✌🏻 +✌🏼 +✌🏽 +✌🏾 +✌🏿 ✍️ -💅 -🤳 -💪 -🦾 -🦿 -🦵 -🦶 -👂 -🦻 -👃 -🧠 -🫀 -🫁 -🦷 -🦴 -👀 -👁️ -👅 -👄 -👶 -🧒 -👦 -👧 -🧑 -👱 -👨 -🧔 -👨‍🦰 -👨‍🦱 -👨‍🦳 -👨‍🦲 -👩 -👩‍🦰 -🧑‍🦰 -👩‍🦱 -🧑‍🦱 -👩‍🦳 -🧑‍🦳 -👩‍🦲 -🧑‍🦲 -👱‍♀️ -👱‍♀️ -👱‍♂️ -🧓 -👴 -👵 -🙍 -🙍‍♂️ -🙍‍♀️ -🙎 -🙎‍♂️ -🙎‍♀️ -🙅 -🙅‍♂️ -🙅‍♂️ -🙅‍♀️ -🙅‍♀️ -🙆 -🙆‍♂️ -🙆‍♀️ -💁 -💁 -💁‍♂️ -💁‍♂️ -💁‍♀️ -💁‍♀️ -🙋 -🙋‍♂️ -🙋‍♀️ -🧏 -🧏‍♂️ -🧏‍♀️ -🙇 -🙇‍♂️ -🙇‍♀️ -🤦 -🤦‍♂️ -🤦‍♀️ -🤷 -🤷‍♂️ -🤷‍♀️ -🧑‍⚕️ -👨‍⚕️ -👩‍⚕️ -🧑‍🎓 -👨‍🎓 -👩‍🎓 -🧑‍🏫 -👨‍🏫 -👩‍🏫 -🧑‍⚖️ -👨‍⚖️ -👩‍⚖️ -🧑‍🌾 -👨‍🌾 -👩‍🌾 -🧑‍🍳 -👨‍🍳 -👩‍🍳 -🧑‍🔧 -👨‍🔧 -👩‍🔧 -🧑‍🏭 -👨‍🏭 -👩‍🏭 -🧑‍💼 -👨‍💼 -👩‍💼 -🧑‍🔬 -👨‍🔬 -👩‍🔬 -🧑‍💻 -👨‍💻 -👩‍💻 -🧑‍🎤 -👨‍🎤 -👩‍🎤 -🧑‍🎨 -👨‍🎨 -👩‍🎨 -🧑‍✈️ -👨‍✈️ -👩‍✈️ -🧑‍🚀 -👨‍🚀 -👩‍🚀 -🧑‍🚒 -👨‍🚒 -👩‍🚒 -👮 -👮 -👮‍♂️ -👮‍♀️ -🕵️ -🕵️‍♂️ -🕵️‍♀️ -💂 -💂‍♂️ -💂‍♀️ -🥷 -👷 -👷‍♂️ -👷‍♀️ -🤴 -👸 -👳 -👳‍♂️ -👳‍♀️ -👲 -🧕 -🤵 -🤵‍♂️ -🤵‍♀️ -👰 -👰‍♂️ -👰‍♀️ -👰‍♀️ -🤰 -🤱 -👩‍🍼 -👨‍🍼 -🧑‍🍼 -👼 -🎅 -🤶 -🧑‍🎄 -🦸 -🦸‍♂️ -🦸‍♀️ -🦹 -🦹‍♂️ -🦹‍♀️ -🧙 -🧙‍♂️ -🧙‍♀️ -🧚 -🧚‍♂️ -🧚‍♀️ -🧛 -🧛‍♂️ -🧛‍♀️ -🧜 -🧜‍♂️ -🧜‍♀️ -🧝 -🧝‍♂️ -🧝‍♀️ -🧞 -🧞‍♂️ -🧞‍♀️ -🧟 -🧟‍♂️ -🧟‍♀️ -💆 -💆‍♂️ -💆‍♀️ -💇 -💇‍♂️ -💇‍♀️ -🚶 -🚶‍♂️ -🚶‍♀️ -🧍 -🧍‍♂️ -🧍‍♀️ -🧎 -🧎‍♂️ -🧎‍♀️ -🧑‍🦯 -👨‍🦯 -👩‍🦯 -🧑‍🦼 -👨‍🦼 -👩‍🦼 -🧑‍🦽 -👨‍🦽 -👩‍🦽 -🏃 -🏃 -🏃‍♂️ -🏃‍♀️ -💃 -💃 -🕺 -🕴️ -👯 -👯‍♂️ -👯‍♀️ -🧖 -🧖‍♂️ -🧖‍♀️ -🧗 -🧗‍♂️ -🧗‍♀️ -🤺 -🏇 -⛷️ -🏂 -🏌️ -🏌️‍♂️ -🏌️‍♀️ -🏄 -🏄‍♂️ -🏄‍♀️ -🚣 -🚣‍♂️ -🚣‍♀️ -🏊 -🏊‍♂️ -🏊‍♀️ -⛹️ -⛹️‍♂️ -⛹️‍♂️ -⛹️‍♀️ -⛹️‍♀️ -🏋️ -🏋️‍♂️ -🏋️‍♀️ -🚴 -🚴‍♂️ -🚴‍♀️ -🚵 -🚵‍♂️ -🚵‍♀️ -🤸 -🤸‍♂️ -🤸‍♀️ -🤼 -🤼‍♂️ -🤼‍♀️ -🤽 -🤽‍♂️ -🤽‍♀️ -🤾 -🤾‍♂️ -🤾‍♀️ -🤹 -🤹‍♂️ -🤹‍♀️ -🧘 -🧘‍♂️ -🧘‍♀️ -🛀 -🛌 -🧑‍🤝‍🧑 -👭 -👫 -👬 -💏 -👩‍❤️‍💋‍👨 -👨‍❤️‍💋‍👨 -👩‍❤️‍💋‍👩 -💑 -👩‍❤️‍👨 -👨‍❤️‍👨 -👩‍❤️‍👩 -👪 -👨‍👩‍👦 -👨‍👩‍👧 -👨‍👩‍👧‍👦 -👨‍👩‍👦‍👦 -👨‍👩‍👧‍👧 -👨‍👨‍👦 -👨‍👨‍👧 -👨‍👨‍👧‍👦 -👨‍👨‍👦‍👦 -👨‍👨‍👧‍👧 -👩‍👩‍👦 -👩‍👩‍👧 -👩‍👩‍👧‍👦 -👩‍👩‍👦‍👦 -👩‍👩‍👧‍👧 -👨‍👦 -👨‍👦‍👦 -👨‍👧 -👨‍👧‍👦 -👨‍👧‍👧 -👩‍👦 -👩‍👦‍👦 -👩‍👧 -👩‍👧‍👦 -👩‍👧‍👧 -🗣️ -👤 -👥 -🫂 -👣 -🐵 -🐒 -🦍 -🦧 -🐶 -🐕 -🦮 -🐕‍🦺 -🐩 -🐺 -🦊 -🦝 -🐱 -🐈 -🐈‍⬛ -🦁 -🐯 -🐅 -🐆 -🐴 -🐎 -🦄 -🦓 -🦌 -🦬 -🐮 -🐂 -🐃 -🐄 -🐷 -🐖 -🐗 -🐽 -🐏 -🐑 -🐐 -🐪 -🐫 -🦙 -🦒 -🐘 -🦣 -🦏 -🦛 -🐭 -🐁 -🐀 -🐹 -🐰 -🐇 -🐿️ -🦫 -🦔 -🦇 -🐻 -🐻‍❄️ -🐨 -🐼 -🦥 -🦦 -🦨 -🦘 -🦡 -🐾 -🐾 -🦃 -🐔 -🐓 -🐣 -🐤 -🐥 -🐦 -🐧 -🕊️ -🦅 -🦆 -🦢 -🦉 -🦤 -🪶 -🦩 -🦚 -🦜 -🐸 -🐊 -🐢 -🦎 -🐍 -🐲 -🐉 -🦕 -🦖 -🐳 -🐋 -🐬 -🐬 -🦭 -🐟 -🐠 -🐡 -🦈 -🐙 -🐚 -🐌 -🦋 -🐛 -🐜 -🐝 -🐝 -🪲 -🐞 -🦗 -🪳 -🕷️ -🕸️ -🦂 -🦟 -🪰 -🪱 -🦠 -💐 -🌸 -💮 -🏵️ -🌹 -🥀 -🌺 -🌻 -🌼 -🌷 -🌱 -🪴 -🌲 -🌳 -🌴 -🌵 -🌾 -🌿 -☘️ -🍀 -🍁 -🍂 -🍃 -🍇 -🍈 -🍉 -🍊 -🍊 -🍊 -🍋 -🍌 -🍌 -🍍 -🥭 -🍎 -🍏 -🍐 -🍑 -🍒 -🍓 -🫐 -🥝 -🍅 -🫒 -🥥 -🥑 -🍆 -🥔 -🥕 -🌽 -🌶️ -🫑 -🥒 -🥬 -🥦 -🧄 -🧅 -🍄 -🥜 -🌰 -🍞 -🥐 -🥖 -🫓 -🥨 -🥯 -🥞 -🧇 -🧀 -🍖 -🍗 -🥩 -🥓 -🍔 -🍟 -🍕 -🌭 -🥪 -🌮 -🌯 -🫔 -🥙 -🧆 -🥚 -🍳 -🥘 -🍲 -🫕 -🥣 -🥗 -🍿 -🧈 -🧂 -🥫 -🍱 -🍘 -🍙 -🍚 -🍛 -🍜 -🍝 -🍠 -🍢 -🍣 -🍤 -🍥 -🥮 -🍡 -🥟 -🥠 -🥡 -🦀 -🦞 -🦐 -🦑 -🦪 -🍦 -🍧 -🍨 -🍩 -🍪 -🎂 -🍰 -🧁 -🥧 -🍫 -🍬 -🍭 -🍮 -🍯 -🍼 -🥛 -☕ -🫖 -🍵 -🍶 -🍾 -🍷 -🍸 -🍹 -🍺 -🍻 -🥂 -🥃 -🥤 -🧋 -🧃 -🧉 -🧊 -🥢 -🍽️ -🍴 -🥄 -🔪 -🔪 -🏺 -🌍 -🌎 -🌏 -🌐 -🗺️ -🗾 -🧭 -🏔️ -⛰️ -🌋 -🗻 -🏕️ -🏖️ -🏜️ -🏝️ -🏞️ -🏟️ -🏛️ -🏗️ -🧱 -🪨 -🪵 -🛖 -🏘️ -🏚️ -🏠 -🏡 -🏢 -🏣 -🏤 -🏥 -🏦 -🏨 -🏩 -🏪 -🏫 -🏬 -🏭 -🏯 -🏰 -💒 -🗼 -🗽 -⛪ -🕌 -🛕 -🕍 -⛩️ -🕋 -⛲ -⛺ -🌁 -🌃 -🏙️ -🌄 -🌅 -🌆 -🌇 -🌉 -♨️ -🎠 -🎡 -🎢 -💈 -🎪 -🚂 -🚃 -🚄 -🚅 -🚆 -🚇 -🚈 -🚉 -🚊 -🚝 -🚞 -🚋 -🚌 -🚍 -🚎 -🚎 -🚐 -🚑 -🚒 -🚓 -🚔 -🚕 -🚖 -🚗 -🚗 -🚘 -🚙 -🛻 -🚚 -🚛 -🚜 -🏎️ -🏍️ -🛵 -🦽 -🦼 -🛺 -🚲 -🛴 -🛹 -🛼 -🚏 -🛣️ -🛤️ -🛢️ -⛽ -🚨 -🚥 -🚦 -🛑 -🚧 -⚓ -⛵ -⛵ -🛶 -🚤 -🛳️ -⛴️ -🛥️ -🚢 -✈️ -🛩️ -🛫 -🛬 -🪂 -💺 -🚁 -🚟 -🚠 -🚡 -🛰️ -🚀 -🛸 -🛎️ -🧳 -⌛ -⏳ -⌚ -⏰ -⏱️ -⏲️ -🕰️ -🕛 -🕧 -🕐 -🕜 -🕑 -🕝 -🕒 -🕞 -🕓 -🕟 -🕔 -🕠 -🕕 -🕡 -🕖 -🕢 -🕗 -🕣 -🕘 -🕤 -🕙 -🕥 -🕚 -🕦 -🌑 -🌒 -🌓 -🌔 -🌔 -🌕 -🌖 -🌗 -🌘 -🌙 -🌚 -🌛 -🌜 -🌡️ -☀️ -🌝 -🌞 -🪐 -⭐ -🌟 -🌠 -🌌 -☁️ -⛅ -⛈️ -🌤️ -🌥️ -🌦️ -🌧️ -🌨️ -🌩️ -🌪️ -🌫️ -🌬️ -🌀 -🌈 -🌂 -☂️ -☔ -⛱️ -⚡ -❄️ -☃️ -⛄ -☄️ -🔥 -💧 -🌊 -🎃 -🎄 -🎆 -🎇 -🧨 -✨ -🎈 -🎉 -🎊 -🎋 -🎍 -🎎 -🎏 -🎐 -🎑 -🧧 -🎀 -🎁 -🎗️ -🎟️ -🎫 -🎖️ -🏆 -🏅 -🥇 -🥈 -🥉 -⚽ -⚾ -🥎 -🏀 -🏐 -🏈 -🏉 -🎾 -🥏 -🎳 -🏏 -🏑 -🏒 -🥍 -🏓 -🏸 -🥊 -🥋 -🥅 -⛳ -⛸️ -🎣 -🤿 -🎽 -🎿 -🛷 -🥌 -🎯 -🪀 -🪁 -🎱 -🔮 -🪄 -🧿 -🎮 -🕹️ -🎰 -🎲 -🧩 -🧸 -🪅 -🪆 -♠️ -♥️ -♦️ -♣️ -♟️ -🃏 -🀄 -🎴 -🎭 -🖼️ -🎨 -🧵 -🪡 -🧶 -🪢 -👓 -🕶️ -🥽 -🥼 -🦺 -👔 -👕 -👕 -👖 -🧣 -🧤 -🧥 -🧦 -👗 -👘 -🥻 -🩱 -🩲 -🩳 -👙 -👚 -👛 -👜 -👝 -🛍️ -🎒 -🩴 -👞 -👞 -👟 -🥾 -🥿 -👠 -👡 -🩰 -👢 -👑 -👒 -🎩 -🎓 -🧢 -🪖 -⛑️ -📿 -💄 -💍 -💎 -🔇 -🔈 -🔉 -🔊 -📢 -📣 -📯 -🔔 -🔕 -🎼 -🎵 -🎶 -🎙️ -🎚️ -🎛️ -🎤 -🎧 -📻 -🎷 -🪗 -🎸 -🎹 -🎺 -🎻 -🪕 -🥁 -🪘 -📱 -📲 -☎️ -☎️ -📞 -📟 -📠 -🔋 -🔌 -💻 -🖥️ -🖨️ -⌨️ -🖱️ -🖲️ -💽 -💾 -💿 -📀 -🧮 -🎥 -🎞️ -📽️ -🎬 -📺 -📷 -📸 -📹 -📼 -🔍 -🔎 -🕯️ -💡 -🔦 -🏮 -🏮 -🪔 -📔 -📕 -📖 -📖 -📗 -📘 -📙 -📚 -📓 -📒 -📃 -📜 -📄 -📰 -🗞️ -📑 -🔖 -🏷️ -💰 -🪙 -💴 -💵 -💶 -💷 -💸 -💳 -🧾 -💹 -✉️ -📧 -📧 -📨 -📩 -📤 -📥 -📦 -📫 -📪 -📬 -📭 -📮 -🗳️ -✏️ -✒️ -🖋️ -🖊️ -🖌️ -🖍️ -📝 -📝 -💼 -📁 -📂 -🗂️ -📅 -📆 -🗒️ -🗓️ -📇 -📈 -📉 -📊 -📋 -📌 -📍 -📎 -🖇️ -📏 -📐 -✂️ -🗃️ -🗄️ -🗑️ -🔒 -🔓 -🔏 -🔐 -🔑 -🗝️ -🔨 -🪓 -⛏️ -⚒️ -🛠️ -🗡️ -⚔️ -🔫 -🪃 -🏹 -🛡️ -🪚 -🔧 -🪛 -🔩 -⚙️ -🗜️ -⚖️ -🦯 -🔗 -⛓️ -🪝 -🧰 -🧲 -🪜 -⚗️ -🧪 -🧫 -🧬 -🔬 -🔭 -📡 -💉 -🩸 -💊 -🩹 -🩺 -🚪 -🛗 -🪞 -🪟 -🛏️ -🛋️ -🪑 -🚽 -🪠 -🚿 -🛁 -🪤 -🪒 -🧴 -🧷 -🧹 -🧺 -🧻 -🪣 -🧼 -🪥 -🧽 -🧯 -🛒 -🚬 -⚰️ -🪦 -⚱️ -🗿 -🪧 -🏧 -🚮 -🚰 -♿ -🚹 -🚺 -🚻 -🚼 -🚾 -🛂 -🛃 -🛄 -🛅 -⚠️ -🚸 -⛔ -🚫 -🚳 -🚭 -🚯 -🚱 -🚷 -📵 -🔞 -☢️ -☣️ -⬆️ -↗️ -➡️ -↘️ -⬇️ -↙️ -⬅️ -↖️ -↕️ -↔️ -↩️ -↪️ -⤴️ -⤵️ -🔃 -🔄 -🔙 -🔚 -🔛 -🔜 -🔝 -🛐 -⚛️ -🕉️ -✡️ -☸️ -☯️ -✝️ -☦️ -☪️ -☮️ -🕎 -🔯 -♈ -♉ -♊ -♋ -♌ -♍ -♎ -♏ -♐ -♑ -♒ -♓ -⛎ -🔀 -🔁 -🔂 -▶️ -⏩ -⏭️ -⏯️ -◀️ -⏪ -⏮️ -🔼 -⏫ -🔽 -⏬ -⏸️ -⏹️ -⏺️ -⏏️ -🎦 -🔅 -🔆 -📶 -📳 -📴 -♀️ -♂️ -⚧️ +✍🏻 +✍🏼 +✍🏽 +✍🏾 +✍🏿 +✏️ +✒️ +✔️ ✖️ -➕ -➖ -➗ -♾️ -‼️ -⁉️ +✝️ +✡️ +✨ +✳️ +✴️ +❄️ +❇️ +❌ +❎ ❓ ❔ ❕ ❗ -❗ -〰️ -💱 -💲 -⚕️ -♻️ -⚜️ -🔱 -📛 -🔰 -⭕ -✅ -☑️ -✔️ -❌ -❎ +❣️ +❤️ +❤️‍🔥 +❤️‍🩹 +➕ +➖ +➗ +➡️ ➰ ➿ +⤴️ +⤵️ +⬅️ +⬆️ +⬇️ +⬛ +⬜ +⭐ +⭕ +〰️ 〽️ -✳️ -✴️ -❇️ -©️ -®️ -™️ -#️⃣ -*️⃣ -0️⃣ -1️⃣ -2️⃣ -3️⃣ -4️⃣ -5️⃣ -6️⃣ -7️⃣ -8️⃣ -9️⃣ -🔟 -🔠 -🔡 -🔣 -🔤 +㊗️ +㊙️ +🀄 +🃏 🅰️ -🆎 🅱️ +🅾️ +🅿️ +🆎 🆑 🆒 🆓 -ℹ️ 🆔 -Ⓜ️ 🆕 🆖 -🅾️ 🆗 -🅿️ 🆘 🆙 🆚 -🈁 -🈂️ -🈷️ -🈶 -🈯 -🉐 -🈹 -🈚 -🈲 -🉑 -🈸 -🈴 -🈳 -㊗️ -㊙️ -🈺 -🈵 -🔴 -🟠 -🟡 -🟢 -🔵 -🟣 -🟤 -⚫ -⚪ -🟥 -🟧 -🟨 -🟩 -🟦 -🟪 -🟫 -⬛ -⬜ -◼️ -◻️ -◾ -◽ -▪️ -▫️ -🔶 -🔷 -🔸 -🔹 -🔺 -🔻 -💠 -🔘 -🔳 -🔲 -🏁 -🚩 -🎌 -🏴 -🏳️ -🏳️‍🌈 -🏳️‍⚧️ -🏴‍☠️ 🇦🇨 🇦🇩 🇦🇪 @@ -1636,6 +293,7 @@ 🇨🇳 🇨🇴 🇨🇵 +🇨🇶 🇨🇷 🇨🇺 🇨🇻 @@ -1659,7 +317,6 @@ 🇪🇸 🇪🇹 🇪🇺 -🇪🇺 🇫🇮 🇫🇯 🇫🇰 @@ -1668,7 +325,6 @@ 🇫🇷 🇬🇦 🇬🇧 -🇬🇧 🇬🇩 🇬🇪 🇬🇫 @@ -1845,6 +501,3444 @@ 🇿🇦 🇿🇲 🇿🇼 +🈁 +🈂️ +🈚 +🈯 +🈲 +🈳 +🈴 +🈵 +🈶 +🈷️ +🈸 +🈹 +🈺 +🉐 +🉑 +🌀 +🌁 +🌂 +🌃 +🌄 +🌅 +🌆 +🌇 +🌈 +🌉 +🌊 +🌋 +🌌 +🌍 +🌎 +🌏 +🌐 +🌑 +🌒 +🌓 +🌔 +🌕 +🌖 +🌗 +🌘 +🌙 +🌚 +🌛 +🌜 +🌝 +🌞 +🌟 +🌠 +🌡️ +🌤️ +🌥️ +🌦️ +🌧️ +🌨️ +🌩️ +🌪️ +🌫️ +🌬️ +🌭 +🌮 +🌯 +🌰 +🌱 +🌲 +🌳 +🌴 +🌵 +🌶️ +🌷 +🌸 +🌹 +🌺 +🌻 +🌼 +🌽 +🌾 +🌿 +🍀 +🍁 +🍂 +🍃 +🍄 +🍄‍🟫 +🍅 +🍆 +🍇 +🍈 +🍉 +🍊 +🍋 +🍋‍🟩 +🍌 +🍍 +🍎 +🍏 +🍐 +🍑 +🍒 +🍓 +🍔 +🍕 +🍖 +🍗 +🍘 +🍙 +🍚 +🍛 +🍜 +🍝 +🍞 +🍟 +🍠 +🍡 +🍢 +🍣 +🍤 +🍥 +🍦 +🍧 +🍨 +🍩 +🍪 +🍫 +🍬 +🍭 +🍮 +🍯 +🍰 +🍱 +🍲 +🍳 +🍴 +🍵 +🍶 +🍷 +🍸 +🍹 +🍺 +🍻 +🍼 +🍽️ +🍾 +🍿 +🎀 +🎁 +🎂 +🎃 +🎄 +🎅 +🎅🏻 +🎅🏼 +🎅🏽 +🎅🏾 +🎅🏿 +🎆 +🎇 +🎈 +🎉 +🎊 +🎋 +🎌 +🎍 +🎎 +🎏 +🎐 +🎑 +🎒 +🎓 +🎖️ +🎗️ +🎙️ +🎚️ +🎛️ +🎞️ +🎟️ +🎠 +🎡 +🎢 +🎣 +🎤 +🎥 +🎦 +🎧 +🎨 +🎩 +🎪 +🎫 +🎬 +🎭 +🎮 +🎯 +🎰 +🎱 +🎲 +🎳 +🎴 +🎵 +🎶 +🎷 +🎸 +🎹 +🎺 +🎻 +🎼 +🎽 +🎾 +🎿 +🏀 +🏁 +🏂 +🏂🏻 +🏂🏼 +🏂🏽 +🏂🏾 +🏂🏿 +🏃 +🏃‍♀️ +🏃‍♀️‍➡️ +🏃‍♂️ +🏃‍♂️‍➡️ +🏃‍➡️ +🏃🏻 +🏃🏻‍♀️ +🏃🏻‍♀️‍➡️ +🏃🏻‍♂️ +🏃🏻‍♂️‍➡️ +🏃🏻‍➡️ +🏃🏼 +🏃🏼‍♀️ +🏃🏼‍♀️‍➡️ +🏃🏼‍♂️ +🏃🏼‍♂️‍➡️ +🏃🏼‍➡️ +🏃🏽 +🏃🏽‍♀️ +🏃🏽‍♀️‍➡️ +🏃🏽‍♂️ +🏃🏽‍♂️‍➡️ +🏃🏽‍➡️ +🏃🏾 +🏃🏾‍♀️ +🏃🏾‍♀️‍➡️ +🏃🏾‍♂️ +🏃🏾‍♂️‍➡️ +🏃🏾‍➡️ +🏃🏿 +🏃🏿‍♀️ +🏃🏿‍♀️‍➡️ +🏃🏿‍♂️ +🏃🏿‍♂️‍➡️ +🏃🏿‍➡️ +🏄 +🏄‍♀️ +🏄‍♂️ +🏄🏻 +🏄🏻‍♀️ +🏄🏻‍♂️ +🏄🏼 +🏄🏼‍♀️ +🏄🏼‍♂️ +🏄🏽 +🏄🏽‍♀️ +🏄🏽‍♂️ +🏄🏾 +🏄🏾‍♀️ +🏄🏾‍♂️ +🏄🏿 +🏄🏿‍♀️ +🏄🏿‍♂️ +🏅 +🏆 +🏇 +🏇🏻 +🏇🏼 +🏇🏽 +🏇🏾 +🏇🏿 +🏈 +🏉 +🏊 +🏊‍♀️ +🏊‍♂️ +🏊🏻 +🏊🏻‍♀️ +🏊🏻‍♂️ +🏊🏼 +🏊🏼‍♀️ +🏊🏼‍♂️ +🏊🏽 +🏊🏽‍♀️ +🏊🏽‍♂️ +🏊🏾 +🏊🏾‍♀️ +🏊🏾‍♂️ +🏊🏿 +🏊🏿‍♀️ +🏊🏿‍♂️ +🏋️ +🏋️‍♀️ +🏋️‍♂️ +🏋🏻 +🏋🏻‍♀️ +🏋🏻‍♂️ +🏋🏼 +🏋🏼‍♀️ +🏋🏼‍♂️ +🏋🏽 +🏋🏽‍♀️ +🏋🏽‍♂️ +🏋🏾 +🏋🏾‍♀️ +🏋🏾‍♂️ +🏋🏿 +🏋🏿‍♀️ +🏋🏿‍♂️ +🏌️ +🏌️‍♀️ +🏌️‍♂️ +🏌🏻 +🏌🏻‍♀️ +🏌🏻‍♂️ +🏌🏼 +🏌🏼‍♀️ +🏌🏼‍♂️ +🏌🏽 +🏌🏽‍♀️ +🏌🏽‍♂️ +🏌🏾 +🏌🏾‍♀️ +🏌🏾‍♂️ +🏌🏿 +🏌🏿‍♀️ +🏌🏿‍♂️ +🏍️ +🏎️ +🏏 +🏐 +🏑 +🏒 +🏓 +🏔️ +🏕️ +🏖️ +🏗️ +🏘️ +🏙️ +🏚️ +🏛️ +🏜️ +🏝️ +🏞️ +🏟️ +🏠 +🏡 +🏢 +🏣 +🏤 +🏥 +🏦 +🏧 +🏨 +🏩 +🏪 +🏫 +🏬 +🏭 +🏮 +🏯 +🏰 +🏳️ +🏳️‍⚧️ +🏳️‍🌈 +🏴 +🏴‍☠️ 🏴󠁧󠁢󠁥󠁮󠁧󠁿 🏴󠁧󠁢󠁳󠁣󠁴󠁿 -🏴󠁧󠁢󠁷󠁬󠁳󠁿 \ No newline at end of file +🏴󠁧󠁢󠁷󠁬󠁳󠁿 +🏵️ +🏷️ +🏸 +🏹 +🏺 +🐀 +🐁 +🐂 +🐃 +🐄 +🐅 +🐆 +🐇 +🐈 +🐈‍⬛ +🐉 +🐊 +🐋 +🐌 +🐍 +🐎 +🐏 +🐐 +🐑 +🐒 +🐓 +🐔 +🐕 +🐕‍🦺 +🐖 +🐗 +🐘 +🐙 +🐚 +🐛 +🐜 +🐝 +🐞 +🐟 +🐠 +🐡 +🐢 +🐣 +🐤 +🐥 +🐦 +🐦‍⬛ +🐦‍🔥 +🐧 +🐨 +🐩 +🐪 +🐫 +🐬 +🐭 +🐮 +🐯 +🐰 +🐱 +🐲 +🐳 +🐴 +🐵 +🐶 +🐷 +🐸 +🐹 +🐺 +🐻 +🐻‍❄️ +🐼 +🐽 +🐾 +🐿️ +👀 +👁️ +👁️‍🗨️ +👂 +👂🏻 +👂🏼 +👂🏽 +👂🏾 +👂🏿 +👃 +👃🏻 +👃🏼 +👃🏽 +👃🏾 +👃🏿 +👄 +👅 +👆 +👆🏻 +👆🏼 +👆🏽 +👆🏾 +👆🏿 +👇 +👇🏻 +👇🏼 +👇🏽 +👇🏾 +👇🏿 +👈 +👈🏻 +👈🏼 +👈🏽 +👈🏾 +👈🏿 +👉 +👉🏻 +👉🏼 +👉🏽 +👉🏾 +👉🏿 +👊 +👊🏻 +👊🏼 +👊🏽 +👊🏾 +👊🏿 +👋 +👋🏻 +👋🏼 +👋🏽 +👋🏾 +👋🏿 +👌 +👌🏻 +👌🏼 +👌🏽 +👌🏾 +👌🏿 +👍 +👍🏻 +👍🏼 +👍🏽 +👍🏾 +👍🏿 +👎 +👎🏻 +👎🏼 +👎🏽 +👎🏾 +👎🏿 +👏 +👏🏻 +👏🏼 +👏🏽 +👏🏾 +👏🏿 +👐 +👐🏻 +👐🏼 +👐🏽 +👐🏾 +👐🏿 +👑 +👒 +👓 +👔 +👕 +👖 +👗 +👘 +👙 +👚 +👛 +👜 +👝 +👞 +👟 +👠 +👡 +👢 +👣 +👤 +👥 +👦 +👦🏻 +👦🏼 +👦🏽 +👦🏾 +👦🏿 +👧 +👧🏻 +👧🏼 +👧🏽 +👧🏾 +👧🏿 +👨 +👨‍⚕️ +👨‍⚖️ +👨‍✈️ +👨‍❤️‍👨 +👨‍❤️‍💋‍👨 +👨‍🌾 +👨‍🍳 +👨‍🍼 +👨‍🎓 +👨‍🎤 +👨‍🎨 +👨‍🏫 +👨‍🏭 +👨‍👦 +👨‍👦‍👦 +👨‍👧 +👨‍👧‍👦 +👨‍👧‍👧 +👨‍👨‍👦 +👨‍👨‍👦‍👦 +👨‍👨‍👧 +👨‍👨‍👧‍👦 +👨‍👨‍👧‍👧 +👨‍👩‍👦 +👨‍👩‍👦‍👦 +👨‍👩‍👧 +👨‍👩‍👧‍👦 +👨‍👩‍👧‍👧 +👨‍💻 +👨‍💼 +👨‍🔧 +👨‍🔬 +👨‍🚀 +👨‍🚒 +👨‍🦯 +👨‍🦯‍➡️ +👨‍🦰 +👨‍🦱 +👨‍🦲 +👨‍🦳 +👨‍🦼 +👨‍🦼‍➡️ +👨‍🦽 +👨‍🦽‍➡️ +👨🏻 +👨🏻‍⚕️ +👨🏻‍⚖️ +👨🏻‍✈️ +👨🏻‍❤️‍👨🏻 +👨🏻‍❤️‍👨🏼 +👨🏻‍❤️‍👨🏽 +👨🏻‍❤️‍👨🏾 +👨🏻‍❤️‍👨🏿 +👨🏻‍❤️‍💋‍👨🏻 +👨🏻‍❤️‍💋‍👨🏼 +👨🏻‍❤️‍💋‍👨🏽 +👨🏻‍❤️‍💋‍👨🏾 +👨🏻‍❤️‍💋‍👨🏿 +👨🏻‍🌾 +👨🏻‍🍳 +👨🏻‍🍼 +👨🏻‍🎓 +👨🏻‍🎤 +👨🏻‍🎨 +👨🏻‍🏫 +👨🏻‍🏭 +👨🏻‍🐰‍👨🏼 +👨🏻‍🐰‍👨🏽 +👨🏻‍🐰‍👨🏾 +👨🏻‍🐰‍👨🏿 +👨🏻‍💻 +👨🏻‍💼 +👨🏻‍🔧 +👨🏻‍🔬 +👨🏻‍🚀 +👨🏻‍🚒 +👨🏻‍🤝‍👨🏼 +👨🏻‍🤝‍👨🏽 +👨🏻‍🤝‍👨🏾 +👨🏻‍🤝‍👨🏿 +👨🏻‍🦯 +👨🏻‍🦯‍➡️ +👨🏻‍🦰 +👨🏻‍🦱 +👨🏻‍🦲 +👨🏻‍🦳 +👨🏻‍🦼 +👨🏻‍🦼‍➡️ +👨🏻‍🦽 +👨🏻‍🦽‍➡️ +👨🏻‍🫯‍👨🏼 +👨🏻‍🫯‍👨🏽 +👨🏻‍🫯‍👨🏾 +👨🏻‍🫯‍👨🏿 +👨🏼 +👨🏼‍⚕️ +👨🏼‍⚖️ +👨🏼‍✈️ +👨🏼‍❤️‍👨🏻 +👨🏼‍❤️‍👨🏼 +👨🏼‍❤️‍👨🏽 +👨🏼‍❤️‍👨🏾 +👨🏼‍❤️‍👨🏿 +👨🏼‍❤️‍💋‍👨🏻 +👨🏼‍❤️‍💋‍👨🏼 +👨🏼‍❤️‍💋‍👨🏽 +👨🏼‍❤️‍💋‍👨🏾 +👨🏼‍❤️‍💋‍👨🏿 +👨🏼‍🌾 +👨🏼‍🍳 +👨🏼‍🍼 +👨🏼‍🎓 +👨🏼‍🎤 +👨🏼‍🎨 +👨🏼‍🏫 +👨🏼‍🏭 +👨🏼‍🐰‍👨🏻 +👨🏼‍🐰‍👨🏽 +👨🏼‍🐰‍👨🏾 +👨🏼‍🐰‍👨🏿 +👨🏼‍💻 +👨🏼‍💼 +👨🏼‍🔧 +👨🏼‍🔬 +👨🏼‍🚀 +👨🏼‍🚒 +👨🏼‍🤝‍👨🏻 +👨🏼‍🤝‍👨🏽 +👨🏼‍🤝‍👨🏾 +👨🏼‍🤝‍👨🏿 +👨🏼‍🦯 +👨🏼‍🦯‍➡️ +👨🏼‍🦰 +👨🏼‍🦱 +👨🏼‍🦲 +👨🏼‍🦳 +👨🏼‍🦼 +👨🏼‍🦼‍➡️ +👨🏼‍🦽 +👨🏼‍🦽‍➡️ +👨🏼‍🫯‍👨🏻 +👨🏼‍🫯‍👨🏽 +👨🏼‍🫯‍👨🏾 +👨🏼‍🫯‍👨🏿 +👨🏽 +👨🏽‍⚕️ +👨🏽‍⚖️ +👨🏽‍✈️ +👨🏽‍❤️‍👨🏻 +👨🏽‍❤️‍👨🏼 +👨🏽‍❤️‍👨🏽 +👨🏽‍❤️‍👨🏾 +👨🏽‍❤️‍👨🏿 +👨🏽‍❤️‍💋‍👨🏻 +👨🏽‍❤️‍💋‍👨🏼 +👨🏽‍❤️‍💋‍👨🏽 +👨🏽‍❤️‍💋‍👨🏾 +👨🏽‍❤️‍💋‍👨🏿 +👨🏽‍🌾 +👨🏽‍🍳 +👨🏽‍🍼 +👨🏽‍🎓 +👨🏽‍🎤 +👨🏽‍🎨 +👨🏽‍🏫 +👨🏽‍🏭 +👨🏽‍🐰‍👨🏻 +👨🏽‍🐰‍👨🏼 +👨🏽‍🐰‍👨🏾 +👨🏽‍🐰‍👨🏿 +👨🏽‍💻 +👨🏽‍💼 +👨🏽‍🔧 +👨🏽‍🔬 +👨🏽‍🚀 +👨🏽‍🚒 +👨🏽‍🤝‍👨🏻 +👨🏽‍🤝‍👨🏼 +👨🏽‍🤝‍👨🏾 +👨🏽‍🤝‍👨🏿 +👨🏽‍🦯 +👨🏽‍🦯‍➡️ +👨🏽‍🦰 +👨🏽‍🦱 +👨🏽‍🦲 +👨🏽‍🦳 +👨🏽‍🦼 +👨🏽‍🦼‍➡️ +👨🏽‍🦽 +👨🏽‍🦽‍➡️ +👨🏽‍🫯‍👨🏻 +👨🏽‍🫯‍👨🏼 +👨🏽‍🫯‍👨🏾 +👨🏽‍🫯‍👨🏿 +👨🏾 +👨🏾‍⚕️ +👨🏾‍⚖️ +👨🏾‍✈️ +👨🏾‍❤️‍👨🏻 +👨🏾‍❤️‍👨🏼 +👨🏾‍❤️‍👨🏽 +👨🏾‍❤️‍👨🏾 +👨🏾‍❤️‍👨🏿 +👨🏾‍❤️‍💋‍👨🏻 +👨🏾‍❤️‍💋‍👨🏼 +👨🏾‍❤️‍💋‍👨🏽 +👨🏾‍❤️‍💋‍👨🏾 +👨🏾‍❤️‍💋‍👨🏿 +👨🏾‍🌾 +👨🏾‍🍳 +👨🏾‍🍼 +👨🏾‍🎓 +👨🏾‍🎤 +👨🏾‍🎨 +👨🏾‍🏫 +👨🏾‍🏭 +👨🏾‍🐰‍👨🏻 +👨🏾‍🐰‍👨🏼 +👨🏾‍🐰‍👨🏽 +👨🏾‍🐰‍👨🏿 +👨🏾‍💻 +👨🏾‍💼 +👨🏾‍🔧 +👨🏾‍🔬 +👨🏾‍🚀 +👨🏾‍🚒 +👨🏾‍🤝‍👨🏻 +👨🏾‍🤝‍👨🏼 +👨🏾‍🤝‍👨🏽 +👨🏾‍🤝‍👨🏿 +👨🏾‍🦯 +👨🏾‍🦯‍➡️ +👨🏾‍🦰 +👨🏾‍🦱 +👨🏾‍🦲 +👨🏾‍🦳 +👨🏾‍🦼 +👨🏾‍🦼‍➡️ +👨🏾‍🦽 +👨🏾‍🦽‍➡️ +👨🏾‍🫯‍👨🏻 +👨🏾‍🫯‍👨🏼 +👨🏾‍🫯‍👨🏽 +👨🏾‍🫯‍👨🏿 +👨🏿 +👨🏿‍⚕️ +👨🏿‍⚖️ +👨🏿‍✈️ +👨🏿‍❤️‍👨🏻 +👨🏿‍❤️‍👨🏼 +👨🏿‍❤️‍👨🏽 +👨🏿‍❤️‍👨🏾 +👨🏿‍❤️‍👨🏿 +👨🏿‍❤️‍💋‍👨🏻 +👨🏿‍❤️‍💋‍👨🏼 +👨🏿‍❤️‍💋‍👨🏽 +👨🏿‍❤️‍💋‍👨🏾 +👨🏿‍❤️‍💋‍👨🏿 +👨🏿‍🌾 +👨🏿‍🍳 +👨🏿‍🍼 +👨🏿‍🎓 +👨🏿‍🎤 +👨🏿‍🎨 +👨🏿‍🏫 +👨🏿‍🏭 +👨🏿‍🐰‍👨🏻 +👨🏿‍🐰‍👨🏼 +👨🏿‍🐰‍👨🏽 +👨🏿‍🐰‍👨🏾 +👨🏿‍💻 +👨🏿‍💼 +👨🏿‍🔧 +👨🏿‍🔬 +👨🏿‍🚀 +👨🏿‍🚒 +👨🏿‍🤝‍👨🏻 +👨🏿‍🤝‍👨🏼 +👨🏿‍🤝‍👨🏽 +👨🏿‍🤝‍👨🏾 +👨🏿‍🦯 +👨🏿‍🦯‍➡️ +👨🏿‍🦰 +👨🏿‍🦱 +👨🏿‍🦲 +👨🏿‍🦳 +👨🏿‍🦼 +👨🏿‍🦼‍➡️ +👨🏿‍🦽 +👨🏿‍🦽‍➡️ +👨🏿‍🫯‍👨🏻 +👨🏿‍🫯‍👨🏼 +👨🏿‍🫯‍👨🏽 +👨🏿‍🫯‍👨🏾 +👩 +👩‍⚕️ +👩‍⚖️ +👩‍✈️ +👩‍❤️‍👨 +👩‍❤️‍👩 +👩‍❤️‍💋‍👨 +👩‍❤️‍💋‍👩 +👩‍🌾 +👩‍🍳 +👩‍🍼 +👩‍🎓 +👩‍🎤 +👩‍🎨 +👩‍🏫 +👩‍🏭 +👩‍👦 +👩‍👦‍👦 +👩‍👧 +👩‍👧‍👦 +👩‍👧‍👧 +👩‍👩‍👦 +👩‍👩‍👦‍👦 +👩‍👩‍👧 +👩‍👩‍👧‍👦 +👩‍👩‍👧‍👧 +👩‍💻 +👩‍💼 +👩‍🔧 +👩‍🔬 +👩‍🚀 +👩‍🚒 +👩‍🦯 +👩‍🦯‍➡️ +👩‍🦰 +👩‍🦱 +👩‍🦲 +👩‍🦳 +👩‍🦼 +👩‍🦼‍➡️ +👩‍🦽 +👩‍🦽‍➡️ +👩🏻 +👩🏻‍⚕️ +👩🏻‍⚖️ +👩🏻‍✈️ +👩🏻‍❤️‍👨🏻 +👩🏻‍❤️‍👨🏼 +👩🏻‍❤️‍👨🏽 +👩🏻‍❤️‍👨🏾 +👩🏻‍❤️‍👨🏿 +👩🏻‍❤️‍👩🏻 +👩🏻‍❤️‍👩🏼 +👩🏻‍❤️‍👩🏽 +👩🏻‍❤️‍👩🏾 +👩🏻‍❤️‍👩🏿 +👩🏻‍❤️‍💋‍👨🏻 +👩🏻‍❤️‍💋‍👨🏼 +👩🏻‍❤️‍💋‍👨🏽 +👩🏻‍❤️‍💋‍👨🏾 +👩🏻‍❤️‍💋‍👨🏿 +👩🏻‍❤️‍💋‍👩🏻 +👩🏻‍❤️‍💋‍👩🏼 +👩🏻‍❤️‍💋‍👩🏽 +👩🏻‍❤️‍💋‍👩🏾 +👩🏻‍❤️‍💋‍👩🏿 +👩🏻‍🌾 +👩🏻‍🍳 +👩🏻‍🍼 +👩🏻‍🎓 +👩🏻‍🎤 +👩🏻‍🎨 +👩🏻‍🏫 +👩🏻‍🏭 +👩🏻‍🐰‍👩🏼 +👩🏻‍🐰‍👩🏽 +👩🏻‍🐰‍👩🏾 +👩🏻‍🐰‍👩🏿 +👩🏻‍💻 +👩🏻‍💼 +👩🏻‍🔧 +👩🏻‍🔬 +👩🏻‍🚀 +👩🏻‍🚒 +👩🏻‍🤝‍👨🏼 +👩🏻‍🤝‍👨🏽 +👩🏻‍🤝‍👨🏾 +👩🏻‍🤝‍👨🏿 +👩🏻‍🤝‍👩🏼 +👩🏻‍🤝‍👩🏽 +👩🏻‍🤝‍👩🏾 +👩🏻‍🤝‍👩🏿 +👩🏻‍🦯 +👩🏻‍🦯‍➡️ +👩🏻‍🦰 +👩🏻‍🦱 +👩🏻‍🦲 +👩🏻‍🦳 +👩🏻‍🦼 +👩🏻‍🦼‍➡️ +👩🏻‍🦽 +👩🏻‍🦽‍➡️ +👩🏻‍🫯‍👩🏼 +👩🏻‍🫯‍👩🏽 +👩🏻‍🫯‍👩🏾 +👩🏻‍🫯‍👩🏿 +👩🏼 +👩🏼‍⚕️ +👩🏼‍⚖️ +👩🏼‍✈️ +👩🏼‍❤️‍👨🏻 +👩🏼‍❤️‍👨🏼 +👩🏼‍❤️‍👨🏽 +👩🏼‍❤️‍👨🏾 +👩🏼‍❤️‍👨🏿 +👩🏼‍❤️‍👩🏻 +👩🏼‍❤️‍👩🏼 +👩🏼‍❤️‍👩🏽 +👩🏼‍❤️‍👩🏾 +👩🏼‍❤️‍👩🏿 +👩🏼‍❤️‍💋‍👨🏻 +👩🏼‍❤️‍💋‍👨🏼 +👩🏼‍❤️‍💋‍👨🏽 +👩🏼‍❤️‍💋‍👨🏾 +👩🏼‍❤️‍💋‍👨🏿 +👩🏼‍❤️‍💋‍👩🏻 +👩🏼‍❤️‍💋‍👩🏼 +👩🏼‍❤️‍💋‍👩🏽 +👩🏼‍❤️‍💋‍👩🏾 +👩🏼‍❤️‍💋‍👩🏿 +👩🏼‍🌾 +👩🏼‍🍳 +👩🏼‍🍼 +👩🏼‍🎓 +👩🏼‍🎤 +👩🏼‍🎨 +👩🏼‍🏫 +👩🏼‍🏭 +👩🏼‍🐰‍👩🏻 +👩🏼‍🐰‍👩🏽 +👩🏼‍🐰‍👩🏾 +👩🏼‍🐰‍👩🏿 +👩🏼‍💻 +👩🏼‍💼 +👩🏼‍🔧 +👩🏼‍🔬 +👩🏼‍🚀 +👩🏼‍🚒 +👩🏼‍🤝‍👨🏻 +👩🏼‍🤝‍👨🏽 +👩🏼‍🤝‍👨🏾 +👩🏼‍🤝‍👨🏿 +👩🏼‍🤝‍👩🏻 +👩🏼‍🤝‍👩🏽 +👩🏼‍🤝‍👩🏾 +👩🏼‍🤝‍👩🏿 +👩🏼‍🦯 +👩🏼‍🦯‍➡️ +👩🏼‍🦰 +👩🏼‍🦱 +👩🏼‍🦲 +👩🏼‍🦳 +👩🏼‍🦼 +👩🏼‍🦼‍➡️ +👩🏼‍🦽 +👩🏼‍🦽‍➡️ +👩🏼‍🫯‍👩🏻 +👩🏼‍🫯‍👩🏽 +👩🏼‍🫯‍👩🏾 +👩🏼‍🫯‍👩🏿 +👩🏽 +👩🏽‍⚕️ +👩🏽‍⚖️ +👩🏽‍✈️ +👩🏽‍❤️‍👨🏻 +👩🏽‍❤️‍👨🏼 +👩🏽‍❤️‍👨🏽 +👩🏽‍❤️‍👨🏾 +👩🏽‍❤️‍👨🏿 +👩🏽‍❤️‍👩🏻 +👩🏽‍❤️‍👩🏼 +👩🏽‍❤️‍👩🏽 +👩🏽‍❤️‍👩🏾 +👩🏽‍❤️‍👩🏿 +👩🏽‍❤️‍💋‍👨🏻 +👩🏽‍❤️‍💋‍👨🏼 +👩🏽‍❤️‍💋‍👨🏽 +👩🏽‍❤️‍💋‍👨🏾 +👩🏽‍❤️‍💋‍👨🏿 +👩🏽‍❤️‍💋‍👩🏻 +👩🏽‍❤️‍💋‍👩🏼 +👩🏽‍❤️‍💋‍👩🏽 +👩🏽‍❤️‍💋‍👩🏾 +👩🏽‍❤️‍💋‍👩🏿 +👩🏽‍🌾 +👩🏽‍🍳 +👩🏽‍🍼 +👩🏽‍🎓 +👩🏽‍🎤 +👩🏽‍🎨 +👩🏽‍🏫 +👩🏽‍🏭 +👩🏽‍🐰‍👩🏻 +👩🏽‍🐰‍👩🏼 +👩🏽‍🐰‍👩🏾 +👩🏽‍🐰‍👩🏿 +👩🏽‍💻 +👩🏽‍💼 +👩🏽‍🔧 +👩🏽‍🔬 +👩🏽‍🚀 +👩🏽‍🚒 +👩🏽‍🤝‍👨🏻 +👩🏽‍🤝‍👨🏼 +👩🏽‍🤝‍👨🏾 +👩🏽‍🤝‍👨🏿 +👩🏽‍🤝‍👩🏻 +👩🏽‍🤝‍👩🏼 +👩🏽‍🤝‍👩🏾 +👩🏽‍🤝‍👩🏿 +👩🏽‍🦯 +👩🏽‍🦯‍➡️ +👩🏽‍🦰 +👩🏽‍🦱 +👩🏽‍🦲 +👩🏽‍🦳 +👩🏽‍🦼 +👩🏽‍🦼‍➡️ +👩🏽‍🦽 +👩🏽‍🦽‍➡️ +👩🏽‍🫯‍👩🏻 +👩🏽‍🫯‍👩🏼 +👩🏽‍🫯‍👩🏾 +👩🏽‍🫯‍👩🏿 +👩🏾 +👩🏾‍⚕️ +👩🏾‍⚖️ +👩🏾‍✈️ +👩🏾‍❤️‍👨🏻 +👩🏾‍❤️‍👨🏼 +👩🏾‍❤️‍👨🏽 +👩🏾‍❤️‍👨🏾 +👩🏾‍❤️‍👨🏿 +👩🏾‍❤️‍👩🏻 +👩🏾‍❤️‍👩🏼 +👩🏾‍❤️‍👩🏽 +👩🏾‍❤️‍👩🏾 +👩🏾‍❤️‍👩🏿 +👩🏾‍❤️‍💋‍👨🏻 +👩🏾‍❤️‍💋‍👨🏼 +👩🏾‍❤️‍💋‍👨🏽 +👩🏾‍❤️‍💋‍👨🏾 +👩🏾‍❤️‍💋‍👨🏿 +👩🏾‍❤️‍💋‍👩🏻 +👩🏾‍❤️‍💋‍👩🏼 +👩🏾‍❤️‍💋‍👩🏽 +👩🏾‍❤️‍💋‍👩🏾 +👩🏾‍❤️‍💋‍👩🏿 +👩🏾‍🌾 +👩🏾‍🍳 +👩🏾‍🍼 +👩🏾‍🎓 +👩🏾‍🎤 +👩🏾‍🎨 +👩🏾‍🏫 +👩🏾‍🏭 +👩🏾‍🐰‍👩🏻 +👩🏾‍🐰‍👩🏼 +👩🏾‍🐰‍👩🏽 +👩🏾‍🐰‍👩🏿 +👩🏾‍💻 +👩🏾‍💼 +👩🏾‍🔧 +👩🏾‍🔬 +👩🏾‍🚀 +👩🏾‍🚒 +👩🏾‍🤝‍👨🏻 +👩🏾‍🤝‍👨🏼 +👩🏾‍🤝‍👨🏽 +👩🏾‍🤝‍👨🏿 +👩🏾‍🤝‍👩🏻 +👩🏾‍🤝‍👩🏼 +👩🏾‍🤝‍👩🏽 +👩🏾‍🤝‍👩🏿 +👩🏾‍🦯 +👩🏾‍🦯‍➡️ +👩🏾‍🦰 +👩🏾‍🦱 +👩🏾‍🦲 +👩🏾‍🦳 +👩🏾‍🦼 +👩🏾‍🦼‍➡️ +👩🏾‍🦽 +👩🏾‍🦽‍➡️ +👩🏾‍🫯‍👩🏻 +👩🏾‍🫯‍👩🏼 +👩🏾‍🫯‍👩🏽 +👩🏾‍🫯‍👩🏿 +👩🏿 +👩🏿‍⚕️ +👩🏿‍⚖️ +👩🏿‍✈️ +👩🏿‍❤️‍👨🏻 +👩🏿‍❤️‍👨🏼 +👩🏿‍❤️‍👨🏽 +👩🏿‍❤️‍👨🏾 +👩🏿‍❤️‍👨🏿 +👩🏿‍❤️‍👩🏻 +👩🏿‍❤️‍👩🏼 +👩🏿‍❤️‍👩🏽 +👩🏿‍❤️‍👩🏾 +👩🏿‍❤️‍👩🏿 +👩🏿‍❤️‍💋‍👨🏻 +👩🏿‍❤️‍💋‍👨🏼 +👩🏿‍❤️‍💋‍👨🏽 +👩🏿‍❤️‍💋‍👨🏾 +👩🏿‍❤️‍💋‍👨🏿 +👩🏿‍❤️‍💋‍👩🏻 +👩🏿‍❤️‍💋‍👩🏼 +👩🏿‍❤️‍💋‍👩🏽 +👩🏿‍❤️‍💋‍👩🏾 +👩🏿‍❤️‍💋‍👩🏿 +👩🏿‍🌾 +👩🏿‍🍳 +👩🏿‍🍼 +👩🏿‍🎓 +👩🏿‍🎤 +👩🏿‍🎨 +👩🏿‍🏫 +👩🏿‍🏭 +👩🏿‍🐰‍👩🏻 +👩🏿‍🐰‍👩🏼 +👩🏿‍🐰‍👩🏽 +👩🏿‍🐰‍👩🏾 +👩🏿‍💻 +👩🏿‍💼 +👩🏿‍🔧 +👩🏿‍🔬 +👩🏿‍🚀 +👩🏿‍🚒 +👩🏿‍🤝‍👨🏻 +👩🏿‍🤝‍👨🏼 +👩🏿‍🤝‍👨🏽 +👩🏿‍🤝‍👨🏾 +👩🏿‍🤝‍👩🏻 +👩🏿‍🤝‍👩🏼 +👩🏿‍🤝‍👩🏽 +👩🏿‍🤝‍👩🏾 +👩🏿‍🦯 +👩🏿‍🦯‍➡️ +👩🏿‍🦰 +👩🏿‍🦱 +👩🏿‍🦲 +👩🏿‍🦳 +👩🏿‍🦼 +👩🏿‍🦼‍➡️ +👩🏿‍🦽 +👩🏿‍🦽‍➡️ +👩🏿‍🫯‍👩🏻 +👩🏿‍🫯‍👩🏼 +👩🏿‍🫯‍👩🏽 +👩🏿‍🫯‍👩🏾 +👪 +👫 +👫🏻 +👫🏼 +👫🏽 +👫🏾 +👫🏿 +👬 +👬🏻 +👬🏼 +👬🏽 +👬🏾 +👬🏿 +👭 +👭🏻 +👭🏼 +👭🏽 +👭🏾 +👭🏿 +👮 +👮‍♀️ +👮‍♂️ +👮🏻 +👮🏻‍♀️ +👮🏻‍♂️ +👮🏼 +👮🏼‍♀️ +👮🏼‍♂️ +👮🏽 +👮🏽‍♀️ +👮🏽‍♂️ +👮🏾 +👮🏾‍♀️ +👮🏾‍♂️ +👮🏿 +👮🏿‍♀️ +👮🏿‍♂️ +👯 +👯‍♀️ +👯‍♂️ +👯🏻 +👯🏻‍♀️ +👯🏻‍♂️ +👯🏼 +👯🏼‍♀️ +👯🏼‍♂️ +👯🏽 +👯🏽‍♀️ +👯🏽‍♂️ +👯🏾 +👯🏾‍♀️ +👯🏾‍♂️ +👯🏿 +👯🏿‍♀️ +👯🏿‍♂️ +👰 +👰‍♀️ +👰‍♂️ +👰🏻 +👰🏻‍♀️ +👰🏻‍♂️ +👰🏼 +👰🏼‍♀️ +👰🏼‍♂️ +👰🏽 +👰🏽‍♀️ +👰🏽‍♂️ +👰🏾 +👰🏾‍♀️ +👰🏾‍♂️ +👰🏿 +👰🏿‍♀️ +👰🏿‍♂️ +👱 +👱‍♀️ +👱‍♂️ +👱🏻 +👱🏻‍♀️ +👱🏻‍♂️ +👱🏼 +👱🏼‍♀️ +👱🏼‍♂️ +👱🏽 +👱🏽‍♀️ +👱🏽‍♂️ +👱🏾 +👱🏾‍♀️ +👱🏾‍♂️ +👱🏿 +👱🏿‍♀️ +👱🏿‍♂️ +👲 +👲🏻 +👲🏼 +👲🏽 +👲🏾 +👲🏿 +👳 +👳‍♀️ +👳‍♂️ +👳🏻 +👳🏻‍♀️ +👳🏻‍♂️ +👳🏼 +👳🏼‍♀️ +👳🏼‍♂️ +👳🏽 +👳🏽‍♀️ +👳🏽‍♂️ +👳🏾 +👳🏾‍♀️ +👳🏾‍♂️ +👳🏿 +👳🏿‍♀️ +👳🏿‍♂️ +👴 +👴🏻 +👴🏼 +👴🏽 +👴🏾 +👴🏿 +👵 +👵🏻 +👵🏼 +👵🏽 +👵🏾 +👵🏿 +👶 +👶🏻 +👶🏼 +👶🏽 +👶🏾 +👶🏿 +👷 +👷‍♀️ +👷‍♂️ +👷🏻 +👷🏻‍♀️ +👷🏻‍♂️ +👷🏼 +👷🏼‍♀️ +👷🏼‍♂️ +👷🏽 +👷🏽‍♀️ +👷🏽‍♂️ +👷🏾 +👷🏾‍♀️ +👷🏾‍♂️ +👷🏿 +👷🏿‍♀️ +👷🏿‍♂️ +👸 +👸🏻 +👸🏼 +👸🏽 +👸🏾 +👸🏿 +👹 +👺 +👻 +👼 +👼🏻 +👼🏼 +👼🏽 +👼🏾 +👼🏿 +👽 +👾 +👿 +💀 +💁 +💁‍♀️ +💁‍♂️ +💁🏻 +💁🏻‍♀️ +💁🏻‍♂️ +💁🏼 +💁🏼‍♀️ +💁🏼‍♂️ +💁🏽 +💁🏽‍♀️ +💁🏽‍♂️ +💁🏾 +💁🏾‍♀️ +💁🏾‍♂️ +💁🏿 +💁🏿‍♀️ +💁🏿‍♂️ +💂 +💂‍♀️ +💂‍♂️ +💂🏻 +💂🏻‍♀️ +💂🏻‍♂️ +💂🏼 +💂🏼‍♀️ +💂🏼‍♂️ +💂🏽 +💂🏽‍♀️ +💂🏽‍♂️ +💂🏾 +💂🏾‍♀️ +💂🏾‍♂️ +💂🏿 +💂🏿‍♀️ +💂🏿‍♂️ +💃 +💃🏻 +💃🏼 +💃🏽 +💃🏾 +💃🏿 +💄 +💅 +💅🏻 +💅🏼 +💅🏽 +💅🏾 +💅🏿 +💆 +💆‍♀️ +💆‍♂️ +💆🏻 +💆🏻‍♀️ +💆🏻‍♂️ +💆🏼 +💆🏼‍♀️ +💆🏼‍♂️ +💆🏽 +💆🏽‍♀️ +💆🏽‍♂️ +💆🏾 +💆🏾‍♀️ +💆🏾‍♂️ +💆🏿 +💆🏿‍♀️ +💆🏿‍♂️ +💇 +💇‍♀️ +💇‍♂️ +💇🏻 +💇🏻‍♀️ +💇🏻‍♂️ +💇🏼 +💇🏼‍♀️ +💇🏼‍♂️ +💇🏽 +💇🏽‍♀️ +💇🏽‍♂️ +💇🏾 +💇🏾‍♀️ +💇🏾‍♂️ +💇🏿 +💇🏿‍♀️ +💇🏿‍♂️ +💈 +💉 +💊 +💋 +💌 +💍 +💎 +💏 +💏🏻 +💏🏼 +💏🏽 +💏🏾 +💏🏿 +💐 +💑 +💑🏻 +💑🏼 +💑🏽 +💑🏾 +💑🏿 +💒 +💓 +💔 +💕 +💖 +💗 +💘 +💙 +💚 +💛 +💜 +💝 +💞 +💟 +💠 +💡 +💢 +💣 +💤 +💥 +💦 +💧 +💨 +💩 +💪 +💪🏻 +💪🏼 +💪🏽 +💪🏾 +💪🏿 +💫 +💬 +💭 +💮 +💯 +💰 +💱 +💲 +💳 +💴 +💵 +💶 +💷 +💸 +💹 +💺 +💻 +💼 +💽 +💾 +💿 +📀 +📁 +📂 +📃 +📄 +📅 +📆 +📇 +📈 +📉 +📊 +📋 +📌 +📍 +📎 +📏 +📐 +📑 +📒 +📓 +📔 +📕 +📖 +📗 +📘 +📙 +📚 +📛 +📜 +📝 +📞 +📟 +📠 +📡 +📢 +📣 +📤 +📥 +📦 +📧 +📨 +📩 +📪 +📫 +📬 +📭 +📮 +📯 +📰 +📱 +📲 +📳 +📴 +📵 +📶 +📷 +📸 +📹 +📺 +📻 +📼 +📽️ +📿 +🔀 +🔁 +🔂 +🔃 +🔄 +🔅 +🔆 +🔇 +🔈 +🔉 +🔊 +🔋 +🔌 +🔍 +🔎 +🔏 +🔐 +🔑 +🔒 +🔓 +🔔 +🔕 +🔖 +🔗 +🔘 +🔙 +🔚 +🔛 +🔜 +🔝 +🔞 +🔟 +🔠 +🔡 +🔢 +🔣 +🔤 +🔥 +🔦 +🔧 +🔨 +🔩 +🔪 +🔫 +🔬 +🔭 +🔮 +🔯 +🔰 +🔱 +🔲 +🔳 +🔴 +🔵 +🔶 +🔷 +🔸 +🔹 +🔺 +🔻 +🔼 +🔽 +🕉️ +🕊️ +🕋 +🕌 +🕍 +🕎 +🕐 +🕑 +🕒 +🕓 +🕔 +🕕 +🕖 +🕗 +🕘 +🕙 +🕚 +🕛 +🕜 +🕝 +🕞 +🕟 +🕠 +🕡 +🕢 +🕣 +🕤 +🕥 +🕦 +🕧 +🕯️ +🕰️ +🕳️ +🕴️ +🕴🏻 +🕴🏼 +🕴🏽 +🕴🏾 +🕴🏿 +🕵️ +🕵️‍♀️ +🕵️‍♂️ +🕵🏻 +🕵🏻‍♀️ +🕵🏻‍♂️ +🕵🏼 +🕵🏼‍♀️ +🕵🏼‍♂️ +🕵🏽 +🕵🏽‍♀️ +🕵🏽‍♂️ +🕵🏾 +🕵🏾‍♀️ +🕵🏾‍♂️ +🕵🏿 +🕵🏿‍♀️ +🕵🏿‍♂️ +🕶️ +🕷️ +🕸️ +🕹️ +🕺 +🕺🏻 +🕺🏼 +🕺🏽 +🕺🏾 +🕺🏿 +🖇️ +🖊️ +🖋️ +🖌️ +🖍️ +🖐️ +🖐🏻 +🖐🏼 +🖐🏽 +🖐🏾 +🖐🏿 +🖕 +🖕🏻 +🖕🏼 +🖕🏽 +🖕🏾 +🖕🏿 +🖖 +🖖🏻 +🖖🏼 +🖖🏽 +🖖🏾 +🖖🏿 +🖤 +🖥️ +🖨️ +🖱️ +🖲️ +🖼️ +🗂️ +🗃️ +🗄️ +🗑️ +🗒️ +🗓️ +🗜️ +🗝️ +🗞️ +🗡️ +🗣️ +🗨️ +🗯️ +🗳️ +🗺️ +🗻 +🗼 +🗽 +🗾 +🗿 +😀 +😁 +😂 +😃 +😄 +😅 +😆 +😇 +😈 +😉 +😊 +😋 +😌 +😍 +😎 +😏 +😐 +😑 +😒 +😓 +😔 +😕 +😖 +😗 +😘 +😙 +😚 +😛 +😜 +😝 +😞 +😟 +😠 +😡 +😢 +😣 +😤 +😥 +😦 +😧 +😨 +😩 +😪 +😫 +😬 +😭 +😮 +😮‍💨 +😯 +😰 +😱 +😲 +😳 +😴 +😵 +😵‍💫 +😶 +😶‍🌫️ +😷 +😸 +😹 +😺 +😻 +😼 +😽 +😾 +😿 +🙀 +🙁 +🙂 +🙂‍↔️ +🙂‍↕️ +🙃 +🙄 +🙅 +🙅‍♀️ +🙅‍♂️ +🙅🏻 +🙅🏻‍♀️ +🙅🏻‍♂️ +🙅🏼 +🙅🏼‍♀️ +🙅🏼‍♂️ +🙅🏽 +🙅🏽‍♀️ +🙅🏽‍♂️ +🙅🏾 +🙅🏾‍♀️ +🙅🏾‍♂️ +🙅🏿 +🙅🏿‍♀️ +🙅🏿‍♂️ +🙆 +🙆‍♀️ +🙆‍♂️ +🙆🏻 +🙆🏻‍♀️ +🙆🏻‍♂️ +🙆🏼 +🙆🏼‍♀️ +🙆🏼‍♂️ +🙆🏽 +🙆🏽‍♀️ +🙆🏽‍♂️ +🙆🏾 +🙆🏾‍♀️ +🙆🏾‍♂️ +🙆🏿 +🙆🏿‍♀️ +🙆🏿‍♂️ +🙇 +🙇‍♀️ +🙇‍♂️ +🙇🏻 +🙇🏻‍♀️ +🙇🏻‍♂️ +🙇🏼 +🙇🏼‍♀️ +🙇🏼‍♂️ +🙇🏽 +🙇🏽‍♀️ +🙇🏽‍♂️ +🙇🏾 +🙇🏾‍♀️ +🙇🏾‍♂️ +🙇🏿 +🙇🏿‍♀️ +🙇🏿‍♂️ +🙈 +🙉 +🙊 +🙋 +🙋‍♀️ +🙋‍♂️ +🙋🏻 +🙋🏻‍♀️ +🙋🏻‍♂️ +🙋🏼 +🙋🏼‍♀️ +🙋🏼‍♂️ +🙋🏽 +🙋🏽‍♀️ +🙋🏽‍♂️ +🙋🏾 +🙋🏾‍♀️ +🙋🏾‍♂️ +🙋🏿 +🙋🏿‍♀️ +🙋🏿‍♂️ +🙌 +🙌🏻 +🙌🏼 +🙌🏽 +🙌🏾 +🙌🏿 +🙍 +🙍‍♀️ +🙍‍♂️ +🙍🏻 +🙍🏻‍♀️ +🙍🏻‍♂️ +🙍🏼 +🙍🏼‍♀️ +🙍🏼‍♂️ +🙍🏽 +🙍🏽‍♀️ +🙍🏽‍♂️ +🙍🏾 +🙍🏾‍♀️ +🙍🏾‍♂️ +🙍🏿 +🙍🏿‍♀️ +🙍🏿‍♂️ +🙎 +🙎‍♀️ +🙎‍♂️ +🙎🏻 +🙎🏻‍♀️ +🙎🏻‍♂️ +🙎🏼 +🙎🏼‍♀️ +🙎🏼‍♂️ +🙎🏽 +🙎🏽‍♀️ +🙎🏽‍♂️ +🙎🏾 +🙎🏾‍♀️ +🙎🏾‍♂️ +🙎🏿 +🙎🏿‍♀️ +🙎🏿‍♂️ +🙏 +🙏🏻 +🙏🏼 +🙏🏽 +🙏🏾 +🙏🏿 +🚀 +🚁 +🚂 +🚃 +🚄 +🚅 +🚆 +🚇 +🚈 +🚉 +🚊 +🚋 +🚌 +🚍 +🚎 +🚏 +🚐 +🚑 +🚒 +🚓 +🚔 +🚕 +🚖 +🚗 +🚘 +🚙 +🚚 +🚛 +🚜 +🚝 +🚞 +🚟 +🚠 +🚡 +🚢 +🚣 +🚣‍♀️ +🚣‍♂️ +🚣🏻 +🚣🏻‍♀️ +🚣🏻‍♂️ +🚣🏼 +🚣🏼‍♀️ +🚣🏼‍♂️ +🚣🏽 +🚣🏽‍♀️ +🚣🏽‍♂️ +🚣🏾 +🚣🏾‍♀️ +🚣🏾‍♂️ +🚣🏿 +🚣🏿‍♀️ +🚣🏿‍♂️ +🚤 +🚥 +🚦 +🚧 +🚨 +🚩 +🚪 +🚫 +🚬 +🚭 +🚮 +🚯 +🚰 +🚱 +🚲 +🚳 +🚴 +🚴‍♀️ +🚴‍♂️ +🚴🏻 +🚴🏻‍♀️ +🚴🏻‍♂️ +🚴🏼 +🚴🏼‍♀️ +🚴🏼‍♂️ +🚴🏽 +🚴🏽‍♀️ +🚴🏽‍♂️ +🚴🏾 +🚴🏾‍♀️ +🚴🏾‍♂️ +🚴🏿 +🚴🏿‍♀️ +🚴🏿‍♂️ +🚵 +🚵‍♀️ +🚵‍♂️ +🚵🏻 +🚵🏻‍♀️ +🚵🏻‍♂️ +🚵🏼 +🚵🏼‍♀️ +🚵🏼‍♂️ +🚵🏽 +🚵🏽‍♀️ +🚵🏽‍♂️ +🚵🏾 +🚵🏾‍♀️ +🚵🏾‍♂️ +🚵🏿 +🚵🏿‍♀️ +🚵🏿‍♂️ +🚶 +🚶‍♀️ +🚶‍♀️‍➡️ +🚶‍♂️ +🚶‍♂️‍➡️ +🚶‍➡️ +🚶🏻 +🚶🏻‍♀️ +🚶🏻‍♀️‍➡️ +🚶🏻‍♂️ +🚶🏻‍♂️‍➡️ +🚶🏻‍➡️ +🚶🏼 +🚶🏼‍♀️ +🚶🏼‍♀️‍➡️ +🚶🏼‍♂️ +🚶🏼‍♂️‍➡️ +🚶🏼‍➡️ +🚶🏽 +🚶🏽‍♀️ +🚶🏽‍♀️‍➡️ +🚶🏽‍♂️ +🚶🏽‍♂️‍➡️ +🚶🏽‍➡️ +🚶🏾 +🚶🏾‍♀️ +🚶🏾‍♀️‍➡️ +🚶🏾‍♂️ +🚶🏾‍♂️‍➡️ +🚶🏾‍➡️ +🚶🏿 +🚶🏿‍♀️ +🚶🏿‍♀️‍➡️ +🚶🏿‍♂️ +🚶🏿‍♂️‍➡️ +🚶🏿‍➡️ +🚷 +🚸 +🚹 +🚺 +🚻 +🚼 +🚽 +🚾 +🚿 +🛀 +🛀🏻 +🛀🏼 +🛀🏽 +🛀🏾 +🛀🏿 +🛁 +🛂 +🛃 +🛄 +🛅 +🛋️ +🛌 +🛌🏻 +🛌🏼 +🛌🏽 +🛌🏾 +🛌🏿 +🛍️ +🛎️ +🛏️ +🛐 +🛑 +🛒 +🛕 +🛖 +🛗 +🛘 +🛜 +🛝 +🛞 +🛟 +🛠️ +🛡️ +🛢️ +🛣️ +🛤️ +🛥️ +🛩️ +🛫 +🛬 +🛰️ +🛳️ +🛴 +🛵 +🛶 +🛷 +🛸 +🛹 +🛺 +🛻 +🛼 +🟠 +🟡 +🟢 +🟣 +🟤 +🟥 +🟦 +🟧 +🟨 +🟩 +🟪 +🟫 +🟰 +🤌 +🤌🏻 +🤌🏼 +🤌🏽 +🤌🏾 +🤌🏿 +🤍 +🤎 +🤏 +🤏🏻 +🤏🏼 +🤏🏽 +🤏🏾 +🤏🏿 +🤐 +🤑 +🤒 +🤓 +🤔 +🤕 +🤖 +🤗 +🤘 +🤘🏻 +🤘🏼 +🤘🏽 +🤘🏾 +🤘🏿 +🤙 +🤙🏻 +🤙🏼 +🤙🏽 +🤙🏾 +🤙🏿 +🤚 +🤚🏻 +🤚🏼 +🤚🏽 +🤚🏾 +🤚🏿 +🤛 +🤛🏻 +🤛🏼 +🤛🏽 +🤛🏾 +🤛🏿 +🤜 +🤜🏻 +🤜🏼 +🤜🏽 +🤜🏾 +🤜🏿 +🤝 +🤝🏻 +🤝🏼 +🤝🏽 +🤝🏾 +🤝🏿 +🤞 +🤞🏻 +🤞🏼 +🤞🏽 +🤞🏾 +🤞🏿 +🤟 +🤟🏻 +🤟🏼 +🤟🏽 +🤟🏾 +🤟🏿 +🤠 +🤡 +🤢 +🤣 +🤤 +🤥 +🤦 +🤦‍♀️ +🤦‍♂️ +🤦🏻 +🤦🏻‍♀️ +🤦🏻‍♂️ +🤦🏼 +🤦🏼‍♀️ +🤦🏼‍♂️ +🤦🏽 +🤦🏽‍♀️ +🤦🏽‍♂️ +🤦🏾 +🤦🏾‍♀️ +🤦🏾‍♂️ +🤦🏿 +🤦🏿‍♀️ +🤦🏿‍♂️ +🤧 +🤨 +🤩 +🤪 +🤫 +🤬 +🤭 +🤮 +🤯 +🤰 +🤰🏻 +🤰🏼 +🤰🏽 +🤰🏾 +🤰🏿 +🤱 +🤱🏻 +🤱🏼 +🤱🏽 +🤱🏾 +🤱🏿 +🤲 +🤲🏻 +🤲🏼 +🤲🏽 +🤲🏾 +🤲🏿 +🤳 +🤳🏻 +🤳🏼 +🤳🏽 +🤳🏾 +🤳🏿 +🤴 +🤴🏻 +🤴🏼 +🤴🏽 +🤴🏾 +🤴🏿 +🤵 +🤵‍♀️ +🤵‍♂️ +🤵🏻 +🤵🏻‍♀️ +🤵🏻‍♂️ +🤵🏼 +🤵🏼‍♀️ +🤵🏼‍♂️ +🤵🏽 +🤵🏽‍♀️ +🤵🏽‍♂️ +🤵🏾 +🤵🏾‍♀️ +🤵🏾‍♂️ +🤵🏿 +🤵🏿‍♀️ +🤵🏿‍♂️ +🤶 +🤶🏻 +🤶🏼 +🤶🏽 +🤶🏾 +🤶🏿 +🤷 +🤷‍♀️ +🤷‍♂️ +🤷🏻 +🤷🏻‍♀️ +🤷🏻‍♂️ +🤷🏼 +🤷🏼‍♀️ +🤷🏼‍♂️ +🤷🏽 +🤷🏽‍♀️ +🤷🏽‍♂️ +🤷🏾 +🤷🏾‍♀️ +🤷🏾‍♂️ +🤷🏿 +🤷🏿‍♀️ +🤷🏿‍♂️ +🤸 +🤸‍♀️ +🤸‍♂️ +🤸🏻 +🤸🏻‍♀️ +🤸🏻‍♂️ +🤸🏼 +🤸🏼‍♀️ +🤸🏼‍♂️ +🤸🏽 +🤸🏽‍♀️ +🤸🏽‍♂️ +🤸🏾 +🤸🏾‍♀️ +🤸🏾‍♂️ +🤸🏿 +🤸🏿‍♀️ +🤸🏿‍♂️ +🤹 +🤹‍♀️ +🤹‍♂️ +🤹🏻 +🤹🏻‍♀️ +🤹🏻‍♂️ +🤹🏼 +🤹🏼‍♀️ +🤹🏼‍♂️ +🤹🏽 +🤹🏽‍♀️ +🤹🏽‍♂️ +🤹🏾 +🤹🏾‍♀️ +🤹🏾‍♂️ +🤹🏿 +🤹🏿‍♀️ +🤹🏿‍♂️ +🤺 +🤼 +🤼‍♀️ +🤼‍♂️ +🤼🏻 +🤼🏻‍♀️ +🤼🏻‍♂️ +🤼🏼 +🤼🏼‍♀️ +🤼🏼‍♂️ +🤼🏽 +🤼🏽‍♀️ +🤼🏽‍♂️ +🤼🏾 +🤼🏾‍♀️ +🤼🏾‍♂️ +🤼🏿 +🤼🏿‍♀️ +🤼🏿‍♂️ +🤽 +🤽‍♀️ +🤽‍♂️ +🤽🏻 +🤽🏻‍♀️ +🤽🏻‍♂️ +🤽🏼 +🤽🏼‍♀️ +🤽🏼‍♂️ +🤽🏽 +🤽🏽‍♀️ +🤽🏽‍♂️ +🤽🏾 +🤽🏾‍♀️ +🤽🏾‍♂️ +🤽🏿 +🤽🏿‍♀️ +🤽🏿‍♂️ +🤾 +🤾‍♀️ +🤾‍♂️ +🤾🏻 +🤾🏻‍♀️ +🤾🏻‍♂️ +🤾🏼 +🤾🏼‍♀️ +🤾🏼‍♂️ +🤾🏽 +🤾🏽‍♀️ +🤾🏽‍♂️ +🤾🏾 +🤾🏾‍♀️ +🤾🏾‍♂️ +🤾🏿 +🤾🏿‍♀️ +🤾🏿‍♂️ +🤿 +🥀 +🥁 +🥂 +🥃 +🥄 +🥅 +🥇 +🥈 +🥉 +🥊 +🥋 +🥌 +🥍 +🥎 +🥏 +🥐 +🥑 +🥒 +🥓 +🥔 +🥕 +🥖 +🥗 +🥘 +🥙 +🥚 +🥛 +🥜 +🥝 +🥞 +🥟 +🥠 +🥡 +🥢 +🥣 +🥤 +🥥 +🥦 +🥧 +🥨 +🥩 +🥪 +🥫 +🥬 +🥭 +🥮 +🥯 +🥰 +🥱 +🥲 +🥳 +🥴 +🥵 +🥶 +🥷 +🥷🏻 +🥷🏼 +🥷🏽 +🥷🏾 +🥷🏿 +🥸 +🥹 +🥺 +🥻 +🥼 +🥽 +🥾 +🥿 +🦀 +🦁 +🦂 +🦃 +🦄 +🦅 +🦆 +🦇 +🦈 +🦉 +🦊 +🦋 +🦌 +🦍 +🦎 +🦏 +🦐 +🦑 +🦒 +🦓 +🦔 +🦕 +🦖 +🦗 +🦘 +🦙 +🦚 +🦛 +🦜 +🦝 +🦞 +🦟 +🦠 +🦡 +🦢 +🦣 +🦤 +🦥 +🦦 +🦧 +🦨 +🦩 +🦪 +🦫 +🦬 +🦭 +🦮 +🦯 +🦴 +🦵 +🦵🏻 +🦵🏼 +🦵🏽 +🦵🏾 +🦵🏿 +🦶 +🦶🏻 +🦶🏼 +🦶🏽 +🦶🏾 +🦶🏿 +🦷 +🦸 +🦸‍♀️ +🦸‍♂️ +🦸🏻 +🦸🏻‍♀️ +🦸🏻‍♂️ +🦸🏼 +🦸🏼‍♀️ +🦸🏼‍♂️ +🦸🏽 +🦸🏽‍♀️ +🦸🏽‍♂️ +🦸🏾 +🦸🏾‍♀️ +🦸🏾‍♂️ +🦸🏿 +🦸🏿‍♀️ +🦸🏿‍♂️ +🦹 +🦹‍♀️ +🦹‍♂️ +🦹🏻 +🦹🏻‍♀️ +🦹🏻‍♂️ +🦹🏼 +🦹🏼‍♀️ +🦹🏼‍♂️ +🦹🏽 +🦹🏽‍♀️ +🦹🏽‍♂️ +🦹🏾 +🦹🏾‍♀️ +🦹🏾‍♂️ +🦹🏿 +🦹🏿‍♀️ +🦹🏿‍♂️ +🦺 +🦻 +🦻🏻 +🦻🏼 +🦻🏽 +🦻🏾 +🦻🏿 +🦼 +🦽 +🦾 +🦿 +🧀 +🧁 +🧂 +🧃 +🧄 +🧅 +🧆 +🧇 +🧈 +🧉 +🧊 +🧋 +🧌 +🧍 +🧍‍♀️ +🧍‍♂️ +🧍🏻 +🧍🏻‍♀️ +🧍🏻‍♂️ +🧍🏼 +🧍🏼‍♀️ +🧍🏼‍♂️ +🧍🏽 +🧍🏽‍♀️ +🧍🏽‍♂️ +🧍🏾 +🧍🏾‍♀️ +🧍🏾‍♂️ +🧍🏿 +🧍🏿‍♀️ +🧍🏿‍♂️ +🧎 +🧎‍♀️ +🧎‍♀️‍➡️ +🧎‍♂️ +🧎‍♂️‍➡️ +🧎‍➡️ +🧎🏻 +🧎🏻‍♀️ +🧎🏻‍♀️‍➡️ +🧎🏻‍♂️ +🧎🏻‍♂️‍➡️ +🧎🏻‍➡️ +🧎🏼 +🧎🏼‍♀️ +🧎🏼‍♀️‍➡️ +🧎🏼‍♂️ +🧎🏼‍♂️‍➡️ +🧎🏼‍➡️ +🧎🏽 +🧎🏽‍♀️ +🧎🏽‍♀️‍➡️ +🧎🏽‍♂️ +🧎🏽‍♂️‍➡️ +🧎🏽‍➡️ +🧎🏾 +🧎🏾‍♀️ +🧎🏾‍♀️‍➡️ +🧎🏾‍♂️ +🧎🏾‍♂️‍➡️ +🧎🏾‍➡️ +🧎🏿 +🧎🏿‍♀️ +🧎🏿‍♀️‍➡️ +🧎🏿‍♂️ +🧎🏿‍♂️‍➡️ +🧎🏿‍➡️ +🧏 +🧏‍♀️ +🧏‍♂️ +🧏🏻 +🧏🏻‍♀️ +🧏🏻‍♂️ +🧏🏼 +🧏🏼‍♀️ +🧏🏼‍♂️ +🧏🏽 +🧏🏽‍♀️ +🧏🏽‍♂️ +🧏🏾 +🧏🏾‍♀️ +🧏🏾‍♂️ +🧏🏿 +🧏🏿‍♀️ +🧏🏿‍♂️ +🧐 +🧑 +🧑‍⚕️ +🧑‍⚖️ +🧑‍✈️ +🧑‍🌾 +🧑‍🍳 +🧑‍🍼 +🧑‍🎄 +🧑‍🎓 +🧑‍🎤 +🧑‍🎨 +🧑‍🏫 +🧑‍🏭 +🧑‍💻 +🧑‍💼 +🧑‍🔧 +🧑‍🔬 +🧑‍🚀 +🧑‍🚒 +🧑‍🤝‍🧑 +🧑‍🦯 +🧑‍🦯‍➡️ +🧑‍🦰 +🧑‍🦱 +🧑‍🦲 +🧑‍🦳 +🧑‍🦼 +🧑‍🦼‍➡️ +🧑‍🦽 +🧑‍🦽‍➡️ +🧑‍🧑‍🧒 +🧑‍🧑‍🧒‍🧒 +🧑‍🧒 +🧑‍🧒‍🧒 +🧑‍🩰 +🧑🏻 +🧑🏻‍⚕️ +🧑🏻‍⚖️ +🧑🏻‍✈️ +🧑🏻‍❤️‍💋‍🧑🏼 +🧑🏻‍❤️‍💋‍🧑🏽 +🧑🏻‍❤️‍💋‍🧑🏾 +🧑🏻‍❤️‍💋‍🧑🏿 +🧑🏻‍❤️‍🧑🏼 +🧑🏻‍❤️‍🧑🏽 +🧑🏻‍❤️‍🧑🏾 +🧑🏻‍❤️‍🧑🏿 +🧑🏻‍🌾 +🧑🏻‍🍳 +🧑🏻‍🍼 +🧑🏻‍🎄 +🧑🏻‍🎓 +🧑🏻‍🎤 +🧑🏻‍🎨 +🧑🏻‍🏫 +🧑🏻‍🏭 +🧑🏻‍🐰‍🧑🏼 +🧑🏻‍🐰‍🧑🏽 +🧑🏻‍🐰‍🧑🏾 +🧑🏻‍🐰‍🧑🏿 +🧑🏻‍💻 +🧑🏻‍💼 +🧑🏻‍🔧 +🧑🏻‍🔬 +🧑🏻‍🚀 +🧑🏻‍🚒 +🧑🏻‍🤝‍🧑🏻 +🧑🏻‍🤝‍🧑🏼 +🧑🏻‍🤝‍🧑🏽 +🧑🏻‍🤝‍🧑🏾 +🧑🏻‍🤝‍🧑🏿 +🧑🏻‍🦯 +🧑🏻‍🦯‍➡️ +🧑🏻‍🦰 +🧑🏻‍🦱 +🧑🏻‍🦲 +🧑🏻‍🦳 +🧑🏻‍🦼 +🧑🏻‍🦼‍➡️ +🧑🏻‍🦽 +🧑🏻‍🦽‍➡️ +🧑🏻‍🩰 +🧑🏻‍🫯‍🧑🏼 +🧑🏻‍🫯‍🧑🏽 +🧑🏻‍🫯‍🧑🏾 +🧑🏻‍🫯‍🧑🏿 +🧑🏼 +🧑🏼‍⚕️ +🧑🏼‍⚖️ +🧑🏼‍✈️ +🧑🏼‍❤️‍💋‍🧑🏻 +🧑🏼‍❤️‍💋‍🧑🏽 +🧑🏼‍❤️‍💋‍🧑🏾 +🧑🏼‍❤️‍💋‍🧑🏿 +🧑🏼‍❤️‍🧑🏻 +🧑🏼‍❤️‍🧑🏽 +🧑🏼‍❤️‍🧑🏾 +🧑🏼‍❤️‍🧑🏿 +🧑🏼‍🌾 +🧑🏼‍🍳 +🧑🏼‍🍼 +🧑🏼‍🎄 +🧑🏼‍🎓 +🧑🏼‍🎤 +🧑🏼‍🎨 +🧑🏼‍🏫 +🧑🏼‍🏭 +🧑🏼‍🐰‍🧑🏻 +🧑🏼‍🐰‍🧑🏽 +🧑🏼‍🐰‍🧑🏾 +🧑🏼‍🐰‍🧑🏿 +🧑🏼‍💻 +🧑🏼‍💼 +🧑🏼‍🔧 +🧑🏼‍🔬 +🧑🏼‍🚀 +🧑🏼‍🚒 +🧑🏼‍🤝‍🧑🏻 +🧑🏼‍🤝‍🧑🏼 +🧑🏼‍🤝‍🧑🏽 +🧑🏼‍🤝‍🧑🏾 +🧑🏼‍🤝‍🧑🏿 +🧑🏼‍🦯 +🧑🏼‍🦯‍➡️ +🧑🏼‍🦰 +🧑🏼‍🦱 +🧑🏼‍🦲 +🧑🏼‍🦳 +🧑🏼‍🦼 +🧑🏼‍🦼‍➡️ +🧑🏼‍🦽 +🧑🏼‍🦽‍➡️ +🧑🏼‍🩰 +🧑🏼‍🫯‍🧑🏻 +🧑🏼‍🫯‍🧑🏽 +🧑🏼‍🫯‍🧑🏾 +🧑🏼‍🫯‍🧑🏿 +🧑🏽 +🧑🏽‍⚕️ +🧑🏽‍⚖️ +🧑🏽‍✈️ +🧑🏽‍❤️‍💋‍🧑🏻 +🧑🏽‍❤️‍💋‍🧑🏼 +🧑🏽‍❤️‍💋‍🧑🏾 +🧑🏽‍❤️‍💋‍🧑🏿 +🧑🏽‍❤️‍🧑🏻 +🧑🏽‍❤️‍🧑🏼 +🧑🏽‍❤️‍🧑🏾 +🧑🏽‍❤️‍🧑🏿 +🧑🏽‍🌾 +🧑🏽‍🍳 +🧑🏽‍🍼 +🧑🏽‍🎄 +🧑🏽‍🎓 +🧑🏽‍🎤 +🧑🏽‍🎨 +🧑🏽‍🏫 +🧑🏽‍🏭 +🧑🏽‍🐰‍🧑🏻 +🧑🏽‍🐰‍🧑🏼 +🧑🏽‍🐰‍🧑🏾 +🧑🏽‍🐰‍🧑🏿 +🧑🏽‍💻 +🧑🏽‍💼 +🧑🏽‍🔧 +🧑🏽‍🔬 +🧑🏽‍🚀 +🧑🏽‍🚒 +🧑🏽‍🤝‍🧑🏻 +🧑🏽‍🤝‍🧑🏼 +🧑🏽‍🤝‍🧑🏽 +🧑🏽‍🤝‍🧑🏾 +🧑🏽‍🤝‍🧑🏿 +🧑🏽‍🦯 +🧑🏽‍🦯‍➡️ +🧑🏽‍🦰 +🧑🏽‍🦱 +🧑🏽‍🦲 +🧑🏽‍🦳 +🧑🏽‍🦼 +🧑🏽‍🦼‍➡️ +🧑🏽‍🦽 +🧑🏽‍🦽‍➡️ +🧑🏽‍🩰 +🧑🏽‍🫯‍🧑🏻 +🧑🏽‍🫯‍🧑🏼 +🧑🏽‍🫯‍🧑🏾 +🧑🏽‍🫯‍🧑🏿 +🧑🏾 +🧑🏾‍⚕️ +🧑🏾‍⚖️ +🧑🏾‍✈️ +🧑🏾‍❤️‍💋‍🧑🏻 +🧑🏾‍❤️‍💋‍🧑🏼 +🧑🏾‍❤️‍💋‍🧑🏽 +🧑🏾‍❤️‍💋‍🧑🏿 +🧑🏾‍❤️‍🧑🏻 +🧑🏾‍❤️‍🧑🏼 +🧑🏾‍❤️‍🧑🏽 +🧑🏾‍❤️‍🧑🏿 +🧑🏾‍🌾 +🧑🏾‍🍳 +🧑🏾‍🍼 +🧑🏾‍🎄 +🧑🏾‍🎓 +🧑🏾‍🎤 +🧑🏾‍🎨 +🧑🏾‍🏫 +🧑🏾‍🏭 +🧑🏾‍🐰‍🧑🏻 +🧑🏾‍🐰‍🧑🏼 +🧑🏾‍🐰‍🧑🏽 +🧑🏾‍🐰‍🧑🏿 +🧑🏾‍💻 +🧑🏾‍💼 +🧑🏾‍🔧 +🧑🏾‍🔬 +🧑🏾‍🚀 +🧑🏾‍🚒 +🧑🏾‍🤝‍🧑🏻 +🧑🏾‍🤝‍🧑🏼 +🧑🏾‍🤝‍🧑🏽 +🧑🏾‍🤝‍🧑🏾 +🧑🏾‍🤝‍🧑🏿 +🧑🏾‍🦯 +🧑🏾‍🦯‍➡️ +🧑🏾‍🦰 +🧑🏾‍🦱 +🧑🏾‍🦲 +🧑🏾‍🦳 +🧑🏾‍🦼 +🧑🏾‍🦼‍➡️ +🧑🏾‍🦽 +🧑🏾‍🦽‍➡️ +🧑🏾‍🩰 +🧑🏾‍🫯‍🧑🏻 +🧑🏾‍🫯‍🧑🏼 +🧑🏾‍🫯‍🧑🏽 +🧑🏾‍🫯‍🧑🏿 +🧑🏿 +🧑🏿‍⚕️ +🧑🏿‍⚖️ +🧑🏿‍✈️ +🧑🏿‍❤️‍💋‍🧑🏻 +🧑🏿‍❤️‍💋‍🧑🏼 +🧑🏿‍❤️‍💋‍🧑🏽 +🧑🏿‍❤️‍💋‍🧑🏾 +🧑🏿‍❤️‍🧑🏻 +🧑🏿‍❤️‍🧑🏼 +🧑🏿‍❤️‍🧑🏽 +🧑🏿‍❤️‍🧑🏾 +🧑🏿‍🌾 +🧑🏿‍🍳 +🧑🏿‍🍼 +🧑🏿‍🎄 +🧑🏿‍🎓 +🧑🏿‍🎤 +🧑🏿‍🎨 +🧑🏿‍🏫 +🧑🏿‍🏭 +🧑🏿‍🐰‍🧑🏻 +🧑🏿‍🐰‍🧑🏼 +🧑🏿‍🐰‍🧑🏽 +🧑🏿‍🐰‍🧑🏾 +🧑🏿‍💻 +🧑🏿‍💼 +🧑🏿‍🔧 +🧑🏿‍🔬 +🧑🏿‍🚀 +🧑🏿‍🚒 +🧑🏿‍🤝‍🧑🏻 +🧑🏿‍🤝‍🧑🏼 +🧑🏿‍🤝‍🧑🏽 +🧑🏿‍🤝‍🧑🏾 +🧑🏿‍🤝‍🧑🏿 +🧑🏿‍🦯 +🧑🏿‍🦯‍➡️ +🧑🏿‍🦰 +🧑🏿‍🦱 +🧑🏿‍🦲 +🧑🏿‍🦳 +🧑🏿‍🦼 +🧑🏿‍🦼‍➡️ +🧑🏿‍🦽 +🧑🏿‍🦽‍➡️ +🧑🏿‍🩰 +🧑🏿‍🫯‍🧑🏻 +🧑🏿‍🫯‍🧑🏼 +🧑🏿‍🫯‍🧑🏽 +🧑🏿‍🫯‍🧑🏾 +🧒 +🧒🏻 +🧒🏼 +🧒🏽 +🧒🏾 +🧒🏿 +🧓 +🧓🏻 +🧓🏼 +🧓🏽 +🧓🏾 +🧓🏿 +🧔 +🧔‍♀️ +🧔‍♂️ +🧔🏻 +🧔🏻‍♀️ +🧔🏻‍♂️ +🧔🏼 +🧔🏼‍♀️ +🧔🏼‍♂️ +🧔🏽 +🧔🏽‍♀️ +🧔🏽‍♂️ +🧔🏾 +🧔🏾‍♀️ +🧔🏾‍♂️ +🧔🏿 +🧔🏿‍♀️ +🧔🏿‍♂️ +🧕 +🧕🏻 +🧕🏼 +🧕🏽 +🧕🏾 +🧕🏿 +🧖 +🧖‍♀️ +🧖‍♂️ +🧖🏻 +🧖🏻‍♀️ +🧖🏻‍♂️ +🧖🏼 +🧖🏼‍♀️ +🧖🏼‍♂️ +🧖🏽 +🧖🏽‍♀️ +🧖🏽‍♂️ +🧖🏾 +🧖🏾‍♀️ +🧖🏾‍♂️ +🧖🏿 +🧖🏿‍♀️ +🧖🏿‍♂️ +🧗 +🧗‍♀️ +🧗‍♂️ +🧗🏻 +🧗🏻‍♀️ +🧗🏻‍♂️ +🧗🏼 +🧗🏼‍♀️ +🧗🏼‍♂️ +🧗🏽 +🧗🏽‍♀️ +🧗🏽‍♂️ +🧗🏾 +🧗🏾‍♀️ +🧗🏾‍♂️ +🧗🏿 +🧗🏿‍♀️ +🧗🏿‍♂️ +🧘 +🧘‍♀️ +🧘‍♂️ +🧘🏻 +🧘🏻‍♀️ +🧘🏻‍♂️ +🧘🏼 +🧘🏼‍♀️ +🧘🏼‍♂️ +🧘🏽 +🧘🏽‍♀️ +🧘🏽‍♂️ +🧘🏾 +🧘🏾‍♀️ +🧘🏾‍♂️ +🧘🏿 +🧘🏿‍♀️ +🧘🏿‍♂️ +🧙 +🧙‍♀️ +🧙‍♂️ +🧙🏻 +🧙🏻‍♀️ +🧙🏻‍♂️ +🧙🏼 +🧙🏼‍♀️ +🧙🏼‍♂️ +🧙🏽 +🧙🏽‍♀️ +🧙🏽‍♂️ +🧙🏾 +🧙🏾‍♀️ +🧙🏾‍♂️ +🧙🏿 +🧙🏿‍♀️ +🧙🏿‍♂️ +🧚 +🧚‍♀️ +🧚‍♂️ +🧚🏻 +🧚🏻‍♀️ +🧚🏻‍♂️ +🧚🏼 +🧚🏼‍♀️ +🧚🏼‍♂️ +🧚🏽 +🧚🏽‍♀️ +🧚🏽‍♂️ +🧚🏾 +🧚🏾‍♀️ +🧚🏾‍♂️ +🧚🏿 +🧚🏿‍♀️ +🧚🏿‍♂️ +🧛 +🧛‍♀️ +🧛‍♂️ +🧛🏻 +🧛🏻‍♀️ +🧛🏻‍♂️ +🧛🏼 +🧛🏼‍♀️ +🧛🏼‍♂️ +🧛🏽 +🧛🏽‍♀️ +🧛🏽‍♂️ +🧛🏾 +🧛🏾‍♀️ +🧛🏾‍♂️ +🧛🏿 +🧛🏿‍♀️ +🧛🏿‍♂️ +🧜 +🧜‍♀️ +🧜‍♂️ +🧜🏻 +🧜🏻‍♀️ +🧜🏻‍♂️ +🧜🏼 +🧜🏼‍♀️ +🧜🏼‍♂️ +🧜🏽 +🧜🏽‍♀️ +🧜🏽‍♂️ +🧜🏾 +🧜🏾‍♀️ +🧜🏾‍♂️ +🧜🏿 +🧜🏿‍♀️ +🧜🏿‍♂️ +🧝 +🧝‍♀️ +🧝‍♂️ +🧝🏻 +🧝🏻‍♀️ +🧝🏻‍♂️ +🧝🏼 +🧝🏼‍♀️ +🧝🏼‍♂️ +🧝🏽 +🧝🏽‍♀️ +🧝🏽‍♂️ +🧝🏾 +🧝🏾‍♀️ +🧝🏾‍♂️ +🧝🏿 +🧝🏿‍♀️ +🧝🏿‍♂️ +🧞 +🧞‍♀️ +🧞‍♂️ +🧟 +🧟‍♀️ +🧟‍♂️ +🧠 +🧡 +🧢 +🧣 +🧤 +🧥 +🧦 +🧧 +🧨 +🧩 +🧪 +🧫 +🧬 +🧭 +🧮 +🧯 +🧰 +🧱 +🧲 +🧳 +🧴 +🧵 +🧶 +🧷 +🧸 +🧹 +🧺 +🧻 +🧼 +🧽 +🧾 +🧿 +🩰 +🩱 +🩲 +🩳 +🩴 +🩵 +🩶 +🩷 +🩸 +🩹 +🩺 +🩻 +🩼 +🪀 +🪁 +🪂 +🪃 +🪄 +🪅 +🪆 +🪇 +🪈 +🪉 +🪊 +🪎 +🪏 +🪐 +🪑 +🪒 +🪓 +🪔 +🪕 +🪖 +🪗 +🪘 +🪙 +🪚 +🪛 +🪜 +🪝 +🪞 +🪟 +🪠 +🪡 +🪢 +🪣 +🪤 +🪥 +🪦 +🪧 +🪨 +🪩 +🪪 +🪫 +🪬 +🪭 +🪮 +🪯 +🪰 +🪱 +🪲 +🪳 +🪴 +🪵 +🪶 +🪷 +🪸 +🪹 +🪺 +🪻 +🪼 +🪽 +🪾 +🪿 +🫀 +🫁 +🫂 +🫃 +🫃🏻 +🫃🏼 +🫃🏽 +🫃🏾 +🫃🏿 +🫄 +🫄🏻 +🫄🏼 +🫄🏽 +🫄🏾 +🫄🏿 +🫅 +🫅🏻 +🫅🏼 +🫅🏽 +🫅🏾 +🫅🏿 +🫆 +🫈 +🫍 +🫎 +🫏 +🫐 +🫑 +🫒 +🫓 +🫔 +🫕 +🫖 +🫗 +🫘 +🫙 +🫚 +🫛 +🫜 +🫟 +🫠 +🫡 +🫢 +🫣 +🫤 +🫥 +🫦 +🫧 +🫨 +🫩 +🫪 +🫯 +🫰 +🫰🏻 +🫰🏼 +🫰🏽 +🫰🏾 +🫰🏿 +🫱 +🫱🏻 +🫱🏻‍🫲🏼 +🫱🏻‍🫲🏽 +🫱🏻‍🫲🏾 +🫱🏻‍🫲🏿 +🫱🏼 +🫱🏼‍🫲🏻 +🫱🏼‍🫲🏽 +🫱🏼‍🫲🏾 +🫱🏼‍🫲🏿 +🫱🏽 +🫱🏽‍🫲🏻 +🫱🏽‍🫲🏼 +🫱🏽‍🫲🏾 +🫱🏽‍🫲🏿 +🫱🏾 +🫱🏾‍🫲🏻 +🫱🏾‍🫲🏼 +🫱🏾‍🫲🏽 +🫱🏾‍🫲🏿 +🫱🏿 +🫱🏿‍🫲🏻 +🫱🏿‍🫲🏼 +🫱🏿‍🫲🏽 +🫱🏿‍🫲🏾 +🫲 +🫲🏻 +🫲🏼 +🫲🏽 +🫲🏾 +🫲🏿 +🫳 +🫳🏻 +🫳🏼 +🫳🏽 +🫳🏾 +🫳🏿 +🫴 +🫴🏻 +🫴🏼 +🫴🏽 +🫴🏾 +🫴🏿 +🫵 +🫵🏻 +🫵🏼 +🫵🏽 +🫵🏾 +🫵🏿 +🫶 +🫶🏻 +🫶🏼 +🫶🏽 +🫶🏾 +🫶🏿 +🫷 +🫷🏻 +🫷🏼 +🫷🏽 +🫷🏾 +🫷🏿 +🫸 +🫸🏻 +🫸🏼 +🫸🏽 +🫸🏾 +🫸🏿 \ No newline at end of file From 9fd7128f800badbd184baf943d4f799e601201e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0spik?= Date: Sat, 9 May 2026 00:38:57 +0300 Subject: [PATCH 157/211] fix: encode filenames in redirects (#737) * fix: encode filenames in redirects Signed-off-by: ispik * refactor: don't add another dependency when the one needed exists Signed-off-by: ispik --------- Signed-off-by: ispik --- Cargo.lock | 1 + crates/services/autumn/Cargo.toml | 2 +- crates/services/autumn/src/api.rs | 5 ++++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3f452c4dd..03b3406f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7002,6 +7002,7 @@ dependencies = [ "tracing", "tracing-subscriber", "ulid 1.2.1", + "url-escape", "utoipa", "utoipa-scalar", "webp", diff --git a/crates/services/autumn/Cargo.toml b/crates/services/autumn/Cargo.toml index 762c4ee35..1636a8ecb 100644 --- a/crates/services/autumn/Cargo.toml +++ b/crates/services/autumn/Cargo.toml @@ -31,7 +31,7 @@ imagesize = { workspace = true } # Utility lazy_static = { workspace = true } moka = { workspace = true, features = ["future"] } - +url-escape = { workspace = true } # Serialisation strum_macros = { workspace = true } serde_json = { workspace = true } diff --git a/crates/services/autumn/src/api.rs b/crates/services/autumn/src/api.rs index 49a61c43c..c0e45d72b 100644 --- a/crates/services/autumn/src/api.rs +++ b/crates/services/autumn/src/api.rs @@ -24,6 +24,7 @@ use sha2::Digest; use tempfile::NamedTempFile; use tokio::time::Instant; use tower_http::cors::{AllowHeaders, Any, CorsLayer}; +use url_escape::encode_component; use utoipa::ToSchema; use crate::{ @@ -479,8 +480,10 @@ async fn fetch_file( // Ensure filename is correct if file_name != file.filename { if file_name == "original" { + let safe_filename = encode_component(&file.filename); + return Ok( - Redirect::permanent(&format!("/{tag}/{file_id}/{}", file.filename)).into_response(), + Redirect::permanent(&format!("/{tag}/{file_id}/{}", safe_filename)).into_response(), ); } From ab5bd47a39ee889de0b5ae6e7b560620853daead Mon Sep 17 00:00:00 2001 From: Tom Date: Fri, 8 May 2026 14:39:16 -0700 Subject: [PATCH 158/211] feat: Rewrite acks (#741) * feat: rewrite ack system Signed-off-by: IAmTomahawkx * feat: rewrite acks to crond + rabbit task * fix: review changes --------- Signed-off-by: IAmTomahawkx --- Cargo.lock | 638 +++++++++++++++++- Cargo.toml | 2 + compose.yml | 14 +- crates/core/config/Revolt.toml | 4 + crates/core/config/src/lib.rs | 7 + crates/core/database/Cargo.toml | 1 + crates/core/database/src/amqp/amqp.rs | 83 ++- crates/core/database/src/events/rabbit.rs | 8 + .../database/src/models/channels/model.rs | 19 +- crates/core/database/src/tasks/ack.rs | 10 +- crates/core/database/src/util/acker.rs | 77 +++ crates/core/database/src/util/mod.rs | 1 + crates/daemons/crond/Cargo.toml | 14 + crates/daemons/crond/src/main.rs | 5 +- crates/daemons/crond/src/tasks/acks.rs | 129 ++++ crates/daemons/crond/src/tasks/mod.rs | 1 + crates/delta/src/main.rs | 22 +- .../delta/src/routes/channels/channel_ack.rs | 5 +- crates/delta/src/routes/servers/server_ack.rs | 16 +- 19 files changed, 993 insertions(+), 63 deletions(-) create mode 100644 crates/core/database/src/util/acker.rs create mode 100644 crates/daemons/crond/src/tasks/acks.rs diff --git a/Cargo.lock b/Cargo.lock index 03b3406f2..671d6a9dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,7 +35,7 @@ checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher", - "cpufeatures", + "cpufeatures 0.2.17", ] [[package]] @@ -124,6 +124,56 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" +[[package]] +name = "amq-protocol" +version = "10.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5b2e8843d88d935a75cbdb1c5b9ad80987da6e6472c2703914e41dc14560990" +dependencies = [ + "amq-protocol-tcp", + "amq-protocol-types", + "amq-protocol-uri", + "cookie-factory", + "nom 8.0.0", + "serde", +] + +[[package]] +name = "amq-protocol-tcp" +version = "10.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "998fb81655e11de5a336bb609042c11633678fc01f90b0772fb9a7886b6cc4c2" +dependencies = [ + "amq-protocol-uri", + "async-rs", + "cfg-if", + "tcp-stream", + "tracing", +] + +[[package]] +name = "amq-protocol-types" +version = "10.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee5b3a9e458bd2e452536995c8cf861b01c17283f55c4bbe0a1b9626b8253add" +dependencies = [ + "cookie-factory", + "nom 8.0.0", + "serde", + "serde_json", +] + +[[package]] +name = "amq-protocol-uri" +version = "10.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dca3316970d20cdcca9123f4e8feb7a2c1c8fdca572a9692fc10002db35407aa" +dependencies = [ + "amq-protocol-types", + "percent-encoding", + "url", +] + [[package]] name = "amqp_serde" version = "0.4.3" @@ -211,6 +261,45 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "asn1-rs" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56624a96882bb8c26d61312ae18cb45868e5a9992ea73c58e45c3101e56a1e60" +dependencies = [ + "asn1-rs-derive", + "asn1-rs-impl", + "displaydoc", + "nom 7.1.3", + "num-traits", + "rusticata-macros", + "thiserror 2.0.18", + "time", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c" +dependencies = [ + "proc-macro2", + "quote 1.0.45", + "syn 2.0.117", + "synstructure 0.13.2", +] + +[[package]] +name = "asn1-rs-impl" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" +dependencies = [ + "proc-macro2", + "quote 1.0.45", + "syn 2.0.117", +] + [[package]] name = "async-attributes" version = "1.1.2" @@ -244,6 +333,19 @@ dependencies = [ "pin-project-lite 0.2.17", ] +[[package]] +name = "async-compat" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ba85bc55464dcbf728b56d97e119d673f4cf9062be330a9a26f3acf504a590" +dependencies = [ + "futures-core", + "futures-io", + "once_cell", + "pin-project-lite 0.2.17", + "tokio 1.51.0", +] + [[package]] name = "async-executor" version = "1.14.0" @@ -275,6 +377,20 @@ dependencies = [ "tokio 1.51.0", ] +[[package]] +name = "async-global-executor" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13f937e26114b93193065fd44f507aa2e9169ad0cdabbb996920b1fe1ddea7ba" +dependencies = [ + "async-channel 2.5.0", + "async-executor", + "async-lock 3.4.2", + "blocking", + "futures-lite", + "tokio 1.51.0", +] + [[package]] name = "async-io" version = "2.6.0" @@ -342,6 +458,22 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "async-rs" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e32bd31386d41d0c06bd79b0397ec96e544d69d9dbd6db0236c7ceefe1ad61b" +dependencies = [ + "async-compat", + "async-global-executor 3.1.0", + "async-trait", + "futures-core", + "futures-io", + "hickory-resolver 0.26.1", + "tokio 1.51.0", + "tokio-stream", +] + [[package]] name = "async-signal" version = "0.2.13" @@ -368,7 +500,7 @@ checksum = "2c8e079a4ab67ae52b7403632e4618815d6db36d2a010cfe41b02c1b1578f93b" dependencies = [ "async-attributes", "async-channel 1.9.0", - "async-global-executor", + "async-global-executor 2.4.1", "async-io", "async-lock 3.4.2", "async-process", @@ -1130,6 +1262,15 @@ dependencies = [ "ubyte", ] +[[package]] +name = "backon" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cffb0e931875b666fc4fcb20fee52e9bbd1ef836fd9e9e04ec21555f9f85f7ef" +dependencies = [ + "fastrand 2.4.0", +] + [[package]] name = "backtrace" version = "0.3.76" @@ -1289,6 +1430,15 @@ dependencies = [ "generic-array 0.14.7", ] +[[package]] +name = "block-padding" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +dependencies = [ + "generic-array 0.14.7", +] + [[package]] name = "block2" version = "0.6.2" @@ -1441,6 +1591,15 @@ dependencies = [ "rustversion", ] +[[package]] +name = "cbc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +dependencies = [ + "cipher", +] + [[package]] name = "cc" version = "1.2.59" @@ -1482,6 +1641,17 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +[[package]] +name = "chacha20" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "rand_core 0.10.1", +] + [[package]] name = "chrono" version = "0.4.44" @@ -1514,6 +1684,18 @@ dependencies = [ "cc", ] +[[package]] +name = "cms" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b77c319abfd5219629c45c34c89ba945ed3c5e49fcde9d16b6c3885f118a730" +dependencies = [ + "const-oid 0.9.6", + "der 0.7.10", + "spki 0.7.3", + "x509-cert", +] + [[package]] name = "coarsetime" version = "0.1.37" @@ -1699,6 +1881,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + [[package]] name = "crc" version = "3.3.0" @@ -1907,7 +2098,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "curve25519-dalek-derive", "digest", "fiat-crypto", @@ -2128,7 +2319,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79b71cca7d95d7681a4b3b9cdf63c8dbc3730d0584c2c74e31416d64a90493f4" dependencies = [ "const-oid 0.6.2", - "der_derive", + "der_derive 0.4.1", ] [[package]] @@ -2149,10 +2340,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ "const-oid 0.9.6", + "der_derive 0.7.3", + "flagset", "pem-rfc7468 0.7.0", "zeroize", ] +[[package]] +name = "der-parser" +version = "10.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07da5016415d5a3c4dd39b11ed26f915f52fc4e0dc197d87908bc916e51bc1a6" +dependencies = [ + "asn1-rs", + "displaydoc", + "nom 7.1.3", + "num-bigint", + "num-traits", + "rusticata-macros", +] + [[package]] name = "der_derive" version = "0.4.1" @@ -2165,6 +2372,17 @@ dependencies = [ "synstructure 0.12.6", ] +[[package]] +name = "der_derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18" +dependencies = [ + "proc-macro2", + "quote 1.0.45", + "syn 2.0.117", +] + [[package]] name = "deranged" version = "0.5.8" @@ -2231,6 +2449,15 @@ dependencies = [ "unicode-xid 0.2.6", ] +[[package]] +name = "des" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdd80ce8ce993de27e9f063a444a4d53ce8e8db4c1f00cc03af5ad5a9867a1e" +dependencies = [ + "cipher", +] + [[package]] name = "devise" version = "0.4.2" @@ -2758,6 +2985,12 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" +[[package]] +name = "flagset" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7ac824320a75a52197e8f2d787f6a38b6718bb6897a35142d749af3c0e8f4fe" + [[package]] name = "flate2" version = "1.1.9" @@ -2777,6 +3010,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "flume" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e139bc46ca777eb5efaf62df0ab8cc5fd400866427e56c68b22e414e53bd3be" +dependencies = [ + "futures-core", + "futures-sink", + "spin 0.9.8", +] + [[package]] name = "fnv" version = "1.0.7" @@ -2973,6 +3217,17 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "futures-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f2f12607f92c69b12ed746fabf9ca4f5c482cba46679c1a75b874ed7c26adb" +dependencies = [ + "futures-io", + "rustls 0.23.37", + "rustls-pki-types", +] + [[package]] name = "futures-sink" version = "0.3.32" @@ -3096,6 +3351,7 @@ dependencies = [ "cfg-if", "libc", "r-efi 6.0.0", + "rand_core 0.10.1", "wasip2", "wasip3", ] @@ -3362,6 +3618,30 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hickory-net" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2295ed2f9c31e471e1428a8f88a3f0e1f4b27c15049592138d1eebe9c35b183" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "futures-channel", + "futures-io", + "futures-util", + "hickory-proto 0.26.1", + "idna 1.1.0", + "ipnet", + "jni 0.22.4", + "rand 0.10.1", + "thiserror 2.0.18", + "tinyvec", + "tokio 1.51.0", + "tracing", + "url", +] + [[package]] name = "hickory-proto" version = "0.25.2" @@ -3387,6 +3667,26 @@ dependencies = [ "url", ] +[[package]] +name = "hickory-proto" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bab31817bfb44672a252e97fe81cd0c18d1b2cf892108922f6818820df8c643" +dependencies = [ + "data-encoding", + "idna 1.1.0", + "ipnet", + "jni 0.22.4", + "once_cell", + "prefix-trie", + "rand 0.10.1", + "ring", + "thiserror 2.0.18", + "tinyvec", + "tracing", + "url", +] + [[package]] name = "hickory-resolver" version = "0.25.2" @@ -3395,7 +3695,7 @@ checksum = "dc62a9a99b0bfb44d2ab95a7208ac952d31060efc16241c87eaf36406fecf87a" dependencies = [ "cfg-if", "futures-util", - "hickory-proto", + "hickory-proto 0.25.2", "ipconfig", "moka", "once_cell", @@ -3408,6 +3708,32 @@ dependencies = [ "tracing", ] +[[package]] +name = "hickory-resolver" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d58d28879ceecde6607729660c2667a081ccdc082e082675042793960f178c" +dependencies = [ + "cfg-if", + "futures-util", + "hickory-net", + "hickory-proto 0.26.1", + "ipconfig", + "ipnet", + "jni 0.22.4", + "moka", + "ndk-context", + "once_cell", + "parking_lot", + "rand 0.10.1", + "resolv-conf", + "smallvec", + "system-configuration 0.7.0", + "thiserror 2.0.18", + "tokio 1.51.0", + "tracing", +] + [[package]] name = "hkdf" version = "0.12.4" @@ -3977,6 +4303,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" dependencies = [ + "block-padding", "generic-array 0.14.7", ] @@ -4018,6 +4345,9 @@ name = "ipnet" version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" +dependencies = [ + "serde", +] [[package]] name = "iri-string" @@ -4129,6 +4459,36 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "jni" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" +dependencies = [ + "cfg-if", + "combine", + "jni-macros", + "jni-sys 0.4.1", + "log", + "simd_cesu8", + "thiserror 2.0.18", + "walkdir", + "windows-link", +] + +[[package]] +name = "jni-macros" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" +dependencies = [ + "proc-macro2", + "quote 1.0.45", + "rustc_version", + "simd_cesu8", + "syn 2.0.117", +] + [[package]] name = "jni-sys" version = "0.3.1" @@ -4460,6 +4820,24 @@ dependencies = [ "log", ] +[[package]] +name = "lapin" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "478790661081f7434e111a31953acc1cf23654cf2a2d815d0e12cef9a2aed720" +dependencies = [ + "amq-protocol", + "async-rs", + "async-trait", + "atomic-waker", + "backon", + "cfg-if", + "flume", + "futures-core", + "futures-io", + "tracing", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -5008,8 +5386,8 @@ dependencies = [ "futures-io", "futures-util", "hex", - "hickory-proto", - "hickory-resolver", + "hickory-proto 0.25.2", + "hickory-resolver 0.25.2", "hmac", "macro_magic", "md-5", @@ -5118,6 +5496,12 @@ dependencies = [ "tempfile", ] +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + [[package]] name = "new_debug_unreachable" version = "1.0.6" @@ -5471,6 +5855,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "oid-registry" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f40cff3dde1b6087cc5d5f5d4d65712f34016a03ed60e9c08dcc392736b5b7" +dependencies = [ + "asn1-rs", +] + [[package]] name = "once_cell" version = "1.21.4" @@ -5575,6 +5968,29 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" +[[package]] +name = "p12-keystore" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb9bf5222606eb712d3bb30e01bc9420545b00859970897e70c682353a034f2" +dependencies = [ + "base64 0.22.1", + "cbc", + "cms", + "der 0.7.10", + "des", + "hex", + "hmac", + "pkcs12", + "pkcs5", + "rand 0.10.1", + "rc2", + "sha1", + "sha2", + "thiserror 2.0.18", + "x509-parser", +] + [[package]] name = "p256" version = "0.11.1" @@ -5701,6 +6117,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ "digest", + "hmac", ] [[package]] @@ -6092,6 +6509,36 @@ dependencies = [ "spki 0.7.3", ] +[[package]] +name = "pkcs12" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "695b3df3d3cc1015f12d70235e35b6b79befc5fa7a9b95b951eab1dd07c9efc2" +dependencies = [ + "cms", + "const-oid 0.9.6", + "der 0.7.10", + "digest", + "spki 0.7.3", + "x509-cert", + "zeroize", +] + +[[package]] +name = "pkcs5" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e847e2c91a18bfa887dd028ec33f2fe6f25db77db3619024764914affe8b69a6" +dependencies = [ + "aes", + "cbc", + "der 0.7.10", + "pbkdf2", + "scrypt", + "sha2", + "spki 0.7.3", +] + [[package]] name = "pkcs8" version = "0.9.0" @@ -6165,7 +6612,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "opaque-debug", "universal-hash", ] @@ -6206,6 +6653,17 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" +[[package]] +name = "prefix-trie" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90f561214012d3fc240a1f9c817cc4d57f5310910d066069c1b093f766bb5966" +dependencies = [ + "either", + "ipnet", + "num-traits", +] + [[package]] name = "pretty_env_logger" version = "0.4.0" @@ -6609,6 +7067,17 @@ dependencies = [ "rand_core 0.9.5", ] +[[package]] +name = "rand" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" +dependencies = [ + "chacha20", + "getrandom 0.4.2", + "rand_core 0.10.1", +] + [[package]] name = "rand_chacha" version = "0.3.1" @@ -6647,6 +7116,12 @@ dependencies = [ "getrandom 0.3.4", ] +[[package]] +name = "rand_core" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + [[package]] name = "rav1e" version = "0.8.1" @@ -6717,6 +7192,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "rc2" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62c64daa8e9438b84aaae55010a93f396f8e60e3911590fcba770d04643fc1dd" +dependencies = [ + "cipher", +] + [[package]] name = "redis" version = "0.23.3" @@ -6929,7 +7413,7 @@ dependencies = [ "quinn", "rustls 0.23.37", "rustls-pki-types", - "rustls-platform-verifier", + "rustls-platform-verifier 0.6.2", "serde", "serde_json", "serde_urlencoded", @@ -7069,11 +7553,19 @@ dependencies = [ name = "revolt-crond" version = "0.12.1" dependencies = [ + "futures-lite", + "iso8601-timestamp", + "lapin", "log", + "redis-kiss", "revolt-config", "revolt-database", "revolt-files", + "revolt-permissions", "revolt-result", + "revolt_optional_struct", + "serde", + "serde_json", "tokio 1.51.0", ] @@ -7108,6 +7600,7 @@ dependencies = [ "rand 0.8.5", "redis-kiss", "regex", + "revolt-coalesced", "revolt-config", "revolt-models", "revolt-parser", @@ -7793,6 +8286,15 @@ dependencies = [ "semver", ] +[[package]] +name = "rusticata-macros" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" +dependencies = [ + "nom 7.1.3", +] + [[package]] name = "rustix" version = "0.38.44" @@ -7861,6 +8363,21 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-connector" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26bcb6901a3319d57589047c0da93a0f3228f13abf8dd949deef024749cb5e2" +dependencies = [ + "futures-io", + "futures-rustls", + "log", + "rustls 0.23.37", + "rustls-pki-types", + "rustls-platform-verifier 0.7.0", + "rustls-webpki 0.103.10", +] + [[package]] name = "rustls-native-certs" version = "0.6.3" @@ -7921,7 +8438,28 @@ checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" dependencies = [ "core-foundation 0.10.1", "core-foundation-sys", - "jni", + "jni 0.21.1", + "log", + "once_cell", + "rustls 0.23.37", + "rustls-native-certs 0.8.3", + "rustls-platform-verifier-android", + "rustls-webpki 0.103.10", + "security-framework 3.7.0", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls-platform-verifier" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0" +dependencies = [ + "core-foundation 0.10.1", + "core-foundation-sys", + "jni 0.22.4", "log", "once_cell", "rustls 0.23.37", @@ -8003,6 +8541,15 @@ version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" +[[package]] +name = "salsa20" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" +dependencies = [ + "cipher", +] + [[package]] name = "same-file" version = "1.0.6" @@ -8075,6 +8622,17 @@ dependencies = [ "tendril", ] +[[package]] +name = "scrypt" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0516a385866c09368f0b5bcd1caff3366aace790fcd46e2bb032697bb172fd1f" +dependencies = [ + "pbkdf2", + "salsa20", + "sha2", +] + [[package]] name = "sct" version = "0.7.1" @@ -8493,7 +9051,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest", ] @@ -8504,7 +9062,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest", ] @@ -8521,7 +9079,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest", ] @@ -8576,6 +9134,16 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" +[[package]] +name = "simd_cesu8" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33" +dependencies = [ + "rustc_version", + "simdutf8", +] + [[package]] name = "simd_helpers" version = "0.1.0" @@ -8679,6 +9247,9 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] [[package]] name = "spin" @@ -8970,6 +9541,19 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "tcp-stream" +version = "0.34.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd7219422d3348cddeaf9073772997c452085c33e22d0b08cbd19652e1b16da5" +dependencies = [ + "async-rs", + "cfg-if", + "futures-io", + "p12-keystore", + "rustls-connector", +] + [[package]] name = "tempfile" version = "3.27.0" @@ -10733,6 +11317,34 @@ dependencies = [ "tap", ] +[[package]] +name = "x509-cert" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1301e935010a701ae5f8655edc0ad17c44bad3ac5ce8c39185f75453b720ae94" +dependencies = [ + "const-oid 0.9.6", + "der 0.7.10", + "spki 0.7.3", +] + +[[package]] +name = "x509-parser" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d43b0f71ce057da06bc0851b23ee24f3f86190b07203dd8f567d0b706a185202" +dependencies = [ + "asn1-rs", + "data-encoding", + "der-parser", + "lazy_static", + "nom 7.1.3", + "oid-registry", + "rusticata-macros", + "thiserror 2.0.18", + "time", +] + [[package]] name = "xmlparser" version = "0.13.6" diff --git a/Cargo.toml b/Cargo.toml index f10bfb261..6ce826ef7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -159,6 +159,7 @@ authifier = "1.0.16" # RabbitMQ amqprs = "1.7.0" +lapin = "4.7.1" # Voice livekit-api = "0.4.4" @@ -184,6 +185,7 @@ url = "2.2.2" impl_ops = "0.1.1" lazy_static = "1.5.0" mime = "0.3.17" +futures-lite = "2.6.1" # Build Dependencies vergen = "7.5.0" diff --git a/compose.yml b/compose.yml index a01c965e5..bb4cb8fec 100644 --- a/compose.yml +++ b/compose.yml @@ -8,10 +8,20 @@ services: # MongoDB database: image: mongo + command: mongod --replSet rs0 ports: - "27017:27017" volumes: - ./.data/db:/data/db + extra_hosts: + - "host.docker.internal:host-gateway" + healthcheck: + test: echo "try { rs.status() } catch (err) { rs.initiate({_id:'rs0',members:[{_id:0,host:'work-laptop.van-acoustic.ts.net:27017'}]}) }" | mongosh --port 27017 --quiet + interval: 5s + timeout: 30s + start_period: 0s + start_interval: 1s + retries: 30 ulimits: nofile: soft: 65536 @@ -19,8 +29,8 @@ services: # MinIO minio: - image: minio/minio - command: server /data + image: firstfinger/minio:latest + #command: server /data environment: MINIO_ROOT_USER: minioautumn MINIO_ROOT_PASSWORD: minioautumn diff --git a/crates/core/config/Revolt.toml b/crates/core/config/Revolt.toml index 2440bb316..ad2d69924 100644 --- a/crates/core/config/Revolt.toml +++ b/crates/core/config/Revolt.toml @@ -30,6 +30,10 @@ host = "rabbit" port = 5672 username = "rabbituser" password = "rabbitpass" +default_exchange = "revolt" + +[rabbit.queues] +acks = "internal.ack" [api] diff --git a/crates/core/config/src/lib.rs b/crates/core/config/src/lib.rs index 3dc2771a3..1ba041cac 100644 --- a/crates/core/config/src/lib.rs +++ b/crates/core/config/src/lib.rs @@ -122,12 +122,19 @@ pub struct Database { pub redis_pubsub: Option, } +#[derive(Deserialize, Debug, Clone)] +pub struct RabbitQueues { + pub acks: String, +} + #[derive(Deserialize, Debug, Clone)] pub struct Rabbit { pub host: String, pub port: u16, pub username: String, pub password: String, + pub default_exchange: String, + pub queues: RabbitQueues, } #[derive(Deserialize, Debug, Clone)] diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index ba5b7d1b9..be3119c56 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -38,6 +38,7 @@ revolt-models = { workspace = true, features = ["validator"] } revolt-presence = { workspace = true } revolt-permissions = { workspace = true, features = ["serde", "bson"] } revolt-parser = { workspace = true } +revolt-coalesced = { workspace = true } # Utility log = { workspace = true } diff --git a/crates/core/database/src/amqp/amqp.rs b/crates/core/database/src/amqp/amqp.rs index b29105edf..5358bc344 100644 --- a/crates/core/database/src/amqp/amqp.rs +++ b/crates/core/database/src/amqp/amqp.rs @@ -2,7 +2,10 @@ use std::collections::HashSet; use crate::events::rabbit::*; use crate::User; -use amqprs::channel::{BasicPublishArguments, ExchangeDeclareArguments}; +use amqprs::channel::{ + BasicPublishArguments, ExchangeDeclareArguments, ExchangeType, QueueBindArguments, + QueueDeclareArguments, +}; use amqprs::connection::OpenConnectionArguments; use amqprs::{channel::Channel, connection::Connection, error::Error as AMQPError}; use amqprs::{BasicProperties, FieldTable}; @@ -55,6 +58,43 @@ impl AMQP { AMQP::new(connection, channel) } + pub async fn configure_channels(&self) -> revolt_result::Result<()> { + let config = revolt_config::config().await; + + self.channel + .exchange_declare( + ExchangeDeclareArguments::new( + &config.rabbit.default_exchange, + &ExchangeType::Topic.to_string(), + ) + .durable(true) + .finish(), + ) + .await + .expect("Failed to declare exchange"); + + // Configure acks channel & routing + self.channel + .queue_declare( + QueueDeclareArguments::new(&config.rabbit.queues.acks) + .durable(true) + .no_wait(true) + .finish(), + ) + .await + .expect("Failed to bind queue"); + + self.channel + .queue_bind(QueueBindArguments::new( + &config.rabbit.queues.acks, + &config.rabbit.default_exchange, + &config.rabbit.queues.acks, + )) + .await + .expect("Failed to bind channel"); + Ok(()) + } + pub async fn friend_request_accepted( &self, accepted_request_user: &User, @@ -232,7 +272,9 @@ impl AMQP { .await } - pub async fn ack_message( + /// # Sends an ack to pushd to update badges on iPhones. + /// Not to be confused with the process_ack function, which handles sending all acks to crond for processing. + pub async fn ack_notification_message( &self, user_id: String, channel_id: String, @@ -316,4 +358,41 @@ impl AMQP { ) .await } + + /// # Send an ack to crond for processing + pub async fn process_ack( + &self, + user_id: &str, + channel_id: Option<&str>, + server_id: Option<&str>, + ) -> Result<(), AMQPError> { + let config = revolt_config::config().await; + + let payload = AckEventPayload { + user_id: user_id.to_string(), + channel_id: channel_id.map(|value| value.to_string()), + server_id: server_id.map(|value| value.to_string()), + }; + let payload = to_string(&payload).unwrap(); + + info!( + "Sending ack processor event on exchange {}, channel {}: {}", + config.rabbit.default_exchange, config.rabbit.queues.acks, payload + ); + + self.channel + .basic_publish( + BasicProperties::default() + .with_content_type("application/json") + .with_persistence(true) + //.with_headers(headers) + .finish(), + payload.into(), + BasicPublishArguments::new( + &config.rabbit.default_exchange, + &config.rabbit.queues.acks, + ), + ) + .await + } } diff --git a/crates/core/database/src/events/rabbit.rs b/crates/core/database/src/events/rabbit.rs index 6f5c9ab3c..1673f4a45 100644 --- a/crates/core/database/src/events/rabbit.rs +++ b/crates/core/database/src/events/rabbit.rs @@ -78,3 +78,11 @@ pub struct AckPayload { pub channel_id: String, pub message_id: String, } + +/// This is not the same as the AckPayload above, as the state for this event is stored in redis to allow for state updates while the event is queued. +#[derive(Serialize, Deserialize, Debug)] +pub struct AckEventPayload { + pub user_id: String, + pub channel_id: Option, + pub server_id: Option, +} diff --git a/crates/core/database/src/models/channels/model.rs b/crates/core/database/src/models/channels/model.rs index 025b7934b..74b56e110 100644 --- a/crates/core/database/src/models/channels/model.rs +++ b/crates/core/database/src/models/channels/model.rs @@ -1,6 +1,7 @@ #![allow(deprecated)] use std::{borrow::Cow, collections::HashMap}; +use redis_kiss::get_connection; use revolt_config::config; use revolt_models::v0::{self, MessageAuthor}; use revolt_permissions::OverrideField; @@ -212,7 +213,7 @@ impl Channel { role_permissions: HashMap::new(), nsfw: data.nsfw.unwrap_or(false), voice: data.voice.map(|voice| voice.into()), - slowmode: None + slowmode: None, }, v0::LegacyServerChannelType::Voice => Channel::TextChannel { id: id.clone(), @@ -225,7 +226,7 @@ impl Channel { role_permissions: HashMap::new(), nsfw: data.nsfw.unwrap_or(false), voice: Some(data.voice.unwrap_or_default().into()), - slowmode: None + slowmode: None, }, }; @@ -643,7 +644,7 @@ impl Channel { } /// Acknowledge a message - pub async fn ack(&self, user: &str, message: &str) -> Result<()> { + pub async fn ack(&self, user: &str, message: &str, amqp: &AMQP) -> Result<()> { EventV1::ChannelAck { id: self.id().to_string(), user: user.to_string(), @@ -652,17 +653,7 @@ impl Channel { .private(user.to_string()) .await; - #[cfg(feature = "tasks")] - crate::tasks::ack::queue_ack( - self.id().to_string(), - user.to_string(), - crate::tasks::ack::AckEvent::AckMessage { - id: message.to_string(), - }, - ) - .await; - - Ok(()) + crate::util::acker::ack_channel(user, self.id(), message, amqp).await } /// Remove user from a group diff --git a/crates/core/database/src/tasks/ack.rs b/crates/core/database/src/tasks/ack.rs index c26de03b7..24e3805ee 100644 --- a/crates/core/database/src/tasks/ack.rs +++ b/crates/core/database/src/tasks/ack.rs @@ -105,7 +105,11 @@ pub async fn handle_ack_event( if mentions_acked > 0 { if let Err(err) = amqp - .ack_message(user.to_string(), channel.to_string(), id.to_owned()) + .ack_notification_message( + user.to_string(), + channel.to_string(), + id.to_owned(), + ) .await { revolt_config::capture_error(&err); @@ -192,9 +196,7 @@ pub async fn handle_ack_event( .expect("Failed to fetch channel from db"); if let TextChannel { server, .. } = channel { - if let Err(err) = - amqp.mass_mention_message_sent(server, mass_mentions).await - { + if let Err(err) = amqp.mass_mention_message_sent(server, mass_mentions).await { revolt_config::capture_error(&err); } } else { diff --git a/crates/core/database/src/util/acker.rs b/crates/core/database/src/util/acker.rs new file mode 100644 index 000000000..8cc104c57 --- /dev/null +++ b/crates/core/database/src/util/acker.rs @@ -0,0 +1,77 @@ +use redis_kiss::{get_connection, AsyncCommands}; +use revolt_permissions::{calculate_channel_permissions, ChannelPermission}; +use revolt_result::{Result, ToRevoltError}; + +use crate::{events::client::EventV1, Channel, Database, Server, User, AMQP}; + +pub async fn ack_channel(user: &str, channel: &str, message: &str, amqp: &AMQP) -> Result<()> { + let mut redis = get_connection() + .await + .map_err(|_| create_error!(InternalError))?; + + let old: Option = redis + .getset(format!("acker:{user}+{channel}"), message) + .await + .to_internal_error()?; + + if old.is_none() || old.unwrap() == message { + amqp.process_ack(user, Some(channel), None) + .await + .to_internal_error()?; + } + + Ok(()) +} + +pub async fn ack_server(user: &User, server: &Server, db: &Database, amqp: &AMQP) -> Result<()> { + let mut redis = get_connection() + .await + .map_err(|_| create_error!(InternalError))?; + + let channels = db.fetch_channels(&server.channels).await?; + let query = crate::util::permissions::DatabasePermissionQuery::new(db, user).server(server); + + for channel in channels { + let channel_id = channel.id(); + let mut q = query.clone().channel(&channel); + + if calculate_channel_permissions(&mut q) + .await + .has_channel_permission(ChannelPermission::ViewChannel) + { + let channel_last_msg = match &channel { + Channel::TextChannel { + last_message_id, .. + } => last_message_id, + _ => unreachable!(), + } + .clone(); + + if let Some(channel_last_msg) = channel_last_msg { + let old: Option = redis + .getset( + format!("acker:{}+{}", user.id, channel_id), + &channel_last_msg, + ) + .await + .to_internal_error()?; + + if old.is_none() || old.unwrap() == channel_last_msg { + amqp.process_ack(&user.id, Some(channel_id), Some(&server.id)) + .await + .to_internal_error()?; + + EventV1::ChannelAck { + id: channel_id.to_string(), + user: user.id.clone(), + message_id: channel_last_msg, + } + .private(user.id.clone()) + .await; + } + } + } + } + + Ok(()) +} diff --git a/crates/core/database/src/util/mod.rs b/crates/core/database/src/util/mod.rs index 1a03a1768..ae2817ac0 100644 --- a/crates/core/database/src/util/mod.rs +++ b/crates/core/database/src/util/mod.rs @@ -1,3 +1,4 @@ +pub mod acker; pub mod bridge; pub mod bulk_permissions; mod funcs; diff --git a/crates/daemons/crond/Cargo.toml b/crates/daemons/crond/Cargo.toml index fe33d2b75..6bd900526 100644 --- a/crates/daemons/crond/Cargo.toml +++ b/crates/daemons/crond/Cargo.toml @@ -16,8 +16,22 @@ log = { workspace = true } # Async tokio = { workspace = true } +# Redis +redis-kiss = { workspace = true } + +# RabbitMQ +lapin = { workspace = true } +futures-lite = { workspace = true } + +# Processing +serde_json = { workspace = true } +revolt_optional_struct = { workspace = true } +serde = { workspace = true } +iso8601-timestamp = { workspace = true, features = ["serde", "bson"] } + # Core revolt-database = { workspace = true } revolt-result = { workspace = true } revolt-config = { workspace = true } revolt-files = { workspace = true } +revolt-permissions = { workspace = true } diff --git a/crates/daemons/crond/src/main.rs b/crates/daemons/crond/src/main.rs index b232a10a6..c45780d5e 100644 --- a/crates/daemons/crond/src/main.rs +++ b/crates/daemons/crond/src/main.rs @@ -1,7 +1,7 @@ use revolt_config::configure; use revolt_database::DatabaseInfo; use revolt_result::Result; -use tasks::{file_deletion, prune_dangling_files, prune_members}; +use tasks::{acks, file_deletion, prune_dangling_files, prune_members}; use tokio::try_join; pub mod tasks; @@ -14,7 +14,8 @@ async fn main() -> Result<()> { try_join!( file_deletion::task(db.clone()), prune_dangling_files::task(db.clone()), - prune_members::task(db.clone()) + prune_members::task(db.clone()), + acks::task(db.clone()) ) .map(|_| ()) } diff --git a/crates/daemons/crond/src/tasks/acks.rs b/crates/daemons/crond/src/tasks/acks.rs new file mode 100644 index 000000000..68b13144f --- /dev/null +++ b/crates/daemons/crond/src/tasks/acks.rs @@ -0,0 +1,129 @@ +use futures_lite::stream::StreamExt; +use lapin::{ + options::*, + types::FieldTable, + uri::{AMQPAuthority, AMQPQueryString, AMQPUri, AMQPUserInfo}, + ConnectionBuilder, ConnectionProperties, +}; +use log::info; +use redis_kiss::{get_connection, AsyncCommands, Conn as RedisConnection}; +use revolt_config::config; +use revolt_database::{events::rabbit::AckEventPayload, Database}; +use revolt_result::{Result, ToRevoltError}; +use serde_json; + +pub async fn task(db: Database) -> Result<()> { + let config = config().await; + + let mut redis = get_connection() + .await + .expect("Failed to get redis connection"); + + let uri = AMQPUri { + scheme: lapin::uri::AMQPScheme::AMQP, + authority: AMQPAuthority { + userinfo: AMQPUserInfo { + username: config.rabbit.username, + password: config.rabbit.password, + }, + host: config.rabbit.host, + port: config.rabbit.port, + }, + vhost: "/".to_string(), + query: AMQPQueryString::default(), + }; + + let connection = ConnectionBuilder::new() + .expect("Builder") + .with_uri(uri) + .with_properties(ConnectionProperties::default()) + .connect() + .await + .expect("Failed to connect to rabbitmq"); + + let reader_channel = connection + .create_channel() + .await + .expect("Failed to create channel"); + + let mut consumer = reader_channel + .basic_consume( + config.rabbit.queues.acks.into(), + "crond-ack-consumer".into(), + BasicConsumeOptions::default(), + FieldTable::default(), + ) + .await + .expect("Failed to create consumer"); + + while let Some(delivery) = consumer.next().await { + if let Ok(delivery) = delivery { + let payload: std::result::Result = + serde_json::from_slice(&delivery.data); + if let Ok(payload) = payload { + info!("{:?}", payload); + if let Err(e) = process_channel_ack( + &db, + payload.user_id, + payload.channel_id.unwrap(), + &mut redis, + ) + .await + { + revolt_config::capture_error(&e); + _ = delivery.reject(BasicRejectOptions { requeue: false }).await; + } else { + _ = delivery.ack(BasicAckOptions { multiple: false }).await; + } + } else { + revolt_config::capture_message( + format!("Failed to decode ack data: {:?}", delivery.data).as_str(), + revolt_config::Level::Error, + ); + } + } + } + Ok(()) +} + +#[allow(clippy::disallowed_methods)] +async fn process_channel_ack( + db: &Database, + user: String, + channel: String, + redis: &mut RedisConnection, +) -> Result<()> { + let message_id: Option = redis + .get_del(format!("acker:{user}+{channel}")) + .await + .to_internal_error()?; + + if let Some(message_id) = message_id { + // This will be uncommented eventually, but we need to sort out the transition to lapin first. For now we'll simply disable the badge update logic. + // We also drop a db request as a bonus. + + //let unread = db.fetch_unread(&user, &channel).await?; + let _updated = db.acknowledge_message(&channel, &user, &message_id).await?; + info!("Set new state for ack: {}:{}:{}", channel, user, message_id); + + // if let (Some(before), Some(after)) = (unread, updated) { + // let before_mentions = before.mentions.unwrap_or_default().len(); + // let after_mentions = after.mentions.unwrap_or_default().len(); + + // let mentions_acked = before_mentions - after_mentions; + + // if mentions_acked > 0 { + // if let Err(err) = amqp + // .ack_message(user.to_string(), channel.to_string(), payload.message_id) + // .await + // { + // revolt_config::capture_error(&err); + // } + // }; + // } + + Ok(()) + } else { + Err(message_id.to_internal_error().expect_err("no err")) + } +} diff --git a/crates/daemons/crond/src/tasks/mod.rs b/crates/daemons/crond/src/tasks/mod.rs index 060f55d89..a7dd9040c 100644 --- a/crates/daemons/crond/src/tasks/mod.rs +++ b/crates/daemons/crond/src/tasks/mod.rs @@ -1,3 +1,4 @@ +pub mod acks; pub mod file_deletion; pub mod prune_dangling_files; pub mod prune_members; diff --git a/crates/delta/src/main.rs b/crates/delta/src/main.rs index 882609cce..e3522de1d 100644 --- a/crates/delta/src/main.rs +++ b/crates/delta/src/main.rs @@ -24,8 +24,8 @@ use amqprs::{ }; use async_std::channel::unbounded; use authifier::AuthifierEvent; -use rocket::data::ToByteUnit; use revolt_database::voice::VoiceClient; +use rocket::data::ToByteUnit; pub async fn web() -> Rocket { // Get settings @@ -93,22 +93,6 @@ pub async fn web() -> Rocket { ) .into(); - let swagger_0_8 = revolt_rocket_okapi::swagger_ui::make_swagger_ui( - &revolt_rocket_okapi::swagger_ui::SwaggerUIConfig { - url: "/0.8/openapi.json".to_owned(), - ..Default::default() - }, - ) - .into(); - - let swagger_0_8 = revolt_rocket_okapi::swagger_ui::make_swagger_ui( - &revolt_rocket_okapi::swagger_ui::SwaggerUIConfig { - url: "/0.8/openapi.json".to_owned(), - ..Default::default() - }, - ) - .into(); - // Voice handler let voice_client = VoiceClient::new(config.api.livekit.nodes.clone()); // Configure Rabbit @@ -136,6 +120,9 @@ pub async fn web() -> Rocket { .expect("Failed to declare exchange"); let amqp = AMQP::new(connection, channel); + amqp.configure_channels() + .await + .expect("Failed to configure channels"); // Launch background task workers revolt_database::tasks::start_workers(db.clone(), amqp.clone()); @@ -153,7 +140,6 @@ pub async fn web() -> Rocket { .mount("/", rocket_cors::catch_all_options_routes()) .mount("/", ratelimiter::routes()) .mount("/swagger/", swagger) - .mount("/0.8/swagger/", swagger_0_8) .manage(authifier) .manage(db) .manage(amqp) diff --git a/crates/delta/src/routes/channels/channel_ack.rs b/crates/delta/src/routes/channels/channel_ack.rs index 2ae0d3b08..e20da642c 100644 --- a/crates/delta/src/routes/channels/channel_ack.rs +++ b/crates/delta/src/routes/channels/channel_ack.rs @@ -1,6 +1,6 @@ use revolt_database::{ util::{permissions::DatabasePermissionQuery, reference::Reference}, - Database, User, + Database, User, AMQP, }; use revolt_permissions::{calculate_channel_permissions, ChannelPermission}; use revolt_result::{create_error, Result}; @@ -14,6 +14,7 @@ use rocket_empty::EmptyResponse; #[put("//ack/")] pub async fn ack( db: &State, + amqp: &State, user: User, target: Reference<'_>, message: Reference<'_>, @@ -29,7 +30,7 @@ pub async fn ack( .throw_if_lacking_channel_permission(ChannelPermission::ViewChannel)?; channel - .ack(&user.id, message.id) + .ack(&user.id, message.id, amqp) .await .map(|_| EmptyResponse) } diff --git a/crates/delta/src/routes/servers/server_ack.rs b/crates/delta/src/routes/servers/server_ack.rs index 789617e11..81ae683e0 100644 --- a/crates/delta/src/routes/servers/server_ack.rs +++ b/crates/delta/src/routes/servers/server_ack.rs @@ -1,6 +1,6 @@ use revolt_database::{ - util::{permissions::DatabasePermissionQuery, reference::Reference}, - Database, User, + util::{acker, permissions::DatabasePermissionQuery, reference::Reference}, + Database, User, AMQP, }; use revolt_permissions::PermissionQuery; use revolt_result::{create_error, Result}; @@ -12,7 +12,12 @@ use rocket_empty::EmptyResponse; /// Mark all channels in a server as read. #[openapi(tag = "Server Information")] #[put("//ack")] -pub async fn ack(db: &State, user: User, target: Reference<'_>) -> Result { +pub async fn ack( + db: &State, + amqp: &State, + user: User, + target: Reference<'_>, +) -> Result { if user.bot.is_some() { return Err(create_error!(IsBot)); } @@ -23,7 +28,6 @@ pub async fn ack(db: &State, user: User, target: Reference<'_>) -> Res return Err(create_error!(NotFound)); } - db.acknowledge_channels(&user.id, &server.channels) - .await - .map(|_| EmptyResponse) + acker::ack_server(&user, &server, db, amqp).await?; + Ok(EmptyResponse) } From 0719985ac5636590f91e6f9ec4b68f3eded70c13 Mon Sep 17 00:00:00 2001 From: Tom Date: Fri, 8 May 2026 15:22:10 -0700 Subject: [PATCH 159/211] fix: docker compose file had personal url in it (#742) --- compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compose.yml b/compose.yml index bb4cb8fec..bf2c2ca1f 100644 --- a/compose.yml +++ b/compose.yml @@ -16,7 +16,7 @@ services: extra_hosts: - "host.docker.internal:host-gateway" healthcheck: - test: echo "try { rs.status() } catch (err) { rs.initiate({_id:'rs0',members:[{_id:0,host:'work-laptop.van-acoustic.ts.net:27017'}]}) }" | mongosh --port 27017 --quiet + test: echo "try { rs.status() } catch (err) { rs.initiate({_id:'rs0',members:[{_id:0,host:'127.0.0.1:27017'}]}) }" | mongosh --port 27017 --quiet interval: 5s timeout: 30s start_period: 0s From d46c7f7f3c04524c0639c3e0a122626f8e0b3bf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0spik?= Date: Sat, 9 May 2026 01:23:30 +0300 Subject: [PATCH 160/211] feat: add embed support for YouTube Shorts (#734) * feat: add embed support for YouTube Shorts Signed-off-by: ispik * feat: blacklist private ip ranges and add january domain blocklist Signed-off-by: IAmTomahawkx * fix: remove duplicates Signed-off-by: ispik --------- Signed-off-by: ispik Signed-off-by: IAmTomahawkx Co-authored-by: IAmTomahawkx --- crates/services/january/src/requests.rs | 10 ++++++++++ crates/services/january/src/website_embed.rs | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/crates/services/january/src/requests.rs b/crates/services/january/src/requests.rs index bec5bc1db..b63f203e7 100644 --- a/crates/services/january/src/requests.rs +++ b/crates/services/january/src/requests.rs @@ -33,6 +33,9 @@ lazy_static! { /// Regex for matching new Reddit URLs static ref RE_URL_NEW_REDDIT: Regex = Regex::new("^(?:(?:new\\.|www\\.)?reddit).com").expect("valid regex"); + /// Regex for matching YouTube Shorts URLs + static ref RE_URL_YOUTUBE_SHORTS: Regex = Regex::new("^(?:(?:https?:)?//)?(?:(?:www\\.)?youtube\\.com)/shorts/([a-zA-Z0-9_-]+)").expect("valid regex"); + /// Cache for proxy results static ref PROXY_CACHE: moka::future::Cache)>> = moka::future::Cache::builder() .weigher(|_key, value: &Result<(String, Vec)>| -> u32 { @@ -214,6 +217,13 @@ impl Request { .to_string(); } + // Re-map Youtube Shorts to regular Youtube links + if let Some(captures) = RE_URL_YOUTUBE_SHORTS.captures(&url) { + if let Some(video_id) = captures.get(1) { + url = format!("https://youtube.com/watch?v={}", video_id.as_str()); + } + } + // Generate the actual embed if let Some(hit) = EMBED_CACHE.get(&url).await { Ok(hit) diff --git a/crates/services/january/src/website_embed.rs b/crates/services/january/src/website_embed.rs index 6ab1af580..0e025b73b 100644 --- a/crates/services/january/src/website_embed.rs +++ b/crates/services/january/src/website_embed.rs @@ -190,7 +190,7 @@ pub async fn create_website_embed(original_url: &str, document: &str) -> Option< pub async fn populate_special(original_url: String, metadata: &mut WebsiteMetadata) { lazy_static! { - static ref RE_YOUTUBE: Regex = Regex::new("^(?:(?:https?:)?//)?(?:(?:www|m)\\.)?(?:(?:youtube\\.com|youtu.be))(?:/(?:[\\w\\-]+\\?v=|embed/|v/)?)([\\w\\-]+)(?:\\S+)?$").unwrap(); + static ref RE_YOUTUBE: Regex = Regex::new("^(?:(?:https?:)?//)?(?:(?:www|m)\\.)?(?:(?:youtube\\.com|youtu.be))(?:/(?:[\\w\\-]+\\?v=|embed/|v/|shorts/)?)([\\w\\-]+)(?:\\S+)?$").unwrap(); static ref RE_LIGHTSPEED: Regex = Regex::new("^(?:https?://)?(?:[\\w]+\\.)?lightspeed\\.tv/([a-z0-9_]{4,25})").unwrap(); From 23ad1359834bb7d07a460b8678d6a6ebffc73eb0 Mon Sep 17 00:00:00 2001 From: Gabriel <60961939+gabrielfordevelopment@users.noreply.github.com> Date: Sat, 9 May 2026 00:23:57 +0200 Subject: [PATCH 161/211] feat: add emoji rename endpoint (#714) * feat: add rename endpoint with rename-only update Signed-off-by: Gabriel <60961939+gabrielfordevelopment@users.noreply.github.com> * fix: enforce detached emoji edit restrictions Signed-off-by: Gabriel <60961939+gabrielfordevelopment@users.noreply.github.com> * fix: always enforce emoji edit permissions Signed-off-by: Gabriel <60961939+gabrielfordevelopment@users.noreply.github.com> --------- Signed-off-by: Gabriel <60961939+gabrielfordevelopment@users.noreply.github.com> --- crates/core/database/src/events/client.rs | 8 +- .../core/database/src/models/emojis/model.rs | 27 +++ crates/core/database/src/models/emojis/ops.rs | 5 +- .../database/src/models/emojis/ops/mongodb.rs | 7 +- .../src/models/emojis/ops/reference.rs | 15 +- crates/core/models/src/v0/emojis.rs | 18 ++ .../src/routes/customisation/emoji_edit.rs | 212 ++++++++++++++++++ crates/delta/src/routes/customisation/mod.rs | 2 + docs/docs/developers/events/protocol.md | 16 ++ 9 files changed, 306 insertions(+), 4 deletions(-) create mode 100644 crates/delta/src/routes/customisation/emoji_edit.rs diff --git a/crates/core/database/src/events/client.rs b/crates/core/database/src/events/client.rs index 4615273d2..38c6f9417 100644 --- a/crates/core/database/src/events/client.rs +++ b/crates/core/database/src/events/client.rs @@ -3,7 +3,7 @@ use revolt_result::Error; use serde::{Deserialize, Serialize}; use revolt_models::v0::{ - AppendMessage, Channel, ChannelUnread, ChannelVoiceState, Emoji, FieldsChannel, FieldsMember, FieldsMessage, FieldsRole, FieldsServer, FieldsUser, FieldsWebhook, Member, MemberCompositeKey, Message, PartialChannel, PartialMember, PartialMessage, PartialRole, PartialServer, PartialUser, PartialUserVoiceState, PartialWebhook, PolicyChange, RemovalIntention, Report, Server, User, UserSettings, UserVoiceState, Webhook + AppendMessage, Channel, ChannelUnread, ChannelVoiceState, Emoji, FieldsChannel, FieldsMember, FieldsMessage, FieldsRole, FieldsServer, FieldsUser, FieldsWebhook, Member, MemberCompositeKey, Message, PartialChannel, PartialEmoji, PartialMember, PartialMessage, PartialRole, PartialServer, PartialUser, PartialUserVoiceState, PartialWebhook, PolicyChange, RemovalIntention, Report, Server, User, UserSettings, UserVoiceState, Webhook }; use crate::Database; @@ -219,6 +219,12 @@ pub enum EventV1 { /// New emoji EmojiCreate(Emoji), + /// Update existing emoji + EmojiUpdate { + id: String, + data: PartialEmoji, + }, + /// Delete emoji EmojiDelete { id: String }, diff --git a/crates/core/database/src/models/emojis/model.rs b/crates/core/database/src/models/emojis/model.rs index 8294d7c72..3f380716a 100644 --- a/crates/core/database/src/models/emojis/model.rs +++ b/crates/core/database/src/models/emojis/model.rs @@ -2,6 +2,7 @@ use std::collections::HashSet; use std::str::FromStr; use once_cell::sync::Lazy; +use revolt_models::v0; use revolt_result::Result; use ulid::Ulid; @@ -41,6 +42,12 @@ auto_derived!( Server { id: String }, Detached, } + + /// Partial representation of an emoji + pub struct PartialEmoji { + #[serde(skip_serializing_if = "Option::is_none")] + pub name: Option, + } ); #[allow(clippy::disallowed_methods)] @@ -75,6 +82,26 @@ impl Emoji { db.detach_emoji(&self).await } + /// Update an emoji + pub async fn update(&mut self, db: &Database, partial: PartialEmoji) -> Result<()> { + if let Some(name) = partial.name.clone() { + self.name = name; + } + + db.update_emoji(&self.id, &partial).await?; + + EventV1::EmojiUpdate { + id: self.id.clone(), + data: v0::PartialEmoji { + name: partial.name.clone(), + }, + } + .p(self.parent().to_string()) + .await; + + Ok(()) + } + /// Check whether we can use a given emoji pub async fn can_use(db: &Database, emoji: &str) -> Result { if Ulid::from_str(emoji).is_ok() { diff --git a/crates/core/database/src/models/emojis/ops.rs b/crates/core/database/src/models/emojis/ops.rs index 26e23acaf..d28f30d4e 100644 --- a/crates/core/database/src/models/emojis/ops.rs +++ b/crates/core/database/src/models/emojis/ops.rs @@ -1,6 +1,6 @@ use revolt_result::Result; -use crate::Emoji; +use crate::{Emoji, PartialEmoji}; #[cfg(feature = "mongodb")] mod mongodb; @@ -20,6 +20,9 @@ pub trait AbstractEmojis: Sync + Send { /// Fetch emoji by their parent ids async fn fetch_emoji_by_parent_ids(&self, parent_ids: &[String]) -> Result>; + /// Update emoji with new information + async fn update_emoji(&self, emoji_id: &str, partial: &PartialEmoji) -> Result<()>; + /// Detach an emoji by its id async fn detach_emoji(&self, emoji: &Emoji) -> Result<()>; } diff --git a/crates/core/database/src/models/emojis/ops/mongodb.rs b/crates/core/database/src/models/emojis/ops/mongodb.rs index 6dd3137b7..ad7b557ca 100644 --- a/crates/core/database/src/models/emojis/ops/mongodb.rs +++ b/crates/core/database/src/models/emojis/ops/mongodb.rs @@ -1,7 +1,7 @@ use bson::Document; use revolt_result::Result; -use crate::Emoji; +use crate::{Emoji, PartialEmoji}; use crate::MongoDb; use super::AbstractEmojis; @@ -46,6 +46,11 @@ impl AbstractEmojis for MongoDb { ) } + /// Update emoji with new information + async fn update_emoji(&self, emoji_id: &str, partial: &PartialEmoji) -> Result<()> { + query!(self, update_one_by_id, COL, emoji_id, partial, vec![], None).map(|_| ()) + } + /// Detach an emoji by its id async fn detach_emoji(&self, emoji: &Emoji) -> Result<()> { self.col::(COL) diff --git a/crates/core/database/src/models/emojis/ops/reference.rs b/crates/core/database/src/models/emojis/ops/reference.rs index 2f0c2a2df..2f9be4352 100644 --- a/crates/core/database/src/models/emojis/ops/reference.rs +++ b/crates/core/database/src/models/emojis/ops/reference.rs @@ -1,6 +1,6 @@ use revolt_result::Result; -use crate::Emoji; +use crate::{Emoji, PartialEmoji}; use crate::EmojiParent; use crate::ReferenceDb; @@ -54,6 +54,19 @@ impl AbstractEmojis for ReferenceDb { .collect()) } + /// Update emoji with new information + async fn update_emoji(&self, emoji_id: &str, partial: &PartialEmoji) -> Result<()> { + let mut emojis = self.emojis.lock().await; + if let Some(emoji) = emojis.get_mut(emoji_id) { + if let Some(name) = partial.name.clone() { + emoji.name = name; + } + Ok(()) + } else { + Err(create_error!(NotFound)) + } + } + /// Detach an emoji by its id async fn detach_emoji(&self, emoji: &Emoji) -> Result<()> { let mut emojis = self.emojis.lock().await; diff --git a/crates/core/models/src/v0/emojis.rs b/crates/core/models/src/v0/emojis.rs index 2d7c015e1..58d47429a 100644 --- a/crates/core/models/src/v0/emojis.rs +++ b/crates/core/models/src/v0/emojis.rs @@ -54,4 +54,22 @@ auto_derived!( #[serde(default)] pub nsfw: bool, } + + /// Partial emoji representation + #[derive(Default)] + pub struct PartialEmoji { + #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + pub name: Option, + } + + /// Edit emoji information + #[cfg_attr(feature = "validator", derive(Validate))] + pub struct DataEditEmoji { + /// Emoji name + #[cfg_attr( + feature = "validator", + validate(length(min = 1, max = 32), regex = "RE_EMOJI") + )] + pub name: Option, + } ); diff --git a/crates/delta/src/routes/customisation/emoji_edit.rs b/crates/delta/src/routes/customisation/emoji_edit.rs new file mode 100644 index 000000000..72e99e341 --- /dev/null +++ b/crates/delta/src/routes/customisation/emoji_edit.rs @@ -0,0 +1,212 @@ +use revolt_database::{ + util::{permissions::DatabasePermissionQuery, reference::Reference}, + Database, EmojiParent, PartialEmoji, User, +}; +use revolt_models::v0; +use revolt_permissions::{calculate_server_permissions, ChannelPermission}; +use revolt_result::{create_error, Result}; +use rocket::{serde::json::Json, State}; +use validator::Validate; + +/// # Edit Emoji +/// +/// Edit an emoji by its id. +#[openapi(tag = "Emojis")] +#[patch("/emoji/", data = "")] +pub async fn edit_emoji( + db: &State, + user: User, + emoji_id: Reference<'_>, + data: Json, +) -> Result> { + let data = data.into_inner(); + data.validate().map_err(|error| { + create_error!(FailedValidation { + error: error.to_string() + }) + })?; + + let mut emoji = emoji_id.as_emoji(db).await?; + + match &emoji.parent { + EmojiParent::Server { id } => { + let server = db.fetch_server(id.as_str()).await?; + + let mut query = DatabasePermissionQuery::new(db, &user).server(&server); + calculate_server_permissions(&mut query) + .await + .throw_if_lacking_channel_permission(ChannelPermission::ManageCustomisation)?; + } + EmojiParent::Detached => return Err(create_error!(NotAuthenticated)), + } + + if data.name.is_none() { + return Ok(Json(emoji.into())); + } + + let partial = PartialEmoji { name: data.name }; + emoji.update(db, partial).await?; + + Ok(Json(emoji.into())) +} + +#[cfg(test)] +mod test { + use crate::util::test::TestHarness; + use revolt_database::{Emoji, EmojiParent, Member}; + use revolt_models::v0; + use rocket::http::{ContentType, Header, Status}; + use ulid::Ulid; + + #[rocket::async_test] + async fn edit_emoji_name_as_creator() { + let harness = TestHarness::new().await; + let (_, session, user) = harness.new_user().await; + let (server, _) = harness.new_server(&user).await; + + let emoji_id = Ulid::new().to_string(); + let emoji = Emoji { + id: emoji_id.clone(), + parent: EmojiParent::Server { + id: server.id.clone(), + }, + creator_id: user.id.clone(), + name: "initial_name".to_string(), + animated: false, + nsfw: false, + }; + emoji.create(&harness.db).await.expect("`Emoji` created"); + + let response = harness + .client + .patch(format!("/custom/emoji/{emoji_id}")) + .header(Header::new("x-session-token", session.token.to_string())) + .header(ContentType::JSON) + .body( + json!(v0::DataEditEmoji { + name: Some("renamed_emoji".to_string()), + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(response.status(), Status::Ok); + + let edited: v0::Emoji = response.into_json().await.expect("`Emoji`"); + assert_eq!(edited.name, "renamed_emoji"); + } + + #[rocket::async_test] + async fn reject_invalid_emoji_name() { + let harness = TestHarness::new().await; + let (_, session, user) = harness.new_user().await; + let (server, _) = harness.new_server(&user).await; + + let emoji_id = Ulid::new().to_string(); + let emoji = Emoji { + id: emoji_id.clone(), + parent: EmojiParent::Server { + id: server.id.clone(), + }, + creator_id: user.id.clone(), + name: "valid_name".to_string(), + animated: false, + nsfw: false, + }; + emoji.create(&harness.db).await.expect("`Emoji` created"); + + let response = harness + .client + .patch(format!("/custom/emoji/{emoji_id}")) + .header(Header::new("x-session-token", session.token.to_string())) + .header(ContentType::JSON) + .body( + json!(v0::DataEditEmoji { + name: Some("Invalid Name".to_string()), + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(response.status(), Status::BadRequest); + } + + #[rocket::async_test] + async fn reject_edit_for_detached_emoji() { + let harness = TestHarness::new().await; + let (_, session, user) = harness.new_user().await; + + let emoji_id = Ulid::new().to_string(); + let emoji = Emoji { + id: emoji_id.clone(), + parent: EmojiParent::Detached, + creator_id: user.id.clone(), + name: "detached_name".to_string(), + animated: false, + nsfw: false, + }; + emoji.create(&harness.db).await.expect("`Emoji` created"); + + let response = harness + .client + .patch(format!("/custom/emoji/{emoji_id}")) + .header(Header::new("x-session-token", session.token.to_string())) + .header(ContentType::JSON) + .body( + json!(v0::DataEditEmoji { + name: Some("should_not_apply".to_string()), + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(response.status(), Status::Unauthorized); + } + + #[rocket::async_test] + async fn reject_edit_for_creator_without_manage_customisation() { + let harness = TestHarness::new().await; + let (_, _, owner) = harness.new_user().await; + let (_, creator_session, creator) = harness.new_user().await; + let (server, _) = harness.new_server(&owner).await; + + Member::create(&harness.db, &server, &creator, None) + .await + .expect("`Member` created"); + + let emoji_id = Ulid::new().to_string(); + let emoji = Emoji { + id: emoji_id.clone(), + parent: EmojiParent::Server { + id: server.id.clone(), + }, + creator_id: creator.id.clone(), + name: "member_uploaded_name".to_string(), + animated: false, + nsfw: false, + }; + emoji.create(&harness.db).await.expect("`Emoji` created"); + + let response = harness + .client + .patch(format!("/custom/emoji/{emoji_id}")) + .header(Header::new( + "x-session-token", + creator_session.token.to_string(), + )) + .header(ContentType::JSON) + .body( + json!(v0::DataEditEmoji { + name: Some("renamed_without_permission".to_string()), + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(response.status(), Status::Forbidden); + } +} diff --git a/crates/delta/src/routes/customisation/mod.rs b/crates/delta/src/routes/customisation/mod.rs index 56d40995d..5ff6f6992 100644 --- a/crates/delta/src/routes/customisation/mod.rs +++ b/crates/delta/src/routes/customisation/mod.rs @@ -3,12 +3,14 @@ use rocket::Route; mod emoji_create; mod emoji_delete; +mod emoji_edit; mod emoji_fetch; pub fn routes() -> (Vec, OpenApi) { openapi_get_routes_spec![ emoji_create::create_emoji, emoji_delete::delete_emoji, + emoji_edit::edit_emoji, emoji_fetch::fetch_emoji ] } diff --git a/docs/docs/developers/events/protocol.md b/docs/docs/developers/events/protocol.md index 1c8a8618f..6e0c8d5ea 100644 --- a/docs/docs/developers/events/protocol.md +++ b/docs/docs/developers/events/protocol.md @@ -539,6 +539,22 @@ Emoji created, the event object has the same schema as the Emoji object in the A } ``` +### EmojiUpdate + +Emoji has been updated. + +```json +{ + "type": "EmojiUpdate", + "id": "{emoji_id}", + "data": { + "name"?: "{emoji_name}" + } +} +``` + +- `data` field contains a partial Emoji object. + ### EmojiDelete Emoji has been deleted. From 6f3441cf4acac2a8e6e1bf07a279a153b80f7956 Mon Sep 17 00:00:00 2001 From: Taureon <45183108+Taureon@users.noreply.github.com> Date: Sat, 9 May 2026 00:37:00 +0200 Subject: [PATCH 162/211] feat: Add webhook endpoints for editing and deleting messages (#682) * feat: ErrorType.CannotDeleteMessage, needed later Signed-off-by: Taureon * feat: webhook edit/delete message endpoints Signed-off-by: Taureon * lol, lmao even Signed-off-by: Taureon * fix contradictory comment Signed-off-by: Taureon --------- Signed-off-by: Taureon Co-authored-by: Taureon --- crates/core/result/src/axum.rs | 1 + crates/core/result/src/lib.rs | 1 + crates/core/result/src/rocket.rs | 1 + crates/delta/src/routes/webhooks/mod.rs | 10 ++- .../routes/webhooks/webhook_delete_message.rs | 27 ++++++ .../routes/webhooks/webhook_edit_message.rs | 84 +++++++++++++++++++ 6 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 crates/delta/src/routes/webhooks/webhook_delete_message.rs create mode 100644 crates/delta/src/routes/webhooks/webhook_edit_message.rs diff --git a/crates/core/result/src/axum.rs b/crates/core/result/src/axum.rs index f465854bf..440c4fc4b 100644 --- a/crates/core/result/src/axum.rs +++ b/crates/core/result/src/axum.rs @@ -24,6 +24,7 @@ impl IntoResponse for Error { ErrorType::UnknownChannel => StatusCode::NOT_FOUND, ErrorType::UnknownMessage => StatusCode::NOT_FOUND, ErrorType::UnknownAttachment => StatusCode::BAD_REQUEST, + ErrorType::CannotDeleteMessage => StatusCode::FORBIDDEN, ErrorType::CannotEditMessage => StatusCode::FORBIDDEN, ErrorType::CannotJoinCall => StatusCode::BAD_REQUEST, ErrorType::TooManyAttachments { .. } => StatusCode::BAD_REQUEST, diff --git a/crates/core/result/src/lib.rs b/crates/core/result/src/lib.rs index e4907a6b5..4124a0476 100644 --- a/crates/core/result/src/lib.rs +++ b/crates/core/result/src/lib.rs @@ -78,6 +78,7 @@ pub enum ErrorType { UnknownChannel, UnknownAttachment, UnknownMessage, + CannotDeleteMessage, CannotEditMessage, CannotJoinCall, TooManyAttachments { diff --git a/crates/core/result/src/rocket.rs b/crates/core/result/src/rocket.rs index 649375e28..76719149a 100644 --- a/crates/core/result/src/rocket.rs +++ b/crates/core/result/src/rocket.rs @@ -30,6 +30,7 @@ impl<'r> Responder<'r, 'static> for Error { ErrorType::UnknownChannel => Status::NotFound, ErrorType::UnknownMessage => Status::NotFound, ErrorType::UnknownAttachment => Status::BadRequest, + ErrorType::CannotDeleteMessage => Status::Forbidden, ErrorType::CannotEditMessage => Status::Forbidden, ErrorType::CannotJoinCall => Status::BadRequest, ErrorType::TooManyAttachments { .. } => Status::BadRequest, diff --git a/crates/delta/src/routes/webhooks/mod.rs b/crates/delta/src/routes/webhooks/mod.rs index 6b0ef448f..1aec16f40 100644 --- a/crates/delta/src/routes/webhooks/mod.rs +++ b/crates/delta/src/routes/webhooks/mod.rs @@ -1,19 +1,23 @@ -use rocket::Route; use revolt_rocket_okapi::revolt_okapi::openapi3::OpenApi; +use rocket::Route; mod webhook_delete; +mod webhook_delete_message; mod webhook_delete_token; mod webhook_edit; +mod webhook_edit_message; mod webhook_edit_token; mod webhook_execute; -mod webhook_fetch_token; -mod webhook_fetch; mod webhook_execute_github; +mod webhook_fetch; +mod webhook_fetch_token; pub fn routes() -> (Vec, OpenApi) { openapi_get_routes_spec![ + webhook_delete_message::webhook_delete_message, webhook_delete_token::webhook_delete_token, webhook_delete::webhook_delete, + webhook_edit_message::webhook_edit_message, webhook_edit_token::webhook_edit_token, webhook_edit::webhook_edit, webhook_execute_github::webhook_execute_github, diff --git a/crates/delta/src/routes/webhooks/webhook_delete_message.rs b/crates/delta/src/routes/webhooks/webhook_delete_message.rs new file mode 100644 index 000000000..be4cb63b9 --- /dev/null +++ b/crates/delta/src/routes/webhooks/webhook_delete_message.rs @@ -0,0 +1,27 @@ +use revolt_database::{util::reference::Reference, Database}; +use revolt_result::{create_error, Result}; +use rocket::State; +use rocket_empty::EmptyResponse; + +/// # Deletes a webhook message +/// +/// Deletes a message sent by a webhook +#[openapi(tag = "Webhooks")] +#[delete("///")] +pub async fn webhook_delete_message( + db: &State, + webhook_id: Reference<'_>, + token: String, + message_id: Reference<'_>, +) -> Result { + let webhook = webhook_id.as_webhook(db).await?; + webhook.assert_token(&token)?; + + let message = message_id.as_message(db).await?; + + if message.author != webhook.id { + return Err(create_error!(CannotDeleteMessage)); + } + + message.delete(db).await.map(|_| EmptyResponse) +} diff --git a/crates/delta/src/routes/webhooks/webhook_edit_message.rs b/crates/delta/src/routes/webhooks/webhook_edit_message.rs new file mode 100644 index 000000000..a6e4036f3 --- /dev/null +++ b/crates/delta/src/routes/webhooks/webhook_edit_message.rs @@ -0,0 +1,84 @@ +use iso8601_timestamp::Timestamp; +use revolt_config::config; +use revolt_database::{ + tasks::process_embeds::queue, util::reference::Reference, Database, Message, PartialMessage, +}; +use revolt_models::v0::{self, DataEditMessage, Embed}; +use revolt_models::validator::Validate; +use revolt_result::{create_error, Result}; +use rocket::{serde::json::Json, State}; + +/// # Edits a webhook message +/// +/// Edits a message sent by a webhook +#[openapi(tag = "Webhooks")] +#[patch("///", data = "")] +pub async fn webhook_edit_message( + db: &State, + webhook_id: Reference<'_>, + token: String, + message_id: Reference<'_>, + data: Json, +) -> Result> { + let edit = data.into_inner(); + edit.validate().map_err(|error| { + create_error!(FailedValidation { + error: error.to_string() + }) + })?; + + Message::validate_sum( + &edit.content, + edit.embeds.as_deref().unwrap_or_default(), + config().await.features.limits.default.message_length, + )?; + + let webhook = webhook_id.as_webhook(db).await?; + webhook.assert_token(&token)?; + + let mut message = message_id.as_message(db).await?; + if message.author != webhook.id { + return Err(create_error!(CannotEditMessage)); + } + + message.edited = Some(Timestamp::now_utc()); + let mut partial = PartialMessage { + edited: message.edited, + ..Default::default() + }; + + // 1. Handle content update + if let Some(content) = &edit.content { + partial.content = Some(content.clone()); + } + + // 2. Clear any auto generated embeds + let mut new_embeds = vec![]; + if let Some(embeds) = &message.embeds { + for embed in embeds { + if let Embed::Text(embed) = embed { + new_embeds.push(Embed::Text(embed.clone())) + } + } + } + + // 3. Replace if we are given new embeds + if let Some(embeds) = edit.embeds { + new_embeds.clear(); + + for embed in embeds { + new_embeds.push(message.create_embed(db, embed).await?); + } + } + + partial.embeds = Some(new_embeds); + + message.update(db, partial, vec![]).await?; + + // Queue up a task for processing embeds + if let Some(content) = edit.content { + queue(message.channel.to_string(), message.id.to_string(), content).await; + } + + Ok(Json(message.into_model(None, None))) +} From d76a71141f3e508f6308ba52fa28eaeb56fb3438 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0spik?= Date: Sat, 9 May 2026 01:49:31 +0300 Subject: [PATCH 163/211] fix: don't strip ICC from exif (#735) * fix: don't strip ICC from exif Signed-off-by: ispik * fix: refactor ICC profile handling in image processing Signed-off-by: ispik --------- Signed-off-by: ispik --- Cargo.lock | 55 ++++++++++++- Cargo.toml | 1 + crates/services/autumn/Cargo.toml | 1 + crates/services/autumn/src/exif.rs | 110 +++++++++++++++++-------- crates/services/autumn/src/main.rs | 1 + crates/services/autumn/src/metadata.rs | 31 ++++--- crates/services/autumn/src/utils.rs | 31 +++++++ 7 files changed, 184 insertions(+), 46 deletions(-) create mode 100644 crates/services/autumn/src/utils.rs diff --git a/Cargo.lock b/Cargo.lock index 671d6a9dd..b55dab061 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3068,7 +3068,28 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" dependencies = [ - "foreign-types-shared", + "foreign-types-shared 0.1.1", +] + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared 0.3.1", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote 1.0.45", + "syn 2.0.117", ] [[package]] @@ -3077,6 +3098,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + [[package]] name = "form_urlencoded" version = "1.2.2" @@ -4847,6 +4874,29 @@ dependencies = [ "spin 0.9.8", ] +[[package]] +name = "lcms2" +version = "6.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b75877b724685dd49310bdbadbf973fc69b1d01992a6d4a861b928fc3943f87b" +dependencies = [ + "bytemuck", + "foreign-types 0.5.0", + "lcms2-sys", +] + +[[package]] +name = "lcms2-sys" +version = "4.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c2604b23848ca80b2add60f0fb2270fd980e622c25029b6597fa01cfd5f8d5f" +dependencies = [ + "cc", + "dunce", + "libc", + "pkg-config", +] + [[package]] name = "leb128fmt" version = "0.1.0" @@ -5894,7 +5944,7 @@ checksum = "951c002c75e16ea2c65b8c7e4d3d51d5530d8dfa7d060b4776828c88cfb18ecf" dependencies = [ "bitflags 2.11.0", "cfg-if", - "foreign-types", + "foreign-types 0.3.2", "libc", "once_cell", "openssl-macros", @@ -7466,6 +7516,7 @@ dependencies = [ "jxl-oxide", "kamadak-exif", "lazy_static", + "lcms2", "moka", "nanoid", "revolt-config", diff --git a/Cargo.toml b/Cargo.toml index 6ce826ef7..f7a3e83ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -134,6 +134,7 @@ kamadak-exif = "0.5.4" webp = "0.3.0" image = "0.25.2" # avif encode requires dav1d system library: features = ["avif-native"] thumbhash = "0.1.0" +lcms2 = "6.1.1" # for color profile processing # File processing revolt_clamav-client = "0.1.5" diff --git a/crates/services/autumn/Cargo.toml b/crates/services/autumn/Cargo.toml index 1636a8ecb..62b0bbcf0 100644 --- a/crates/services/autumn/Cargo.toml +++ b/crates/services/autumn/Cargo.toml @@ -18,6 +18,7 @@ kamadak-exif = { workspace = true } # revolt_little_exif = "0.5.1" image = { workspace = true } thumbhash = { workspace = true } +lcms2 = { workspace = true } # File processing revolt_clamav-client = { workspace = true } diff --git a/crates/services/autumn/src/exif.rs b/crates/services/autumn/src/exif.rs index af02953e5..be8e61508 100644 --- a/crates/services/autumn/src/exif.rs +++ b/crates/services/autumn/src/exif.rs @@ -1,13 +1,24 @@ use std::io::{Cursor, Read}; +use crate::utils::apply_icc_profile; use exif::Reader; -use image::{ImageFormat, ImageReader}; +use image::{ImageEncoder, ImageReader}; use revolt_config::report_internal_error; use revolt_database::Metadata; use revolt_result::{create_error, Result}; use tempfile::NamedTempFile; use tokio::process::Command; +macro_rules! encode_with_icc { + ($encoder:expr, $icc:expr, $image:expr, $width:expr, $height:expr, $color:expr) => {{ + let mut encoder = $encoder; + if let Some(icc) = $icc { + let _ = encoder.set_icc_profile(icc.clone()); + } + encoder.write_image($image, $width, $height, $color) + }}; +} + /// Strip EXIF data from given file and produce new file and metadata pub async fn strip_metadata( file: NamedTempFile, @@ -17,8 +28,8 @@ pub async fn strip_metadata( ) -> Result<(Vec, Metadata)> { match &metadata { Metadata::Image { - width, - height, + width: _, + height: _, thumbhash, animated, } => match mime { @@ -46,11 +57,12 @@ pub async fn strip_metadata( let mut cursor = Cursor::new(buf); // Decode the image - let image = report_internal_error!(report_internal_error!(ImageReader::new( - &mut cursor - ) - .with_guessed_format())? - .decode()); + let reader = + report_internal_error!(ImageReader::new(&mut cursor).with_guessed_format())?; + let mut decoder = report_internal_error!(reader.into_decoder())?; + let mut icc_profile = + report_internal_error!(image::ImageDecoder::icc_profile(&mut decoder))?; + let mut image = report_internal_error!(image::DynamicImage::from_decoder(decoder))?; // Reset read position cursor.set_position(0); @@ -71,38 +83,68 @@ pub async fn strip_metadata( // Apply the EXIF rotation // See https://jdhao.github.io/2019/07/31/image_rotation_exif_info/ - report_internal_error!(match &rotation { - 2 => image?.fliph(), - 3 => image?.rotate180(), - 4 => image?.rotate180().fliph(), - 5 => image?.rotate90().fliph(), - 6 => image?.rotate90(), - 7 => image?.rotate270().fliph(), - 8 => image?.rotate270(), - _ => image?, + image = match &rotation { + 2 => image.fliph(), + 3 => image.rotate180(), + 4 => image.rotate180().fliph(), + 5 => image.rotate90().fliph(), + 6 => image.rotate90(), + 7 => image.rotate270().fliph(), + 8 => image.rotate270(), + _ => image, + }; + + if let Some(icc) = &icc_profile { + image = apply_icc_profile(image, icc); + icc_profile = None; } - .write_to( - &mut writer, - match mime { - "image/jpeg" => ImageFormat::Jpeg, - "image/png" => ImageFormat::Png, - "image/avif" => ImageFormat::Avif, - "image/tiff" => ImageFormat::Tiff, - _ => todo!(), - }, - ))?; - // Calculate dimensions after rotation. - let (width, height) = match &rotation { - 2 | 4 | 5 | 7 => (*height, *width), - _ => (*width, *height), - }; + let color_type = image.color(); + let width = image.width(); + let height = image.height(); + + report_internal_error!(match mime { + "image/jpeg" => encode_with_icc!( + image::codecs::jpeg::JpegEncoder::new(&mut writer), + &icc_profile, + image.as_bytes(), + width, + height, + color_type.into() + ), + "image/png" => encode_with_icc!( + image::codecs::png::PngEncoder::new(&mut writer), + &icc_profile, + image.as_bytes(), + width, + height, + color_type.into() + ), + "image/avif" => { + // avif encoder doesn't implement set_icc_profile currently + image::codecs::avif::AvifEncoder::new(&mut writer).write_image( + image.as_bytes(), + width, + height, + color_type.into(), + ) + } + "image/tiff" => encode_with_icc!( + image::codecs::tiff::TiffEncoder::new(&mut writer), + &icc_profile, + image.as_bytes(), + width, + height, + color_type.into() + ), + _ => unreachable!(), + })?; Ok(( bytes, Metadata::Image { - width, - height, + width: width as isize, + height: height as isize, thumbhash: thumbhash.clone(), animated: *animated, }, diff --git a/crates/services/autumn/src/main.rs b/crates/services/autumn/src/main.rs index cb936e0cd..e62343186 100644 --- a/crates/services/autumn/src/main.rs +++ b/crates/services/autumn/src/main.rs @@ -18,6 +18,7 @@ pub mod exif; pub mod metadata; pub mod mime_type; mod ratelimits; +mod utils; #[derive(FromRef, Clone)] struct AppState { diff --git a/crates/services/autumn/src/metadata.rs b/crates/services/autumn/src/metadata.rs index 8e0c89cd9..c476eac46 100644 --- a/crates/services/autumn/src/metadata.rs +++ b/crates/services/autumn/src/metadata.rs @@ -1,5 +1,6 @@ use std::io::Cursor; +use crate::utils::apply_icc_profile; use image::{GenericImageView, ImageError, ImageReader}; use revolt_database::Metadata; use revolt_files::{image_size, is_animated, video_size}; @@ -27,16 +28,26 @@ pub fn generate_metadata(f: &NamedTempFile, mime_type: &str) -> Metadata { .map(|(width, height)| Metadata::Image { width: width as isize, height: height as isize, - thumbhash: ImageReader::open(f) - .and_then(|r| r.with_guessed_format()) - .map_err(ImageError::from) - .and_then(|r| r.decode()) - .map(|img| img.thumbnail(100, 100)) - .map(|img| (img.dimensions(), img.to_rgba8().into_raw())) - .map(|((width, height), rgba)| { - thumbhash::rgba_to_thumb_hash(width as usize, height as usize, &rgba) - }) - .ok(), + thumbhash: (|| { + let reader = ImageReader::open(f).ok()?.with_guessed_format().ok()?; + let mut decoder = reader.into_decoder().ok()?; + let icc_profile = image::ImageDecoder::icc_profile(&mut decoder) + .ok() + .flatten(); + let mut img = image::DynamicImage::from_decoder(decoder).ok()?; + + if let Some(icc) = icc_profile { + img = apply_icc_profile(img, &icc); + } + + let img = img.thumbnail(100, 100); + let (width, height) = img.dimensions(); + Some(thumbhash::rgba_to_thumb_hash( + width as usize, + height as usize, + &img.into_rgba8().into_raw(), + )) + })(), animated: is_animated(f, mime_type).or(Some(false)), }) .unwrap_or_default() diff --git a/crates/services/autumn/src/utils.rs b/crates/services/autumn/src/utils.rs new file mode 100644 index 000000000..5e2fbfb8b --- /dev/null +++ b/crates/services/autumn/src/utils.rs @@ -0,0 +1,31 @@ +/// Convert image to sRGB using the provided ICC profile. +/// Returns the converted image, or the original if conversion fails. +pub fn apply_icc_profile(image: image::DynamicImage, icc: &[u8]) -> image::DynamicImage { + let Ok(src_profile) = lcms2::Profile::new_icc(icc) else { + return image; + }; + let dst_profile = lcms2::Profile::new_srgb(); + let format = if image.color().has_alpha() { + lcms2::PixelFormat::RGBA_8 + } else { + lcms2::PixelFormat::RGB_8 + }; + let Ok(t) = lcms2::Transform::new( + &src_profile, + format, + &dst_profile, + format, + lcms2::Intent::Perceptual, + ) else { + return image; + }; + if image.color().has_alpha() { + let mut rgba_image = image.into_rgba8(); + t.transform_in_place(rgba_image.as_mut()); + image::DynamicImage::ImageRgba8(rgba_image) + } else { + let mut rgb_image = image.into_rgb8(); + t.transform_in_place(rgb_image.as_mut()); + image::DynamicImage::ImageRgb8(rgb_image) + } +} From d52e84c5d3afec0d7d843ef03b7cb807a54f98a8 Mon Sep 17 00:00:00 2001 From: "stoat-release[bot]" <245062572+stoat-release[bot]@users.noreply.github.com> Date: Sat, 9 May 2026 17:26:38 +0100 Subject: [PATCH 164/211] chore(main): release 0.13.0 (#722) Co-authored-by: stoat-release[bot] <245062572+stoat-release[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] --- .release-please-manifest.json | 2 +- CHANGELOG.md | 27 +++++++++++++++++++ Cargo.lock | 36 ++++++++++++------------- Cargo.toml | 20 +++++++------- crates/bonfire/Cargo.toml | 2 +- crates/core/coalesced/Cargo.toml | 2 +- crates/core/config/Cargo.toml | 2 +- crates/core/database/Cargo.toml | 2 +- crates/core/files/Cargo.toml | 2 +- crates/core/models/Cargo.toml | 2 +- crates/core/parser/Cargo.toml | 2 +- crates/core/permissions/Cargo.toml | 2 +- crates/core/presence/Cargo.toml | 2 +- crates/core/ratelimits/Cargo.toml | 2 +- crates/core/result/Cargo.toml | 2 +- crates/daemons/crond/Cargo.toml | 2 +- crates/daemons/pushd/Cargo.toml | 2 +- crates/daemons/voice-ingress/Cargo.toml | 2 +- crates/delta/Cargo.toml | 2 +- crates/services/autumn/Cargo.toml | 2 +- crates/services/gifbox/Cargo.toml | 2 +- crates/services/january/Cargo.toml | 2 +- version.txt | 2 +- 23 files changed, 75 insertions(+), 48 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 8950f7120..04733b0e8 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.12.1" + ".": "0.13.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index cc7f73283..bfb6b326c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,32 @@ # Changelog +## [0.13.0](https://github.com/stoatchat/stoatchat/compare/v0.12.1...v0.13.0) (2026-05-08) + + +### Features + +* add embed support for YouTube Shorts ([#734](https://github.com/stoatchat/stoatchat/issues/734)) ([d46c7f7](https://github.com/stoatchat/stoatchat/commit/d46c7f7f3c04524c0639c3e0a122626f8e0b3bf7)) +* add emoji rename endpoint ([#714](https://github.com/stoatchat/stoatchat/issues/714)) ([23ad135](https://github.com/stoatchat/stoatchat/commit/23ad1359834bb7d07a460b8678d6a6ebffc73eb0)) +* add legal links to root payload ([#733](https://github.com/stoatchat/stoatchat/issues/733)) ([21d8201](https://github.com/stoatchat/stoatchat/commit/21d82018cf84ab0fdd10613d254b9562aea8eea3)) +* add role icon support ([#724](https://github.com/stoatchat/stoatchat/issues/724)) ([841985d](https://github.com/stoatchat/stoatchat/commit/841985d3b994df1c6eefab2fc7ecbd77ab22c493)) +* Add webhook endpoints for editing and deleting messages ([#682](https://github.com/stoatchat/stoatchat/issues/682)) ([6f3441c](https://github.com/stoatchat/stoatchat/commit/6f3441cf4acac2a8e6e1bf07a279a153b80f7956)) +* automatically sanitise usernames on create/update ([#689](https://github.com/stoatchat/stoatchat/issues/689)) ([e937697](https://github.com/stoatchat/stoatchat/commit/e93769786c7669485a659ee471630740d3cea702)) +* blacklist private ip ranges and add january domain blocklist ([#731](https://github.com/stoatchat/stoatchat/issues/731)) ([6b41db9](https://github.com/stoatchat/stoatchat/commit/6b41db984bb491b2e58324309cc70d8c14e0b814)) +* Rewrite acks ([#741](https://github.com/stoatchat/stoatchat/issues/741)) ([ab5bd47](https://github.com/stoatchat/stoatchat/commit/ab5bd47a39ee889de0b5ae6e7b560620853daead)) + + +### Bug Fixes + +* add new_user_hours to configuration limits ([#729](https://github.com/stoatchat/stoatchat/issues/729)) ([279f5d5](https://github.com/stoatchat/stoatchat/commit/279f5d5fd7af2df55902c706859ec07f569cdb1e)) +* add reconnection policy to Redis subscriber to prevent ghost state ([#708](https://github.com/stoatchat/stoatchat/issues/708)) ([057f2bb](https://github.com/stoatchat/stoatchat/commit/057f2bb8b359f8b942741a30ff54eeb8fbe3e0b1)) +* docker compose file had personal url in it ([#742](https://github.com/stoatchat/stoatchat/issues/742)) ([0719985](https://github.com/stoatchat/stoatchat/commit/0719985ac5636590f91e6f9ec4b68f3eded70c13)) +* don't strip ICC from exif ([#735](https://github.com/stoatchat/stoatchat/issues/735)) ([d76a711](https://github.com/stoatchat/stoatchat/commit/d76a71141f3e508f6308ba52fa28eaeb56fb3438)) +* dont send notification in fcm ([#721](https://github.com/stoatchat/stoatchat/issues/721)) ([89171e9](https://github.com/stoatchat/stoatchat/commit/89171e9bd0f15711157e78c6eec0fe7b480de93a)) +* encode filenames in redirects ([#737](https://github.com/stoatchat/stoatchat/issues/737)) ([9fd7128](https://github.com/stoatchat/stoatchat/commit/9fd7128f800badbd184baf943d4f799e601201e4)) +* january ip redirects & domain resolver ([#738](https://github.com/stoatchat/stoatchat/issues/738)) ([356491e](https://github.com/stoatchat/stoatchat/commit/356491e934b274f9e895df883dd63ef0b3123510)) +* update message length validation to remove upper limit ([#723](https://github.com/stoatchat/stoatchat/issues/723)) ([ed4fd5e](https://github.com/stoatchat/stoatchat/commit/ed4fd5ebfe6d0ea534a0898da4afdc1f4e2cd6c5)) +* use correct response for NoEffect errors ([#732](https://github.com/stoatchat/stoatchat/issues/732)) ([5378cd2](https://github.com/stoatchat/stoatchat/commit/5378cd22b4c7d85f44c31a6af0dda00941b80d5c)) + ## [0.12.1](https://github.com/stoatchat/stoatchat/compare/v0.12.0...v0.12.1) (2026-04-10) diff --git a/Cargo.lock b/Cargo.lock index b55dab061..ecc716a16 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7504,7 +7504,7 @@ dependencies = [ [[package]] name = "revolt-autumn" -version = "0.12.1" +version = "0.13.0" dependencies = [ "axum", "axum-macros", @@ -7545,7 +7545,7 @@ dependencies = [ [[package]] name = "revolt-bonfire" -version = "0.12.1" +version = "0.13.0" dependencies = [ "async-channel 2.5.0", "async-std", @@ -7576,7 +7576,7 @@ dependencies = [ [[package]] name = "revolt-coalesced" -version = "0.12.1" +version = "0.13.0" dependencies = [ "indexmap 2.13.1", "lru", @@ -7585,7 +7585,7 @@ dependencies = [ [[package]] name = "revolt-config" -version = "0.12.1" +version = "0.13.0" dependencies = [ "async-std", "cached", @@ -7602,7 +7602,7 @@ dependencies = [ [[package]] name = "revolt-crond" -version = "0.12.1" +version = "0.13.0" dependencies = [ "futures-lite", "iso8601-timestamp", @@ -7622,7 +7622,7 @@ dependencies = [ [[package]] name = "revolt-database" -version = "0.12.1" +version = "0.13.0" dependencies = [ "amqprs", "async-lock 2.8.0", @@ -7673,7 +7673,7 @@ dependencies = [ [[package]] name = "revolt-delta" -version = "0.12.1" +version = "0.13.0" dependencies = [ "amqprs", "async-channel 2.5.0", @@ -7722,7 +7722,7 @@ dependencies = [ [[package]] name = "revolt-files" -version = "0.12.1" +version = "0.13.0" dependencies = [ "aes-gcm", "anyhow", @@ -7750,7 +7750,7 @@ dependencies = [ [[package]] name = "revolt-gifbox" -version = "0.12.1" +version = "0.13.0" dependencies = [ "axum", "axum-extra", @@ -7773,7 +7773,7 @@ dependencies = [ [[package]] name = "revolt-january" -version = "0.12.1" +version = "0.13.0" dependencies = [ "async-recursion", "axum", @@ -7803,7 +7803,7 @@ dependencies = [ [[package]] name = "revolt-models" -version = "0.12.1" +version = "0.13.0" dependencies = [ "indexmap 2.13.1", "iso8601-timestamp", @@ -7822,14 +7822,14 @@ dependencies = [ [[package]] name = "revolt-parser" -version = "0.12.1" +version = "0.13.0" dependencies = [ "logos", ] [[package]] name = "revolt-permissions" -version = "0.12.1" +version = "0.13.0" dependencies = [ "async-std", "async-trait", @@ -7844,7 +7844,7 @@ dependencies = [ [[package]] name = "revolt-presence" -version = "0.12.1" +version = "0.13.0" dependencies = [ "async-std", "log", @@ -7856,7 +7856,7 @@ dependencies = [ [[package]] name = "revolt-pushd" -version = "0.12.1" +version = "0.13.0" dependencies = [ "amqprs", "anyhow", @@ -7887,7 +7887,7 @@ dependencies = [ [[package]] name = "revolt-ratelimits" -version = "0.12.1" +version = "0.13.0" dependencies = [ "async-trait", "authifier", @@ -7904,7 +7904,7 @@ dependencies = [ [[package]] name = "revolt-result" -version = "0.12.1" +version = "0.13.0" dependencies = [ "axum", "log", @@ -7920,7 +7920,7 @@ dependencies = [ [[package]] name = "revolt-voice-ingress" -version = "0.12.1" +version = "0.13.0" dependencies = [ "amqprs", "async-std", diff --git a/Cargo.toml b/Cargo.toml index f7a3e83ad..f49dd3f15 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -192,13 +192,13 @@ futures-lite = "2.6.1" vergen = "7.5.0" # Local packages -revolt-coalesced = { version = "0.12.0", path = "crates/core/coalesced" } -revolt-config = { version = "0.12.0", path = "crates/core/config" } -revolt-database = { version = "0.12.0", path = "crates/core/database" } -revolt-files = { version = "0.12.0", path = "crates/core/files" } -revolt-models = { version = "0.12.0", path = "crates/core/models" } -revolt-parser = { version = "0.12.0", path = "crates/core/parser" } -revolt-permissions = { version = "0.12.0", path = "crates/core/permissions" } -revolt-presence = { version = "0.12.0", path = "crates/core/presence" } -revolt-ratelimits = { version = "0.12.0", path = "crates/core/ratelimits" } -revolt-result = { version = "0.12.0", path = "crates/core/result" } +revolt-coalesced = { version = "0.13.0", path = "crates/core/coalesced" } +revolt-config = { version = "0.13.0", path = "crates/core/config" } +revolt-database = { version = "0.13.0", path = "crates/core/database" } +revolt-files = { version = "0.13.0", path = "crates/core/files" } +revolt-models = { version = "0.13.0", path = "crates/core/models" } +revolt-parser = { version = "0.13.0", path = "crates/core/parser" } +revolt-permissions = { version = "0.13.0", path = "crates/core/permissions" } +revolt-presence = { version = "0.13.0", path = "crates/core/presence" } +revolt-ratelimits = { version = "0.13.0", path = "crates/core/ratelimits" } +revolt-result = { version = "0.13.0", path = "crates/core/result" } diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index 1e1cc8cab..401c2fa0b 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-bonfire" -version = "0.12.1" +version = "0.13.0" license = "AGPL-3.0-or-later" edition = "2021" publish = false diff --git a/crates/core/coalesced/Cargo.toml b/crates/core/coalesced/Cargo.toml index e6277bd0a..17f7839f6 100644 --- a/crates/core/coalesced/Cargo.toml +++ b/crates/core/coalesced/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-coalesced" -version = "0.12.1" +version = "0.13.0" edition = "2021" license = "MIT" authors = ["Paul Makles ", "Zomatree "] diff --git a/crates/core/config/Cargo.toml b/crates/core/config/Cargo.toml index 7b33b5e9a..f4f70e586 100644 --- a/crates/core/config/Cargo.toml +++ b/crates/core/config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-config" -version = "0.12.1" +version = "0.13.0" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index be3119c56..c42c8e8f9 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-database" -version = "0.12.1" +version = "0.13.0" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] diff --git a/crates/core/files/Cargo.toml b/crates/core/files/Cargo.toml index 9f30649d4..416d57d97 100644 --- a/crates/core/files/Cargo.toml +++ b/crates/core/files/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-files" -version = "0.12.1" +version = "0.13.0" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] diff --git a/crates/core/models/Cargo.toml b/crates/core/models/Cargo.toml index f8a4c6979..41d08d78b 100644 --- a/crates/core/models/Cargo.toml +++ b/crates/core/models/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-models" -version = "0.12.1" +version = "0.13.0" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/core/parser/Cargo.toml b/crates/core/parser/Cargo.toml index 1bc35301c..79f65d700 100644 --- a/crates/core/parser/Cargo.toml +++ b/crates/core/parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-parser" -version = "0.12.1" +version = "0.13.0" edition = "2021" license = "MIT" authors = ["Zomatree ", "Paul Makles "] diff --git a/crates/core/permissions/Cargo.toml b/crates/core/permissions/Cargo.toml index 838b10b29..0fb22d944 100644 --- a/crates/core/permissions/Cargo.toml +++ b/crates/core/permissions/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-permissions" -version = "0.12.1" +version = "0.13.0" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/core/presence/Cargo.toml b/crates/core/presence/Cargo.toml index 547dcd798..e2cfe001b 100644 --- a/crates/core/presence/Cargo.toml +++ b/crates/core/presence/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-presence" -version = "0.12.1" +version = "0.13.0" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] diff --git a/crates/core/ratelimits/Cargo.toml b/crates/core/ratelimits/Cargo.toml index 0e862c808..3e9bb620c 100644 --- a/crates/core/ratelimits/Cargo.toml +++ b/crates/core/ratelimits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-ratelimits" -version = "0.12.1" +version = "0.13.0" edition = "2024" license = "MIT" authors = ["Zomatree ", "Paul Makles "] diff --git a/crates/core/result/Cargo.toml b/crates/core/result/Cargo.toml index 9a1d1c134..461659dcd 100644 --- a/crates/core/result/Cargo.toml +++ b/crates/core/result/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-result" -version = "0.12.1" +version = "0.13.0" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/daemons/crond/Cargo.toml b/crates/daemons/crond/Cargo.toml index 6bd900526..9a7319ab9 100644 --- a/crates/daemons/crond/Cargo.toml +++ b/crates/daemons/crond/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-crond" -version = "0.12.1" +version = "0.13.0" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2021" diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index b26c80e10..28aa7fd8b 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-pushd" -version = "0.12.1" +version = "0.13.0" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/crates/daemons/voice-ingress/Cargo.toml b/crates/daemons/voice-ingress/Cargo.toml index b8d15250b..054698dfb 100644 --- a/crates/daemons/voice-ingress/Cargo.toml +++ b/crates/daemons/voice-ingress/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-voice-ingress" -version = "0.12.1" +version = "0.13.0" license = "AGPL-3.0-or-later" edition = "2021" publish = false diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index 2919ff566..9f8a931c5 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-delta" -version = "0.12.1" +version = "0.13.0" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2018" diff --git a/crates/services/autumn/Cargo.toml b/crates/services/autumn/Cargo.toml index 62b0bbcf0..1f24bb4b6 100644 --- a/crates/services/autumn/Cargo.toml +++ b/crates/services/autumn/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-autumn" -version = "0.12.1" +version = "0.13.0" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/crates/services/gifbox/Cargo.toml b/crates/services/gifbox/Cargo.toml index 6e7b467ca..b9edcf1ba 100644 --- a/crates/services/gifbox/Cargo.toml +++ b/crates/services/gifbox/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-gifbox" -version = "0.12.1" +version = "0.13.0" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/crates/services/january/Cargo.toml b/crates/services/january/Cargo.toml index 7059cca05..f40d128e2 100644 --- a/crates/services/january/Cargo.toml +++ b/crates/services/january/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-january" -version = "0.12.1" +version = "0.13.0" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/version.txt b/version.txt index 34a83616b..54d1a4f2a 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.12.1 +0.13.0 From 1100eaf46f849f2509ae01ac497556ca33bde778 Mon Sep 17 00:00:00 2001 From: Tom Date: Sun, 10 May 2026 07:22:26 -0700 Subject: [PATCH 165/211] fix: amqprs startup bug (#744) --- crates/core/database/src/amqp/amqp.rs | 27 ++++++++++++++++----------- crates/delta/src/main.rs | 2 +- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/crates/core/database/src/amqp/amqp.rs b/crates/core/database/src/amqp/amqp.rs index 5358bc344..163260454 100644 --- a/crates/core/database/src/amqp/amqp.rs +++ b/crates/core/database/src/amqp/amqp.rs @@ -29,7 +29,7 @@ impl AMQP { } } - pub async fn new_auto() -> AMQP { + pub async fn new_auto() -> revolt_result::Result { let config = revolt_config::config().await; let connection = Connection::open(&OpenConnectionArguments::new( @@ -46,21 +46,26 @@ impl AMQP { .await .expect("Failed to open RabbitMQ channel"); - channel - .exchange_declare( - ExchangeDeclareArguments::new(&config.pushd.exchange, "direct") - .durable(true) - .finish(), - ) - .await - .expect("Failed to declare exchange"); + let mut resp = AMQP::new(connection, channel); + resp.configure_channels().await?; + Ok(resp) + } - AMQP::new(connection, channel) + pub async fn repoen_channel(&mut self) { + self.channel = self + .connection + .open_channel(None) + .await + .expect("Failed to open RabbitMQ channel"); } - pub async fn configure_channels(&self) -> revolt_result::Result<()> { + pub async fn configure_channels(&mut self) -> revolt_result::Result<()> { let config = revolt_config::config().await; + if !self.channel.is_open() { + self.repoen_channel().await; + } + self.channel .exchange_declare( ExchangeDeclareArguments::new( diff --git a/crates/delta/src/main.rs b/crates/delta/src/main.rs index e3522de1d..e3cf43a4c 100644 --- a/crates/delta/src/main.rs +++ b/crates/delta/src/main.rs @@ -119,7 +119,7 @@ pub async fn web() -> Rocket { .await .expect("Failed to declare exchange"); - let amqp = AMQP::new(connection, channel); + let mut amqp = AMQP::new(connection, channel); amqp.configure_channels() .await .expect("Failed to configure channels"); From 260036488d85807c74e0ed47ba4dd93d41b65349 Mon Sep 17 00:00:00 2001 From: "stoat-release[bot]" <245062572+stoat-release[bot]@users.noreply.github.com> Date: Sun, 10 May 2026 15:34:41 +0100 Subject: [PATCH 166/211] chore(main): release 0.13.1 (#745) Co-authored-by: stoat-release[bot] <245062572+stoat-release[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] --- .release-please-manifest.json | 2 +- CHANGELOG.md | 7 +++++ Cargo.lock | 36 ++++++++++++------------- Cargo.toml | 20 +++++++------- crates/bonfire/Cargo.toml | 2 +- crates/core/coalesced/Cargo.toml | 2 +- crates/core/config/Cargo.toml | 2 +- crates/core/database/Cargo.toml | 2 +- crates/core/files/Cargo.toml | 2 +- crates/core/models/Cargo.toml | 2 +- crates/core/parser/Cargo.toml | 2 +- crates/core/permissions/Cargo.toml | 2 +- crates/core/presence/Cargo.toml | 2 +- crates/core/ratelimits/Cargo.toml | 2 +- crates/core/result/Cargo.toml | 2 +- crates/daemons/crond/Cargo.toml | 2 +- crates/daemons/pushd/Cargo.toml | 2 +- crates/daemons/voice-ingress/Cargo.toml | 2 +- crates/delta/Cargo.toml | 2 +- crates/services/autumn/Cargo.toml | 2 +- crates/services/gifbox/Cargo.toml | 2 +- crates/services/january/Cargo.toml | 2 +- version.txt | 2 +- 23 files changed, 55 insertions(+), 48 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 04733b0e8..7f0526224 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.13.0" + ".": "0.13.1" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index bfb6b326c..31c46f2e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [0.13.1](https://github.com/stoatchat/stoatchat/compare/v0.13.0...v0.13.1) (2026-05-10) + + +### Bug Fixes + +* amqprs startup bug ([#744](https://github.com/stoatchat/stoatchat/issues/744)) ([1100eaf](https://github.com/stoatchat/stoatchat/commit/1100eaf46f849f2509ae01ac497556ca33bde778)) + ## [0.13.0](https://github.com/stoatchat/stoatchat/compare/v0.12.1...v0.13.0) (2026-05-08) diff --git a/Cargo.lock b/Cargo.lock index ecc716a16..8eeb17c5d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7504,7 +7504,7 @@ dependencies = [ [[package]] name = "revolt-autumn" -version = "0.13.0" +version = "0.13.1" dependencies = [ "axum", "axum-macros", @@ -7545,7 +7545,7 @@ dependencies = [ [[package]] name = "revolt-bonfire" -version = "0.13.0" +version = "0.13.1" dependencies = [ "async-channel 2.5.0", "async-std", @@ -7576,7 +7576,7 @@ dependencies = [ [[package]] name = "revolt-coalesced" -version = "0.13.0" +version = "0.13.1" dependencies = [ "indexmap 2.13.1", "lru", @@ -7585,7 +7585,7 @@ dependencies = [ [[package]] name = "revolt-config" -version = "0.13.0" +version = "0.13.1" dependencies = [ "async-std", "cached", @@ -7602,7 +7602,7 @@ dependencies = [ [[package]] name = "revolt-crond" -version = "0.13.0" +version = "0.13.1" dependencies = [ "futures-lite", "iso8601-timestamp", @@ -7622,7 +7622,7 @@ dependencies = [ [[package]] name = "revolt-database" -version = "0.13.0" +version = "0.13.1" dependencies = [ "amqprs", "async-lock 2.8.0", @@ -7673,7 +7673,7 @@ dependencies = [ [[package]] name = "revolt-delta" -version = "0.13.0" +version = "0.13.1" dependencies = [ "amqprs", "async-channel 2.5.0", @@ -7722,7 +7722,7 @@ dependencies = [ [[package]] name = "revolt-files" -version = "0.13.0" +version = "0.13.1" dependencies = [ "aes-gcm", "anyhow", @@ -7750,7 +7750,7 @@ dependencies = [ [[package]] name = "revolt-gifbox" -version = "0.13.0" +version = "0.13.1" dependencies = [ "axum", "axum-extra", @@ -7773,7 +7773,7 @@ dependencies = [ [[package]] name = "revolt-january" -version = "0.13.0" +version = "0.13.1" dependencies = [ "async-recursion", "axum", @@ -7803,7 +7803,7 @@ dependencies = [ [[package]] name = "revolt-models" -version = "0.13.0" +version = "0.13.1" dependencies = [ "indexmap 2.13.1", "iso8601-timestamp", @@ -7822,14 +7822,14 @@ dependencies = [ [[package]] name = "revolt-parser" -version = "0.13.0" +version = "0.13.1" dependencies = [ "logos", ] [[package]] name = "revolt-permissions" -version = "0.13.0" +version = "0.13.1" dependencies = [ "async-std", "async-trait", @@ -7844,7 +7844,7 @@ dependencies = [ [[package]] name = "revolt-presence" -version = "0.13.0" +version = "0.13.1" dependencies = [ "async-std", "log", @@ -7856,7 +7856,7 @@ dependencies = [ [[package]] name = "revolt-pushd" -version = "0.13.0" +version = "0.13.1" dependencies = [ "amqprs", "anyhow", @@ -7887,7 +7887,7 @@ dependencies = [ [[package]] name = "revolt-ratelimits" -version = "0.13.0" +version = "0.13.1" dependencies = [ "async-trait", "authifier", @@ -7904,7 +7904,7 @@ dependencies = [ [[package]] name = "revolt-result" -version = "0.13.0" +version = "0.13.1" dependencies = [ "axum", "log", @@ -7920,7 +7920,7 @@ dependencies = [ [[package]] name = "revolt-voice-ingress" -version = "0.13.0" +version = "0.13.1" dependencies = [ "amqprs", "async-std", diff --git a/Cargo.toml b/Cargo.toml index f49dd3f15..3ee8db8f2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -192,13 +192,13 @@ futures-lite = "2.6.1" vergen = "7.5.0" # Local packages -revolt-coalesced = { version = "0.13.0", path = "crates/core/coalesced" } -revolt-config = { version = "0.13.0", path = "crates/core/config" } -revolt-database = { version = "0.13.0", path = "crates/core/database" } -revolt-files = { version = "0.13.0", path = "crates/core/files" } -revolt-models = { version = "0.13.0", path = "crates/core/models" } -revolt-parser = { version = "0.13.0", path = "crates/core/parser" } -revolt-permissions = { version = "0.13.0", path = "crates/core/permissions" } -revolt-presence = { version = "0.13.0", path = "crates/core/presence" } -revolt-ratelimits = { version = "0.13.0", path = "crates/core/ratelimits" } -revolt-result = { version = "0.13.0", path = "crates/core/result" } +revolt-coalesced = { version = "0.13.1", path = "crates/core/coalesced" } +revolt-config = { version = "0.13.1", path = "crates/core/config" } +revolt-database = { version = "0.13.1", path = "crates/core/database" } +revolt-files = { version = "0.13.1", path = "crates/core/files" } +revolt-models = { version = "0.13.1", path = "crates/core/models" } +revolt-parser = { version = "0.13.1", path = "crates/core/parser" } +revolt-permissions = { version = "0.13.1", path = "crates/core/permissions" } +revolt-presence = { version = "0.13.1", path = "crates/core/presence" } +revolt-ratelimits = { version = "0.13.1", path = "crates/core/ratelimits" } +revolt-result = { version = "0.13.1", path = "crates/core/result" } diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index 401c2fa0b..9018e9655 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-bonfire" -version = "0.13.0" +version = "0.13.1" license = "AGPL-3.0-or-later" edition = "2021" publish = false diff --git a/crates/core/coalesced/Cargo.toml b/crates/core/coalesced/Cargo.toml index 17f7839f6..589afa704 100644 --- a/crates/core/coalesced/Cargo.toml +++ b/crates/core/coalesced/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-coalesced" -version = "0.13.0" +version = "0.13.1" edition = "2021" license = "MIT" authors = ["Paul Makles ", "Zomatree "] diff --git a/crates/core/config/Cargo.toml b/crates/core/config/Cargo.toml index f4f70e586..48921d77a 100644 --- a/crates/core/config/Cargo.toml +++ b/crates/core/config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-config" -version = "0.13.0" +version = "0.13.1" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index c42c8e8f9..dd60ccd7d 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-database" -version = "0.13.0" +version = "0.13.1" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] diff --git a/crates/core/files/Cargo.toml b/crates/core/files/Cargo.toml index 416d57d97..6910f6c13 100644 --- a/crates/core/files/Cargo.toml +++ b/crates/core/files/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-files" -version = "0.13.0" +version = "0.13.1" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] diff --git a/crates/core/models/Cargo.toml b/crates/core/models/Cargo.toml index 41d08d78b..696107e86 100644 --- a/crates/core/models/Cargo.toml +++ b/crates/core/models/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-models" -version = "0.13.0" +version = "0.13.1" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/core/parser/Cargo.toml b/crates/core/parser/Cargo.toml index 79f65d700..8bd9cf03d 100644 --- a/crates/core/parser/Cargo.toml +++ b/crates/core/parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-parser" -version = "0.13.0" +version = "0.13.1" edition = "2021" license = "MIT" authors = ["Zomatree ", "Paul Makles "] diff --git a/crates/core/permissions/Cargo.toml b/crates/core/permissions/Cargo.toml index 0fb22d944..675b569b5 100644 --- a/crates/core/permissions/Cargo.toml +++ b/crates/core/permissions/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-permissions" -version = "0.13.0" +version = "0.13.1" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/core/presence/Cargo.toml b/crates/core/presence/Cargo.toml index e2cfe001b..86043d644 100644 --- a/crates/core/presence/Cargo.toml +++ b/crates/core/presence/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-presence" -version = "0.13.0" +version = "0.13.1" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] diff --git a/crates/core/ratelimits/Cargo.toml b/crates/core/ratelimits/Cargo.toml index 3e9bb620c..c917269d7 100644 --- a/crates/core/ratelimits/Cargo.toml +++ b/crates/core/ratelimits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-ratelimits" -version = "0.13.0" +version = "0.13.1" edition = "2024" license = "MIT" authors = ["Zomatree ", "Paul Makles "] diff --git a/crates/core/result/Cargo.toml b/crates/core/result/Cargo.toml index 461659dcd..12e358f11 100644 --- a/crates/core/result/Cargo.toml +++ b/crates/core/result/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-result" -version = "0.13.0" +version = "0.13.1" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/daemons/crond/Cargo.toml b/crates/daemons/crond/Cargo.toml index 9a7319ab9..f9b09ef14 100644 --- a/crates/daemons/crond/Cargo.toml +++ b/crates/daemons/crond/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-crond" -version = "0.13.0" +version = "0.13.1" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2021" diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index 28aa7fd8b..2f1ba2f75 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-pushd" -version = "0.13.0" +version = "0.13.1" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/crates/daemons/voice-ingress/Cargo.toml b/crates/daemons/voice-ingress/Cargo.toml index 054698dfb..ebd90a586 100644 --- a/crates/daemons/voice-ingress/Cargo.toml +++ b/crates/daemons/voice-ingress/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-voice-ingress" -version = "0.13.0" +version = "0.13.1" license = "AGPL-3.0-or-later" edition = "2021" publish = false diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index 9f8a931c5..ef007daea 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-delta" -version = "0.13.0" +version = "0.13.1" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2018" diff --git a/crates/services/autumn/Cargo.toml b/crates/services/autumn/Cargo.toml index 1f24bb4b6..549ecdcd9 100644 --- a/crates/services/autumn/Cargo.toml +++ b/crates/services/autumn/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-autumn" -version = "0.13.0" +version = "0.13.1" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/crates/services/gifbox/Cargo.toml b/crates/services/gifbox/Cargo.toml index b9edcf1ba..355952cfa 100644 --- a/crates/services/gifbox/Cargo.toml +++ b/crates/services/gifbox/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-gifbox" -version = "0.13.0" +version = "0.13.1" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/crates/services/january/Cargo.toml b/crates/services/january/Cargo.toml index f40d128e2..76d8e5c3f 100644 --- a/crates/services/january/Cargo.toml +++ b/crates/services/january/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-january" -version = "0.13.0" +version = "0.13.1" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/version.txt b/version.txt index 54d1a4f2a..c317a9189 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.13.0 +0.13.1 From fcb8091cd7a00d7f26c798daa33aae4b923b2a8b Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Mon, 11 May 2026 15:21:34 +0100 Subject: [PATCH 167/211] fix: update default exchange to `revolt.default` (#746) Signed-off-by: Paul Makles --- crates/core/config/Revolt.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/core/config/Revolt.toml b/crates/core/config/Revolt.toml index ad2d69924..e598a3dc8 100644 --- a/crates/core/config/Revolt.toml +++ b/crates/core/config/Revolt.toml @@ -30,7 +30,7 @@ host = "rabbit" port = 5672 username = "rabbituser" password = "rabbitpass" -default_exchange = "revolt" +default_exchange = "revolt.default" [rabbit.queues] acks = "internal.ack" From 8157e1f6e9ddc0e0290f06b9aa625d639397b69e Mon Sep 17 00:00:00 2001 From: "stoat-release[bot]" <245062572+stoat-release[bot]@users.noreply.github.com> Date: Mon, 11 May 2026 15:26:03 +0100 Subject: [PATCH 168/211] chore(main): release 0.13.2 (#747) * chore(main): release 0.13.2 * chore: update Cargo.lock Signed-off-by: github-actions[bot] --------- Signed-off-by: github-actions[bot] Co-authored-by: stoat-release[bot] <245062572+stoat-release[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] --- .release-please-manifest.json | 2 +- CHANGELOG.md | 7 +++++ Cargo.lock | 36 ++++++++++++------------- Cargo.toml | 20 +++++++------- crates/bonfire/Cargo.toml | 2 +- crates/core/coalesced/Cargo.toml | 2 +- crates/core/config/Cargo.toml | 2 +- crates/core/database/Cargo.toml | 2 +- crates/core/files/Cargo.toml | 2 +- crates/core/models/Cargo.toml | 2 +- crates/core/parser/Cargo.toml | 2 +- crates/core/permissions/Cargo.toml | 2 +- crates/core/presence/Cargo.toml | 2 +- crates/core/ratelimits/Cargo.toml | 2 +- crates/core/result/Cargo.toml | 2 +- crates/daemons/crond/Cargo.toml | 2 +- crates/daemons/pushd/Cargo.toml | 2 +- crates/daemons/voice-ingress/Cargo.toml | 2 +- crates/delta/Cargo.toml | 2 +- crates/services/autumn/Cargo.toml | 2 +- crates/services/gifbox/Cargo.toml | 2 +- crates/services/january/Cargo.toml | 2 +- version.txt | 2 +- 23 files changed, 55 insertions(+), 48 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 7f0526224..ad0fd276f 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.13.1" + ".": "0.13.2" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 31c46f2e8..d44ac826c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [0.13.2](https://github.com/stoatchat/stoatchat/compare/v0.13.1...v0.13.2) (2026-05-11) + + +### Bug Fixes + +* update default exchange to `revolt.default` ([#746](https://github.com/stoatchat/stoatchat/issues/746)) ([fcb8091](https://github.com/stoatchat/stoatchat/commit/fcb8091cd7a00d7f26c798daa33aae4b923b2a8b)) + ## [0.13.1](https://github.com/stoatchat/stoatchat/compare/v0.13.0...v0.13.1) (2026-05-10) diff --git a/Cargo.lock b/Cargo.lock index 8eeb17c5d..619c5afd0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7504,7 +7504,7 @@ dependencies = [ [[package]] name = "revolt-autumn" -version = "0.13.1" +version = "0.13.2" dependencies = [ "axum", "axum-macros", @@ -7545,7 +7545,7 @@ dependencies = [ [[package]] name = "revolt-bonfire" -version = "0.13.1" +version = "0.13.2" dependencies = [ "async-channel 2.5.0", "async-std", @@ -7576,7 +7576,7 @@ dependencies = [ [[package]] name = "revolt-coalesced" -version = "0.13.1" +version = "0.13.2" dependencies = [ "indexmap 2.13.1", "lru", @@ -7585,7 +7585,7 @@ dependencies = [ [[package]] name = "revolt-config" -version = "0.13.1" +version = "0.13.2" dependencies = [ "async-std", "cached", @@ -7602,7 +7602,7 @@ dependencies = [ [[package]] name = "revolt-crond" -version = "0.13.1" +version = "0.13.2" dependencies = [ "futures-lite", "iso8601-timestamp", @@ -7622,7 +7622,7 @@ dependencies = [ [[package]] name = "revolt-database" -version = "0.13.1" +version = "0.13.2" dependencies = [ "amqprs", "async-lock 2.8.0", @@ -7673,7 +7673,7 @@ dependencies = [ [[package]] name = "revolt-delta" -version = "0.13.1" +version = "0.13.2" dependencies = [ "amqprs", "async-channel 2.5.0", @@ -7722,7 +7722,7 @@ dependencies = [ [[package]] name = "revolt-files" -version = "0.13.1" +version = "0.13.2" dependencies = [ "aes-gcm", "anyhow", @@ -7750,7 +7750,7 @@ dependencies = [ [[package]] name = "revolt-gifbox" -version = "0.13.1" +version = "0.13.2" dependencies = [ "axum", "axum-extra", @@ -7773,7 +7773,7 @@ dependencies = [ [[package]] name = "revolt-january" -version = "0.13.1" +version = "0.13.2" dependencies = [ "async-recursion", "axum", @@ -7803,7 +7803,7 @@ dependencies = [ [[package]] name = "revolt-models" -version = "0.13.1" +version = "0.13.2" dependencies = [ "indexmap 2.13.1", "iso8601-timestamp", @@ -7822,14 +7822,14 @@ dependencies = [ [[package]] name = "revolt-parser" -version = "0.13.1" +version = "0.13.2" dependencies = [ "logos", ] [[package]] name = "revolt-permissions" -version = "0.13.1" +version = "0.13.2" dependencies = [ "async-std", "async-trait", @@ -7844,7 +7844,7 @@ dependencies = [ [[package]] name = "revolt-presence" -version = "0.13.1" +version = "0.13.2" dependencies = [ "async-std", "log", @@ -7856,7 +7856,7 @@ dependencies = [ [[package]] name = "revolt-pushd" -version = "0.13.1" +version = "0.13.2" dependencies = [ "amqprs", "anyhow", @@ -7887,7 +7887,7 @@ dependencies = [ [[package]] name = "revolt-ratelimits" -version = "0.13.1" +version = "0.13.2" dependencies = [ "async-trait", "authifier", @@ -7904,7 +7904,7 @@ dependencies = [ [[package]] name = "revolt-result" -version = "0.13.1" +version = "0.13.2" dependencies = [ "axum", "log", @@ -7920,7 +7920,7 @@ dependencies = [ [[package]] name = "revolt-voice-ingress" -version = "0.13.1" +version = "0.13.2" dependencies = [ "amqprs", "async-std", diff --git a/Cargo.toml b/Cargo.toml index 3ee8db8f2..89d36808e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -192,13 +192,13 @@ futures-lite = "2.6.1" vergen = "7.5.0" # Local packages -revolt-coalesced = { version = "0.13.1", path = "crates/core/coalesced" } -revolt-config = { version = "0.13.1", path = "crates/core/config" } -revolt-database = { version = "0.13.1", path = "crates/core/database" } -revolt-files = { version = "0.13.1", path = "crates/core/files" } -revolt-models = { version = "0.13.1", path = "crates/core/models" } -revolt-parser = { version = "0.13.1", path = "crates/core/parser" } -revolt-permissions = { version = "0.13.1", path = "crates/core/permissions" } -revolt-presence = { version = "0.13.1", path = "crates/core/presence" } -revolt-ratelimits = { version = "0.13.1", path = "crates/core/ratelimits" } -revolt-result = { version = "0.13.1", path = "crates/core/result" } +revolt-coalesced = { version = "0.13.2", path = "crates/core/coalesced" } +revolt-config = { version = "0.13.2", path = "crates/core/config" } +revolt-database = { version = "0.13.2", path = "crates/core/database" } +revolt-files = { version = "0.13.2", path = "crates/core/files" } +revolt-models = { version = "0.13.2", path = "crates/core/models" } +revolt-parser = { version = "0.13.2", path = "crates/core/parser" } +revolt-permissions = { version = "0.13.2", path = "crates/core/permissions" } +revolt-presence = { version = "0.13.2", path = "crates/core/presence" } +revolt-ratelimits = { version = "0.13.2", path = "crates/core/ratelimits" } +revolt-result = { version = "0.13.2", path = "crates/core/result" } diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index 9018e9655..3d3dca666 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-bonfire" -version = "0.13.1" +version = "0.13.2" license = "AGPL-3.0-or-later" edition = "2021" publish = false diff --git a/crates/core/coalesced/Cargo.toml b/crates/core/coalesced/Cargo.toml index 589afa704..1f071bb8c 100644 --- a/crates/core/coalesced/Cargo.toml +++ b/crates/core/coalesced/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-coalesced" -version = "0.13.1" +version = "0.13.2" edition = "2021" license = "MIT" authors = ["Paul Makles ", "Zomatree "] diff --git a/crates/core/config/Cargo.toml b/crates/core/config/Cargo.toml index 48921d77a..8c8ed893e 100644 --- a/crates/core/config/Cargo.toml +++ b/crates/core/config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-config" -version = "0.13.1" +version = "0.13.2" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index dd60ccd7d..ba4b80ea3 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-database" -version = "0.13.1" +version = "0.13.2" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] diff --git a/crates/core/files/Cargo.toml b/crates/core/files/Cargo.toml index 6910f6c13..0b4f0333b 100644 --- a/crates/core/files/Cargo.toml +++ b/crates/core/files/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-files" -version = "0.13.1" +version = "0.13.2" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] diff --git a/crates/core/models/Cargo.toml b/crates/core/models/Cargo.toml index 696107e86..5bfffbe00 100644 --- a/crates/core/models/Cargo.toml +++ b/crates/core/models/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-models" -version = "0.13.1" +version = "0.13.2" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/core/parser/Cargo.toml b/crates/core/parser/Cargo.toml index 8bd9cf03d..9637e86a5 100644 --- a/crates/core/parser/Cargo.toml +++ b/crates/core/parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-parser" -version = "0.13.1" +version = "0.13.2" edition = "2021" license = "MIT" authors = ["Zomatree ", "Paul Makles "] diff --git a/crates/core/permissions/Cargo.toml b/crates/core/permissions/Cargo.toml index 675b569b5..e9cd85119 100644 --- a/crates/core/permissions/Cargo.toml +++ b/crates/core/permissions/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-permissions" -version = "0.13.1" +version = "0.13.2" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/core/presence/Cargo.toml b/crates/core/presence/Cargo.toml index 86043d644..07fe66e66 100644 --- a/crates/core/presence/Cargo.toml +++ b/crates/core/presence/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-presence" -version = "0.13.1" +version = "0.13.2" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] diff --git a/crates/core/ratelimits/Cargo.toml b/crates/core/ratelimits/Cargo.toml index c917269d7..bedcdd427 100644 --- a/crates/core/ratelimits/Cargo.toml +++ b/crates/core/ratelimits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-ratelimits" -version = "0.13.1" +version = "0.13.2" edition = "2024" license = "MIT" authors = ["Zomatree ", "Paul Makles "] diff --git a/crates/core/result/Cargo.toml b/crates/core/result/Cargo.toml index 12e358f11..8543a07ab 100644 --- a/crates/core/result/Cargo.toml +++ b/crates/core/result/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-result" -version = "0.13.1" +version = "0.13.2" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/daemons/crond/Cargo.toml b/crates/daemons/crond/Cargo.toml index f9b09ef14..065e0dc6b 100644 --- a/crates/daemons/crond/Cargo.toml +++ b/crates/daemons/crond/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-crond" -version = "0.13.1" +version = "0.13.2" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2021" diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index 2f1ba2f75..2500d53e6 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-pushd" -version = "0.13.1" +version = "0.13.2" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/crates/daemons/voice-ingress/Cargo.toml b/crates/daemons/voice-ingress/Cargo.toml index ebd90a586..4bd679e6e 100644 --- a/crates/daemons/voice-ingress/Cargo.toml +++ b/crates/daemons/voice-ingress/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-voice-ingress" -version = "0.13.1" +version = "0.13.2" license = "AGPL-3.0-or-later" edition = "2021" publish = false diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index ef007daea..b3914455c 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-delta" -version = "0.13.1" +version = "0.13.2" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2018" diff --git a/crates/services/autumn/Cargo.toml b/crates/services/autumn/Cargo.toml index 549ecdcd9..a12e07cd1 100644 --- a/crates/services/autumn/Cargo.toml +++ b/crates/services/autumn/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-autumn" -version = "0.13.1" +version = "0.13.2" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/crates/services/gifbox/Cargo.toml b/crates/services/gifbox/Cargo.toml index 355952cfa..7e804be92 100644 --- a/crates/services/gifbox/Cargo.toml +++ b/crates/services/gifbox/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-gifbox" -version = "0.13.1" +version = "0.13.2" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/crates/services/january/Cargo.toml b/crates/services/january/Cargo.toml index 76d8e5c3f..749ceac7a 100644 --- a/crates/services/january/Cargo.toml +++ b/crates/services/january/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-january" -version = "0.13.1" +version = "0.13.2" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/version.txt b/version.txt index c317a9189..9beb74d49 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.13.1 +0.13.2 From 7647cfc8d93aba99f5faef13eb3d970097540d76 Mon Sep 17 00:00:00 2001 From: Tom Date: Fri, 15 May 2026 12:17:36 -0700 Subject: [PATCH 169/211] fix: don't automatically set up rabbitmq in delta (#749) fix: don't declare queues which seem to cause the backend to crash in prod for now, these exchanges/queues/bindings will need to be declared manually. Hopefully the lapin rewrite will fix this. Signed-off-by: IAmTomahawkx --- crates/core/database/src/amqp/amqp.rs | 2 +- crates/delta/src/main.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/core/database/src/amqp/amqp.rs b/crates/core/database/src/amqp/amqp.rs index 163260454..e0c644e51 100644 --- a/crates/core/database/src/amqp/amqp.rs +++ b/crates/core/database/src/amqp/amqp.rs @@ -47,7 +47,7 @@ impl AMQP { .expect("Failed to open RabbitMQ channel"); let mut resp = AMQP::new(connection, channel); - resp.configure_channels().await?; + //resp.configure_channels().await?; Ok(resp) } diff --git a/crates/delta/src/main.rs b/crates/delta/src/main.rs index e3cf43a4c..15aa2d3b7 100644 --- a/crates/delta/src/main.rs +++ b/crates/delta/src/main.rs @@ -120,9 +120,9 @@ pub async fn web() -> Rocket { .expect("Failed to declare exchange"); let mut amqp = AMQP::new(connection, channel); - amqp.configure_channels() - .await - .expect("Failed to configure channels"); + // amqp.configure_channels() + // .await + // .expect("Failed to configure channels"); // Launch background task workers revolt_database::tasks::start_workers(db.clone(), amqp.clone()); From ab9b8ccfca5235973605406ace483b3f7dfe9ba1 Mon Sep 17 00:00:00 2001 From: "stoat-release[bot]" <245062572+stoat-release[bot]@users.noreply.github.com> Date: Fri, 15 May 2026 12:22:27 -0700 Subject: [PATCH 170/211] chore(main): release 0.13.3 (#750) * chore(main): release 0.13.3 * chore: update Cargo.lock Signed-off-by: github-actions[bot] --------- Signed-off-by: github-actions[bot] Co-authored-by: stoat-release[bot] <245062572+stoat-release[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] --- .release-please-manifest.json | 2 +- CHANGELOG.md | 8 ++++++ Cargo.lock | 36 ++++++++++++------------- Cargo.toml | 20 +++++++------- crates/bonfire/Cargo.toml | 2 +- crates/core/coalesced/Cargo.toml | 2 +- crates/core/config/Cargo.toml | 2 +- crates/core/database/Cargo.toml | 2 +- crates/core/files/Cargo.toml | 2 +- crates/core/models/Cargo.toml | 2 +- crates/core/parser/Cargo.toml | 2 +- crates/core/permissions/Cargo.toml | 2 +- crates/core/presence/Cargo.toml | 2 +- crates/core/ratelimits/Cargo.toml | 2 +- crates/core/result/Cargo.toml | 2 +- crates/daemons/crond/Cargo.toml | 2 +- crates/daemons/pushd/Cargo.toml | 2 +- crates/daemons/voice-ingress/Cargo.toml | 2 +- crates/delta/Cargo.toml | 2 +- crates/services/autumn/Cargo.toml | 2 +- crates/services/gifbox/Cargo.toml | 2 +- crates/services/january/Cargo.toml | 2 +- version.txt | 2 +- 23 files changed, 56 insertions(+), 48 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index ad0fd276f..e408c3706 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.13.2" + ".": "0.13.3" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index d44ac826c..9581ec4a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [0.13.3](https://github.com/stoatchat/stoatchat/compare/v0.13.2...v0.13.3) (2026-05-15) + + +### Bug Fixes + +* don't automatically set up rabbitmq in delta ([#749](https://github.com/stoatchat/stoatchat/issues/749)) ([7647cfc](https://github.com/stoatchat/stoatchat/commit/7647cfc8d93aba99f5faef13eb3d970097540d76)) +* don't declare queues which seem to cause the backend to crash in prod ([7647cfc](https://github.com/stoatchat/stoatchat/commit/7647cfc8d93aba99f5faef13eb3d970097540d76)) + ## [0.13.2](https://github.com/stoatchat/stoatchat/compare/v0.13.1...v0.13.2) (2026-05-11) diff --git a/Cargo.lock b/Cargo.lock index 619c5afd0..c70500117 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7504,7 +7504,7 @@ dependencies = [ [[package]] name = "revolt-autumn" -version = "0.13.2" +version = "0.13.3" dependencies = [ "axum", "axum-macros", @@ -7545,7 +7545,7 @@ dependencies = [ [[package]] name = "revolt-bonfire" -version = "0.13.2" +version = "0.13.3" dependencies = [ "async-channel 2.5.0", "async-std", @@ -7576,7 +7576,7 @@ dependencies = [ [[package]] name = "revolt-coalesced" -version = "0.13.2" +version = "0.13.3" dependencies = [ "indexmap 2.13.1", "lru", @@ -7585,7 +7585,7 @@ dependencies = [ [[package]] name = "revolt-config" -version = "0.13.2" +version = "0.13.3" dependencies = [ "async-std", "cached", @@ -7602,7 +7602,7 @@ dependencies = [ [[package]] name = "revolt-crond" -version = "0.13.2" +version = "0.13.3" dependencies = [ "futures-lite", "iso8601-timestamp", @@ -7622,7 +7622,7 @@ dependencies = [ [[package]] name = "revolt-database" -version = "0.13.2" +version = "0.13.3" dependencies = [ "amqprs", "async-lock 2.8.0", @@ -7673,7 +7673,7 @@ dependencies = [ [[package]] name = "revolt-delta" -version = "0.13.2" +version = "0.13.3" dependencies = [ "amqprs", "async-channel 2.5.0", @@ -7722,7 +7722,7 @@ dependencies = [ [[package]] name = "revolt-files" -version = "0.13.2" +version = "0.13.3" dependencies = [ "aes-gcm", "anyhow", @@ -7750,7 +7750,7 @@ dependencies = [ [[package]] name = "revolt-gifbox" -version = "0.13.2" +version = "0.13.3" dependencies = [ "axum", "axum-extra", @@ -7773,7 +7773,7 @@ dependencies = [ [[package]] name = "revolt-january" -version = "0.13.2" +version = "0.13.3" dependencies = [ "async-recursion", "axum", @@ -7803,7 +7803,7 @@ dependencies = [ [[package]] name = "revolt-models" -version = "0.13.2" +version = "0.13.3" dependencies = [ "indexmap 2.13.1", "iso8601-timestamp", @@ -7822,14 +7822,14 @@ dependencies = [ [[package]] name = "revolt-parser" -version = "0.13.2" +version = "0.13.3" dependencies = [ "logos", ] [[package]] name = "revolt-permissions" -version = "0.13.2" +version = "0.13.3" dependencies = [ "async-std", "async-trait", @@ -7844,7 +7844,7 @@ dependencies = [ [[package]] name = "revolt-presence" -version = "0.13.2" +version = "0.13.3" dependencies = [ "async-std", "log", @@ -7856,7 +7856,7 @@ dependencies = [ [[package]] name = "revolt-pushd" -version = "0.13.2" +version = "0.13.3" dependencies = [ "amqprs", "anyhow", @@ -7887,7 +7887,7 @@ dependencies = [ [[package]] name = "revolt-ratelimits" -version = "0.13.2" +version = "0.13.3" dependencies = [ "async-trait", "authifier", @@ -7904,7 +7904,7 @@ dependencies = [ [[package]] name = "revolt-result" -version = "0.13.2" +version = "0.13.3" dependencies = [ "axum", "log", @@ -7920,7 +7920,7 @@ dependencies = [ [[package]] name = "revolt-voice-ingress" -version = "0.13.2" +version = "0.13.3" dependencies = [ "amqprs", "async-std", diff --git a/Cargo.toml b/Cargo.toml index 89d36808e..7bc0d3526 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -192,13 +192,13 @@ futures-lite = "2.6.1" vergen = "7.5.0" # Local packages -revolt-coalesced = { version = "0.13.2", path = "crates/core/coalesced" } -revolt-config = { version = "0.13.2", path = "crates/core/config" } -revolt-database = { version = "0.13.2", path = "crates/core/database" } -revolt-files = { version = "0.13.2", path = "crates/core/files" } -revolt-models = { version = "0.13.2", path = "crates/core/models" } -revolt-parser = { version = "0.13.2", path = "crates/core/parser" } -revolt-permissions = { version = "0.13.2", path = "crates/core/permissions" } -revolt-presence = { version = "0.13.2", path = "crates/core/presence" } -revolt-ratelimits = { version = "0.13.2", path = "crates/core/ratelimits" } -revolt-result = { version = "0.13.2", path = "crates/core/result" } +revolt-coalesced = { version = "0.13.3", path = "crates/core/coalesced" } +revolt-config = { version = "0.13.3", path = "crates/core/config" } +revolt-database = { version = "0.13.3", path = "crates/core/database" } +revolt-files = { version = "0.13.3", path = "crates/core/files" } +revolt-models = { version = "0.13.3", path = "crates/core/models" } +revolt-parser = { version = "0.13.3", path = "crates/core/parser" } +revolt-permissions = { version = "0.13.3", path = "crates/core/permissions" } +revolt-presence = { version = "0.13.3", path = "crates/core/presence" } +revolt-ratelimits = { version = "0.13.3", path = "crates/core/ratelimits" } +revolt-result = { version = "0.13.3", path = "crates/core/result" } diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index 3d3dca666..83a025133 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-bonfire" -version = "0.13.2" +version = "0.13.3" license = "AGPL-3.0-or-later" edition = "2021" publish = false diff --git a/crates/core/coalesced/Cargo.toml b/crates/core/coalesced/Cargo.toml index 1f071bb8c..8ed165849 100644 --- a/crates/core/coalesced/Cargo.toml +++ b/crates/core/coalesced/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-coalesced" -version = "0.13.2" +version = "0.13.3" edition = "2021" license = "MIT" authors = ["Paul Makles ", "Zomatree "] diff --git a/crates/core/config/Cargo.toml b/crates/core/config/Cargo.toml index 8c8ed893e..464c4e1ba 100644 --- a/crates/core/config/Cargo.toml +++ b/crates/core/config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-config" -version = "0.13.2" +version = "0.13.3" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index ba4b80ea3..26e12e8d7 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-database" -version = "0.13.2" +version = "0.13.3" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] diff --git a/crates/core/files/Cargo.toml b/crates/core/files/Cargo.toml index 0b4f0333b..8c106597b 100644 --- a/crates/core/files/Cargo.toml +++ b/crates/core/files/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-files" -version = "0.13.2" +version = "0.13.3" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] diff --git a/crates/core/models/Cargo.toml b/crates/core/models/Cargo.toml index 5bfffbe00..e27a0eb83 100644 --- a/crates/core/models/Cargo.toml +++ b/crates/core/models/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-models" -version = "0.13.2" +version = "0.13.3" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/core/parser/Cargo.toml b/crates/core/parser/Cargo.toml index 9637e86a5..5612294e7 100644 --- a/crates/core/parser/Cargo.toml +++ b/crates/core/parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-parser" -version = "0.13.2" +version = "0.13.3" edition = "2021" license = "MIT" authors = ["Zomatree ", "Paul Makles "] diff --git a/crates/core/permissions/Cargo.toml b/crates/core/permissions/Cargo.toml index e9cd85119..d39b4a013 100644 --- a/crates/core/permissions/Cargo.toml +++ b/crates/core/permissions/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-permissions" -version = "0.13.2" +version = "0.13.3" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/core/presence/Cargo.toml b/crates/core/presence/Cargo.toml index 07fe66e66..4d3505c7a 100644 --- a/crates/core/presence/Cargo.toml +++ b/crates/core/presence/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-presence" -version = "0.13.2" +version = "0.13.3" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] diff --git a/crates/core/ratelimits/Cargo.toml b/crates/core/ratelimits/Cargo.toml index bedcdd427..30d32e2f4 100644 --- a/crates/core/ratelimits/Cargo.toml +++ b/crates/core/ratelimits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-ratelimits" -version = "0.13.2" +version = "0.13.3" edition = "2024" license = "MIT" authors = ["Zomatree ", "Paul Makles "] diff --git a/crates/core/result/Cargo.toml b/crates/core/result/Cargo.toml index 8543a07ab..7ff40fcaf 100644 --- a/crates/core/result/Cargo.toml +++ b/crates/core/result/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-result" -version = "0.13.2" +version = "0.13.3" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/daemons/crond/Cargo.toml b/crates/daemons/crond/Cargo.toml index 065e0dc6b..8946ea734 100644 --- a/crates/daemons/crond/Cargo.toml +++ b/crates/daemons/crond/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-crond" -version = "0.13.2" +version = "0.13.3" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2021" diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index 2500d53e6..65fb5cf4b 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-pushd" -version = "0.13.2" +version = "0.13.3" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/crates/daemons/voice-ingress/Cargo.toml b/crates/daemons/voice-ingress/Cargo.toml index 4bd679e6e..5b680a046 100644 --- a/crates/daemons/voice-ingress/Cargo.toml +++ b/crates/daemons/voice-ingress/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-voice-ingress" -version = "0.13.2" +version = "0.13.3" license = "AGPL-3.0-or-later" edition = "2021" publish = false diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index b3914455c..d57b2d1fd 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-delta" -version = "0.13.2" +version = "0.13.3" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2018" diff --git a/crates/services/autumn/Cargo.toml b/crates/services/autumn/Cargo.toml index a12e07cd1..119870967 100644 --- a/crates/services/autumn/Cargo.toml +++ b/crates/services/autumn/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-autumn" -version = "0.13.2" +version = "0.13.3" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/crates/services/gifbox/Cargo.toml b/crates/services/gifbox/Cargo.toml index 7e804be92..32a93770d 100644 --- a/crates/services/gifbox/Cargo.toml +++ b/crates/services/gifbox/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-gifbox" -version = "0.13.2" +version = "0.13.3" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/crates/services/january/Cargo.toml b/crates/services/january/Cargo.toml index 749ceac7a..fd89d808a 100644 --- a/crates/services/january/Cargo.toml +++ b/crates/services/january/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-january" -version = "0.13.2" +version = "0.13.3" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/version.txt b/version.txt index 9beb74d49..288adf538 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.13.2 +0.13.3 From 6cfee1f601c1e084df7c8f1e7a5e8a560d1dd514 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Sat, 16 May 2026 12:23:45 -0500 Subject: [PATCH 171/211] fix: add TLS feature to livekit-api crate (#753) --- Cargo.lock | 47 ++++++++++++++++++++++++++++++++- crates/core/database/Cargo.toml | 2 +- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c70500117..d34b40dc7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -570,7 +570,7 @@ dependencies = [ "futures-util", "log", "pin-project-lite 0.2.17", - "tungstenite", + "tungstenite 0.17.3", ] [[package]] @@ -5048,11 +5048,14 @@ dependencies = [ "prost", "rand 0.9.2", "reqwest 0.12.28", + "rustls-native-certs 0.6.3", "scopeguard", "serde", "serde_json", "sha2", "thiserror 2.0.18", + "tokio-rustls 0.24.1", + "tokio-tungstenite", "url", ] @@ -7419,16 +7422,22 @@ dependencies = [ "http-body 1.0.1", "http-body-util", "hyper 1.9.0", + "hyper-rustls 0.27.7", "hyper-util", "js-sys", "log", "percent-encoding", "pin-project-lite 0.2.17", + "quinn", + "rustls 0.23.37", + "rustls-native-certs 0.8.3", + "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", "sync_wrapper 1.0.2", "tokio 1.51.0", + "tokio-rustls 0.26.4", "tower", "tower-http 0.6.8", "tower-service", @@ -7665,6 +7674,7 @@ dependencies = [ "schemars", "serde", "serde_json", + "tokio 1.51.0", "ulid 1.2.1", "unicode-segmentation", "url-escape", @@ -9891,6 +9901,21 @@ dependencies = [ "tokio 1.51.0", ] +[[package]] +name = "tokio-tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +dependencies = [ + "futures-util", + "log", + "rustls 0.21.12", + "rustls-native-certs 0.6.3", + "tokio 1.51.0", + "tokio-rustls 0.24.1", + "tungstenite 0.20.1", +] + [[package]] name = "tokio-util" version = "0.7.18" @@ -10146,6 +10171,26 @@ dependencies = [ "utf-8", ] +[[package]] +name = "tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" +dependencies = [ + "byteorder", + "bytes 1.11.1", + "data-encoding", + "http 0.2.12", + "httparse", + "log", + "rand 0.8.5", + "rustls 0.21.12", + "sha1", + "thiserror 1.0.69", + "url", + "utf-8", +] + [[package]] name = "typed-builder" version = "0.22.0" diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index 26e12e8d7..dbaf35756 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -98,6 +98,6 @@ authifier = { workspace = true } amqprs = { workspace = true } # Voice -livekit-api = { workspace = true, optional = true } +livekit-api = { workspace = true, features = ["rustls-tls-native-roots"], optional = true } livekit-protocol = { workspace = true, optional = true } livekit-runtime = { workspace = true, features = ["tokio"], optional = true } From ee4575470bbad9608031f574e9e432535530f4dd Mon Sep 17 00:00:00 2001 From: "stoat-release[bot]" <245062572+stoat-release[bot]@users.noreply.github.com> Date: Sat, 16 May 2026 18:27:44 +0100 Subject: [PATCH 172/211] chore(main): release 0.13.4 (#754) Co-authored-by: github-actions[bot] Signed-off-by: github-actions[bot] --- .release-please-manifest.json | 2 +- CHANGELOG.md | 7 +++++ Cargo.lock | 37 ++++++++++++------------- Cargo.toml | 20 ++++++------- crates/bonfire/Cargo.toml | 2 +- crates/core/coalesced/Cargo.toml | 2 +- crates/core/config/Cargo.toml | 2 +- crates/core/database/Cargo.toml | 2 +- crates/core/files/Cargo.toml | 2 +- crates/core/models/Cargo.toml | 2 +- crates/core/parser/Cargo.toml | 2 +- crates/core/permissions/Cargo.toml | 2 +- crates/core/presence/Cargo.toml | 2 +- crates/core/ratelimits/Cargo.toml | 2 +- crates/core/result/Cargo.toml | 2 +- crates/daemons/crond/Cargo.toml | 2 +- crates/daemons/pushd/Cargo.toml | 2 +- crates/daemons/voice-ingress/Cargo.toml | 2 +- crates/delta/Cargo.toml | 2 +- crates/services/autumn/Cargo.toml | 2 +- crates/services/gifbox/Cargo.toml | 2 +- crates/services/january/Cargo.toml | 2 +- version.txt | 2 +- 23 files changed, 55 insertions(+), 49 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index e408c3706..60633e475 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.13.3" + ".": "0.13.4" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 9581ec4a3..18d08823f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [0.13.4](https://github.com/stoatchat/stoatchat/compare/v0.13.3...v0.13.4) (2026-05-16) + + +### Bug Fixes + +* add TLS feature to livekit-api crate ([#753](https://github.com/stoatchat/stoatchat/issues/753)) ([6cfee1f](https://github.com/stoatchat/stoatchat/commit/6cfee1f601c1e084df7c8f1e7a5e8a560d1dd514)) + ## [0.13.3](https://github.com/stoatchat/stoatchat/compare/v0.13.2...v0.13.3) (2026-05-15) diff --git a/Cargo.lock b/Cargo.lock index d34b40dc7..e34841661 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7513,7 +7513,7 @@ dependencies = [ [[package]] name = "revolt-autumn" -version = "0.13.3" +version = "0.13.4" dependencies = [ "axum", "axum-macros", @@ -7554,7 +7554,7 @@ dependencies = [ [[package]] name = "revolt-bonfire" -version = "0.13.3" +version = "0.13.4" dependencies = [ "async-channel 2.5.0", "async-std", @@ -7585,7 +7585,7 @@ dependencies = [ [[package]] name = "revolt-coalesced" -version = "0.13.3" +version = "0.13.4" dependencies = [ "indexmap 2.13.1", "lru", @@ -7594,7 +7594,7 @@ dependencies = [ [[package]] name = "revolt-config" -version = "0.13.3" +version = "0.13.4" dependencies = [ "async-std", "cached", @@ -7611,7 +7611,7 @@ dependencies = [ [[package]] name = "revolt-crond" -version = "0.13.3" +version = "0.13.4" dependencies = [ "futures-lite", "iso8601-timestamp", @@ -7631,7 +7631,7 @@ dependencies = [ [[package]] name = "revolt-database" -version = "0.13.3" +version = "0.13.4" dependencies = [ "amqprs", "async-lock 2.8.0", @@ -7674,7 +7674,6 @@ dependencies = [ "schemars", "serde", "serde_json", - "tokio 1.51.0", "ulid 1.2.1", "unicode-segmentation", "url-escape", @@ -7683,7 +7682,7 @@ dependencies = [ [[package]] name = "revolt-delta" -version = "0.13.3" +version = "0.13.4" dependencies = [ "amqprs", "async-channel 2.5.0", @@ -7732,7 +7731,7 @@ dependencies = [ [[package]] name = "revolt-files" -version = "0.13.3" +version = "0.13.4" dependencies = [ "aes-gcm", "anyhow", @@ -7760,7 +7759,7 @@ dependencies = [ [[package]] name = "revolt-gifbox" -version = "0.13.3" +version = "0.13.4" dependencies = [ "axum", "axum-extra", @@ -7783,7 +7782,7 @@ dependencies = [ [[package]] name = "revolt-january" -version = "0.13.3" +version = "0.13.4" dependencies = [ "async-recursion", "axum", @@ -7813,7 +7812,7 @@ dependencies = [ [[package]] name = "revolt-models" -version = "0.13.3" +version = "0.13.4" dependencies = [ "indexmap 2.13.1", "iso8601-timestamp", @@ -7832,14 +7831,14 @@ dependencies = [ [[package]] name = "revolt-parser" -version = "0.13.3" +version = "0.13.4" dependencies = [ "logos", ] [[package]] name = "revolt-permissions" -version = "0.13.3" +version = "0.13.4" dependencies = [ "async-std", "async-trait", @@ -7854,7 +7853,7 @@ dependencies = [ [[package]] name = "revolt-presence" -version = "0.13.3" +version = "0.13.4" dependencies = [ "async-std", "log", @@ -7866,7 +7865,7 @@ dependencies = [ [[package]] name = "revolt-pushd" -version = "0.13.3" +version = "0.13.4" dependencies = [ "amqprs", "anyhow", @@ -7897,7 +7896,7 @@ dependencies = [ [[package]] name = "revolt-ratelimits" -version = "0.13.3" +version = "0.13.4" dependencies = [ "async-trait", "authifier", @@ -7914,7 +7913,7 @@ dependencies = [ [[package]] name = "revolt-result" -version = "0.13.3" +version = "0.13.4" dependencies = [ "axum", "log", @@ -7930,7 +7929,7 @@ dependencies = [ [[package]] name = "revolt-voice-ingress" -version = "0.13.3" +version = "0.13.4" dependencies = [ "amqprs", "async-std", diff --git a/Cargo.toml b/Cargo.toml index 7bc0d3526..5cb9b347a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -192,13 +192,13 @@ futures-lite = "2.6.1" vergen = "7.5.0" # Local packages -revolt-coalesced = { version = "0.13.3", path = "crates/core/coalesced" } -revolt-config = { version = "0.13.3", path = "crates/core/config" } -revolt-database = { version = "0.13.3", path = "crates/core/database" } -revolt-files = { version = "0.13.3", path = "crates/core/files" } -revolt-models = { version = "0.13.3", path = "crates/core/models" } -revolt-parser = { version = "0.13.3", path = "crates/core/parser" } -revolt-permissions = { version = "0.13.3", path = "crates/core/permissions" } -revolt-presence = { version = "0.13.3", path = "crates/core/presence" } -revolt-ratelimits = { version = "0.13.3", path = "crates/core/ratelimits" } -revolt-result = { version = "0.13.3", path = "crates/core/result" } +revolt-coalesced = { version = "0.13.4", path = "crates/core/coalesced" } +revolt-config = { version = "0.13.4", path = "crates/core/config" } +revolt-database = { version = "0.13.4", path = "crates/core/database" } +revolt-files = { version = "0.13.4", path = "crates/core/files" } +revolt-models = { version = "0.13.4", path = "crates/core/models" } +revolt-parser = { version = "0.13.4", path = "crates/core/parser" } +revolt-permissions = { version = "0.13.4", path = "crates/core/permissions" } +revolt-presence = { version = "0.13.4", path = "crates/core/presence" } +revolt-ratelimits = { version = "0.13.4", path = "crates/core/ratelimits" } +revolt-result = { version = "0.13.4", path = "crates/core/result" } diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index 83a025133..b67410dde 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-bonfire" -version = "0.13.3" +version = "0.13.4" license = "AGPL-3.0-or-later" edition = "2021" publish = false diff --git a/crates/core/coalesced/Cargo.toml b/crates/core/coalesced/Cargo.toml index 8ed165849..f8e3e0111 100644 --- a/crates/core/coalesced/Cargo.toml +++ b/crates/core/coalesced/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-coalesced" -version = "0.13.3" +version = "0.13.4" edition = "2021" license = "MIT" authors = ["Paul Makles ", "Zomatree "] diff --git a/crates/core/config/Cargo.toml b/crates/core/config/Cargo.toml index 464c4e1ba..df4cbf37a 100644 --- a/crates/core/config/Cargo.toml +++ b/crates/core/config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-config" -version = "0.13.3" +version = "0.13.4" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index dbaf35756..987bfa86c 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-database" -version = "0.13.3" +version = "0.13.4" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] diff --git a/crates/core/files/Cargo.toml b/crates/core/files/Cargo.toml index 8c106597b..1b0252a86 100644 --- a/crates/core/files/Cargo.toml +++ b/crates/core/files/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-files" -version = "0.13.3" +version = "0.13.4" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] diff --git a/crates/core/models/Cargo.toml b/crates/core/models/Cargo.toml index e27a0eb83..2139f1592 100644 --- a/crates/core/models/Cargo.toml +++ b/crates/core/models/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-models" -version = "0.13.3" +version = "0.13.4" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/core/parser/Cargo.toml b/crates/core/parser/Cargo.toml index 5612294e7..2f0d62786 100644 --- a/crates/core/parser/Cargo.toml +++ b/crates/core/parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-parser" -version = "0.13.3" +version = "0.13.4" edition = "2021" license = "MIT" authors = ["Zomatree ", "Paul Makles "] diff --git a/crates/core/permissions/Cargo.toml b/crates/core/permissions/Cargo.toml index d39b4a013..c9e775fea 100644 --- a/crates/core/permissions/Cargo.toml +++ b/crates/core/permissions/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-permissions" -version = "0.13.3" +version = "0.13.4" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/core/presence/Cargo.toml b/crates/core/presence/Cargo.toml index 4d3505c7a..faa0f0a27 100644 --- a/crates/core/presence/Cargo.toml +++ b/crates/core/presence/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-presence" -version = "0.13.3" +version = "0.13.4" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] diff --git a/crates/core/ratelimits/Cargo.toml b/crates/core/ratelimits/Cargo.toml index 30d32e2f4..bf367893b 100644 --- a/crates/core/ratelimits/Cargo.toml +++ b/crates/core/ratelimits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-ratelimits" -version = "0.13.3" +version = "0.13.4" edition = "2024" license = "MIT" authors = ["Zomatree ", "Paul Makles "] diff --git a/crates/core/result/Cargo.toml b/crates/core/result/Cargo.toml index 7ff40fcaf..736fbd332 100644 --- a/crates/core/result/Cargo.toml +++ b/crates/core/result/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-result" -version = "0.13.3" +version = "0.13.4" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/daemons/crond/Cargo.toml b/crates/daemons/crond/Cargo.toml index 8946ea734..f17e5e77a 100644 --- a/crates/daemons/crond/Cargo.toml +++ b/crates/daemons/crond/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-crond" -version = "0.13.3" +version = "0.13.4" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2021" diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index 65fb5cf4b..94f610f78 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-pushd" -version = "0.13.3" +version = "0.13.4" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/crates/daemons/voice-ingress/Cargo.toml b/crates/daemons/voice-ingress/Cargo.toml index 5b680a046..50218d480 100644 --- a/crates/daemons/voice-ingress/Cargo.toml +++ b/crates/daemons/voice-ingress/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-voice-ingress" -version = "0.13.3" +version = "0.13.4" license = "AGPL-3.0-or-later" edition = "2021" publish = false diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index d57b2d1fd..431a80a66 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-delta" -version = "0.13.3" +version = "0.13.4" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2018" diff --git a/crates/services/autumn/Cargo.toml b/crates/services/autumn/Cargo.toml index 119870967..aa77a337f 100644 --- a/crates/services/autumn/Cargo.toml +++ b/crates/services/autumn/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-autumn" -version = "0.13.3" +version = "0.13.4" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/crates/services/gifbox/Cargo.toml b/crates/services/gifbox/Cargo.toml index 32a93770d..03e3ee6e2 100644 --- a/crates/services/gifbox/Cargo.toml +++ b/crates/services/gifbox/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-gifbox" -version = "0.13.3" +version = "0.13.4" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/crates/services/january/Cargo.toml b/crates/services/january/Cargo.toml index fd89d808a..d8f1dac93 100644 --- a/crates/services/january/Cargo.toml +++ b/crates/services/january/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-january" -version = "0.13.3" +version = "0.13.4" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/version.txt b/version.txt index 288adf538..dffa40ec3 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.13.3 +0.13.4 From 19ee535f45e76512c17b38206bf3b61b39c6d4df Mon Sep 17 00:00:00 2001 From: Tom Date: Sun, 17 May 2026 10:55:38 -0700 Subject: [PATCH 173/211] Merge commit from fork * fix: cache dns & block more ranges * fix: idle time instead of ttl Signed-off-by: IAmTomahawkx --------- Signed-off-by: IAmTomahawkx --- crates/services/january/src/requests.rs | 120 ++++++++++++++++++++---- 1 file changed, 104 insertions(+), 16 deletions(-) diff --git a/crates/services/january/src/requests.rs b/crates/services/january/src/requests.rs index b63f203e7..c818619b7 100644 --- a/crates/services/january/src/requests.rs +++ b/crates/services/january/src/requests.rs @@ -4,6 +4,7 @@ use mime::Mime; use pdk_ip_filter_lib::IpFilter; use regex::Regex; use reqwest::{ + dns::{Addrs, Name, Resolve}, header::{self, CONTENT_TYPE}, redirect, Client, Response, }; @@ -11,6 +12,7 @@ use revolt_config::{config, report_internal_error}; use revolt_files::{create_thumbnail, decode_image, image_size_vec, is_valid_image, video_size}; use revolt_models::v0::{Embed, Image, ImageSize, Video}; use revolt_result::{create_error, Error, Result, ToRevoltError}; +use std::net::{IpAddr, SocketAddr}; use std::{ io::{Cursor, Write}, str::FromStr, @@ -21,6 +23,7 @@ use url::{Host, Url}; lazy_static! { /// Request client static ref CLIENT: Client = reqwest::Client::builder() + .dns_resolver(CachedDnsResolver {}) .timeout(Duration::from_secs(10)) // TODO config .connect_timeout(Duration::from_secs(5)) // TODO config .redirect(redirect::Policy::none()) @@ -58,18 +61,73 @@ lazy_static! { .time_to_live(Duration::from_secs(60)) // For up to 1 minute .build(); + static ref DNS_CACHE: moka::future::Cache> = moka::future::Cache::builder() + .max_capacity(10_000) + .time_to_idle(Duration::from_secs(30)) + .build(); + static ref IP_BLOCKLIST: IpFilter = IpFilter::block(&[ + "0.0.0.0/8", "10.0.0.0/8", "192.168.0.0/16", "127.0.0.0/8", "172.16.0.0/12", "169.254.0.0/16", "::1", - "fc00::/7" + "fc00::/7", ] ).unwrap(); } +#[derive(Clone)] +pub struct IPRequest { + url: Url, + ip: IpAddr, + pub blocked: bool, +} + +impl From for Url { + fn from(value: IPRequest) -> Self { + let mut url = value.url.clone(); + url.set_host(Some(&value.ip.to_string())) + .map(|_| url) + .unwrap_or(value.url) + } +} + +struct CachedDnsResolver {} + +impl reqwest::dns::Resolve for CachedDnsResolver { + fn resolve(&self, name: Name) -> reqwest::dns::Resolving { + Box::pin(async move { + { + if let Some(addrs) = DNS_CACHE.get(&name.as_str().to_string()).await { + let resp: Addrs = Box::new(addrs.clone().into_iter()); + return Ok(resp); + } + } + + let mut lookup = name.as_str().to_string(); + if !lookup.contains(":") { + lookup += ":0"; + } + + let fallback: Vec = tokio::net::lookup_host(&lookup) + .await + .map_err(|e| -> Box { Box::new(e) })? + .collect(); + + { + DNS_CACHE + .insert(name.as_str().to_string().clone(), fallback.clone()) + .await; + let addrs: Addrs = Box::new(fallback.clone().into_iter()); + Ok(addrs) + } + }) + } +} + /// Information about a successful request pub struct Request { response: Response, @@ -275,7 +333,12 @@ impl Request { let mut url = url; let url_host_str = url.host_str().ok_or(create_error!(ProxyError))?.to_string(); - Request::url_is_blacklisted(&url).await?; + let mut blocker = Request::url_is_blacklisted(&url).await?; + + if blocker.blocked { + return Err(create_error!(InvalidOperation)); + } + let mut redirect_count = 0; loop { @@ -304,9 +367,13 @@ impl Request { let location = location.to_str().map_err(|_| create_error!(ProxyError))?; url = Url::from_str(location).to_internal_error()?; - if !Request::url_is_blacklisted(&url).await? { - continue; + blocker = Request::url_is_blacklisted(&url).await?; + + if blocker.blocked { + return Err(create_error!(InvalidOperation)); } + + continue; } else { return Err(create_error!(ProxyError)); } @@ -351,17 +418,25 @@ impl Request { Ok(Request::exists(proper_url).await) } - pub async fn url_is_blacklisted(url: &Url) -> Result { + pub async fn url_is_blacklisted(url: &Url) -> Result { + let resolved_address: IpAddr; + if let Some(host) = url.host() { match host { Host::Ipv4(ipv4) => { - let url_str = ipv4.to_string(); - if !IP_BLOCKLIST.is_allowed(&url_str) { + resolved_address = ipv4.into(); + if !IP_BLOCKLIST.is_allowed(&ipv4.to_string()) { + return Err(create_error!(InvalidOperation)); + } + } + Host::Ipv6(ipv6) => { + resolved_address = ipv6.into(); + if !IP_BLOCKLIST.is_allowed(&ipv6.to_string()) { return Err(create_error!(InvalidOperation)); } } Host::Domain(domain) => { - let mut domain = domain.to_string(); + let domain = domain.to_string(); let config = config().await; @@ -372,14 +447,22 @@ impl Request { return Err(create_error!(InvalidOperation)); } - if !domain.contains(":") { - domain += ":80"; - } - // Second step: resolve the IP and check the blocklist - if let Ok(mut resolved_ip) = tokio::net::lookup_host(domain.clone()).await { + let resolver = CachedDnsResolver {}; + if let Ok(mut resolved_ip) = resolver + .resolve( + Name::from_str(&domain) + .map_err(|_| create_error!(ProxyError)) + .unwrap(), + ) + .await + { if let Some(resolved_ip) = resolved_ip.next() { - if !IP_BLOCKLIST.is_allowed(&resolved_ip.ip().to_string()) { + resolved_address = resolved_ip.ip(); + let resolved_string = resolved_address.to_string(); + if !IP_BLOCKLIST.is_allowed(&resolved_string) + || resolved_string.contains("::ffff:") + { return Err(create_error!(InvalidOperation)); } } else { @@ -389,10 +472,15 @@ impl Request { return Err(create_error!(ProxyError)); } } - _ => (), } + } else { + return Err(create_error!(ProxyError)); }; - Ok(false) + Ok(IPRequest { + url: url.clone(), + ip: resolved_address, + blocked: false, + }) } } From c902077cf51076fee11712eb732dc8a8f786fc4b Mon Sep 17 00:00:00 2001 From: Angelo Kontaxis Date: Sun, 17 May 2026 18:59:56 +0100 Subject: [PATCH 174/211] fix: dont panic on hash missing when deleting files (#755) Signed-off-by: Zomatree --- .../daemons/crond/src/tasks/file_deletion.rs | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/crates/daemons/crond/src/tasks/file_deletion.rs b/crates/daemons/crond/src/tasks/file_deletion.rs index 912173b3f..42942bf35 100644 --- a/crates/daemons/crond/src/tasks/file_deletion.rs +++ b/crates/daemons/crond/src/tasks/file_deletion.rs @@ -11,22 +11,24 @@ pub async fn task(db: Database) -> Result<()> { let files = db.fetch_deleted_attachments().await?; for file in files { - let count = db - .count_file_hash_references(file.hash.as_ref().expect("no `hash` present")) - .await?; - - // No other files reference this file on disk anymore - if count <= 1 { - let file_hash = db - .fetch_attachment_hash(file.hash.as_ref().expect("no `hash` present")) + if let Some(hash) = &file.hash { + let count = db + .count_file_hash_references(hash) .await?; - // Delete from S3 - delete_from_s3(&file_hash.bucket_id, &file_hash.path).await?; + // No other files reference this file on disk anymore + if count <= 1 { + let file_hash = db + .fetch_attachment_hash(hash) + .await?; - // Delete the hash - db.delete_attachment_hash(&file_hash.id).await?; - info!("Deleted file hash {}", file_hash.id); + // Delete from S3 + delete_from_s3(&file_hash.bucket_id, &file_hash.path).await?; + + // Delete the hash + db.delete_attachment_hash(&file_hash.id).await?; + info!("Deleted file hash {}", file_hash.id); + } } // Delete the file From 6c920de03a275e73f1f632b6cd6bc924acb66324 Mon Sep 17 00:00:00 2001 From: "stoat-release[bot]" <245062572+stoat-release[bot]@users.noreply.github.com> Date: Sun, 17 May 2026 11:02:21 -0700 Subject: [PATCH 175/211] chore(main): release 0.13.5 (#759) * chore(main): release 0.13.5 * chore: update Cargo.lock Signed-off-by: github-actions[bot] --------- Signed-off-by: github-actions[bot] Co-authored-by: stoat-release[bot] <245062572+stoat-release[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] --- .release-please-manifest.json | 2 +- CHANGELOG.md | 7 +++++ Cargo.lock | 36 ++++++++++++------------- Cargo.toml | 20 +++++++------- crates/bonfire/Cargo.toml | 2 +- crates/core/coalesced/Cargo.toml | 2 +- crates/core/config/Cargo.toml | 2 +- crates/core/database/Cargo.toml | 2 +- crates/core/files/Cargo.toml | 2 +- crates/core/models/Cargo.toml | 2 +- crates/core/parser/Cargo.toml | 2 +- crates/core/permissions/Cargo.toml | 2 +- crates/core/presence/Cargo.toml | 2 +- crates/core/ratelimits/Cargo.toml | 2 +- crates/core/result/Cargo.toml | 2 +- crates/daemons/crond/Cargo.toml | 2 +- crates/daemons/pushd/Cargo.toml | 2 +- crates/daemons/voice-ingress/Cargo.toml | 2 +- crates/delta/Cargo.toml | 2 +- crates/services/autumn/Cargo.toml | 2 +- crates/services/gifbox/Cargo.toml | 2 +- crates/services/january/Cargo.toml | 2 +- version.txt | 2 +- 23 files changed, 55 insertions(+), 48 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 60633e475..429a83fc6 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.13.4" + ".": "0.13.5" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 18d08823f..1921756b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [0.13.5](https://github.com/stoatchat/stoatchat/compare/v0.13.4...v0.13.5) (2026-05-17) + + +### Bug Fixes + +* dont panic on hash missing when deleting files ([#755](https://github.com/stoatchat/stoatchat/issues/755)) ([c902077](https://github.com/stoatchat/stoatchat/commit/c902077cf51076fee11712eb732dc8a8f786fc4b)) + ## [0.13.4](https://github.com/stoatchat/stoatchat/compare/v0.13.3...v0.13.4) (2026-05-16) diff --git a/Cargo.lock b/Cargo.lock index e34841661..9bccaccde 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7513,7 +7513,7 @@ dependencies = [ [[package]] name = "revolt-autumn" -version = "0.13.4" +version = "0.13.5" dependencies = [ "axum", "axum-macros", @@ -7554,7 +7554,7 @@ dependencies = [ [[package]] name = "revolt-bonfire" -version = "0.13.4" +version = "0.13.5" dependencies = [ "async-channel 2.5.0", "async-std", @@ -7585,7 +7585,7 @@ dependencies = [ [[package]] name = "revolt-coalesced" -version = "0.13.4" +version = "0.13.5" dependencies = [ "indexmap 2.13.1", "lru", @@ -7594,7 +7594,7 @@ dependencies = [ [[package]] name = "revolt-config" -version = "0.13.4" +version = "0.13.5" dependencies = [ "async-std", "cached", @@ -7611,7 +7611,7 @@ dependencies = [ [[package]] name = "revolt-crond" -version = "0.13.4" +version = "0.13.5" dependencies = [ "futures-lite", "iso8601-timestamp", @@ -7631,7 +7631,7 @@ dependencies = [ [[package]] name = "revolt-database" -version = "0.13.4" +version = "0.13.5" dependencies = [ "amqprs", "async-lock 2.8.0", @@ -7682,7 +7682,7 @@ dependencies = [ [[package]] name = "revolt-delta" -version = "0.13.4" +version = "0.13.5" dependencies = [ "amqprs", "async-channel 2.5.0", @@ -7731,7 +7731,7 @@ dependencies = [ [[package]] name = "revolt-files" -version = "0.13.4" +version = "0.13.5" dependencies = [ "aes-gcm", "anyhow", @@ -7759,7 +7759,7 @@ dependencies = [ [[package]] name = "revolt-gifbox" -version = "0.13.4" +version = "0.13.5" dependencies = [ "axum", "axum-extra", @@ -7782,7 +7782,7 @@ dependencies = [ [[package]] name = "revolt-january" -version = "0.13.4" +version = "0.13.5" dependencies = [ "async-recursion", "axum", @@ -7812,7 +7812,7 @@ dependencies = [ [[package]] name = "revolt-models" -version = "0.13.4" +version = "0.13.5" dependencies = [ "indexmap 2.13.1", "iso8601-timestamp", @@ -7831,14 +7831,14 @@ dependencies = [ [[package]] name = "revolt-parser" -version = "0.13.4" +version = "0.13.5" dependencies = [ "logos", ] [[package]] name = "revolt-permissions" -version = "0.13.4" +version = "0.13.5" dependencies = [ "async-std", "async-trait", @@ -7853,7 +7853,7 @@ dependencies = [ [[package]] name = "revolt-presence" -version = "0.13.4" +version = "0.13.5" dependencies = [ "async-std", "log", @@ -7865,7 +7865,7 @@ dependencies = [ [[package]] name = "revolt-pushd" -version = "0.13.4" +version = "0.13.5" dependencies = [ "amqprs", "anyhow", @@ -7896,7 +7896,7 @@ dependencies = [ [[package]] name = "revolt-ratelimits" -version = "0.13.4" +version = "0.13.5" dependencies = [ "async-trait", "authifier", @@ -7913,7 +7913,7 @@ dependencies = [ [[package]] name = "revolt-result" -version = "0.13.4" +version = "0.13.5" dependencies = [ "axum", "log", @@ -7929,7 +7929,7 @@ dependencies = [ [[package]] name = "revolt-voice-ingress" -version = "0.13.4" +version = "0.13.5" dependencies = [ "amqprs", "async-std", diff --git a/Cargo.toml b/Cargo.toml index 5cb9b347a..3b4977849 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -192,13 +192,13 @@ futures-lite = "2.6.1" vergen = "7.5.0" # Local packages -revolt-coalesced = { version = "0.13.4", path = "crates/core/coalesced" } -revolt-config = { version = "0.13.4", path = "crates/core/config" } -revolt-database = { version = "0.13.4", path = "crates/core/database" } -revolt-files = { version = "0.13.4", path = "crates/core/files" } -revolt-models = { version = "0.13.4", path = "crates/core/models" } -revolt-parser = { version = "0.13.4", path = "crates/core/parser" } -revolt-permissions = { version = "0.13.4", path = "crates/core/permissions" } -revolt-presence = { version = "0.13.4", path = "crates/core/presence" } -revolt-ratelimits = { version = "0.13.4", path = "crates/core/ratelimits" } -revolt-result = { version = "0.13.4", path = "crates/core/result" } +revolt-coalesced = { version = "0.13.5", path = "crates/core/coalesced" } +revolt-config = { version = "0.13.5", path = "crates/core/config" } +revolt-database = { version = "0.13.5", path = "crates/core/database" } +revolt-files = { version = "0.13.5", path = "crates/core/files" } +revolt-models = { version = "0.13.5", path = "crates/core/models" } +revolt-parser = { version = "0.13.5", path = "crates/core/parser" } +revolt-permissions = { version = "0.13.5", path = "crates/core/permissions" } +revolt-presence = { version = "0.13.5", path = "crates/core/presence" } +revolt-ratelimits = { version = "0.13.5", path = "crates/core/ratelimits" } +revolt-result = { version = "0.13.5", path = "crates/core/result" } diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index b67410dde..c0fbe500c 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-bonfire" -version = "0.13.4" +version = "0.13.5" license = "AGPL-3.0-or-later" edition = "2021" publish = false diff --git a/crates/core/coalesced/Cargo.toml b/crates/core/coalesced/Cargo.toml index f8e3e0111..7c8bdcb97 100644 --- a/crates/core/coalesced/Cargo.toml +++ b/crates/core/coalesced/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-coalesced" -version = "0.13.4" +version = "0.13.5" edition = "2021" license = "MIT" authors = ["Paul Makles ", "Zomatree "] diff --git a/crates/core/config/Cargo.toml b/crates/core/config/Cargo.toml index df4cbf37a..c8be6a4f6 100644 --- a/crates/core/config/Cargo.toml +++ b/crates/core/config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-config" -version = "0.13.4" +version = "0.13.5" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index 987bfa86c..5031009de 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-database" -version = "0.13.4" +version = "0.13.5" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] diff --git a/crates/core/files/Cargo.toml b/crates/core/files/Cargo.toml index 1b0252a86..a17be124e 100644 --- a/crates/core/files/Cargo.toml +++ b/crates/core/files/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-files" -version = "0.13.4" +version = "0.13.5" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] diff --git a/crates/core/models/Cargo.toml b/crates/core/models/Cargo.toml index 2139f1592..75976fc5f 100644 --- a/crates/core/models/Cargo.toml +++ b/crates/core/models/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-models" -version = "0.13.4" +version = "0.13.5" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/core/parser/Cargo.toml b/crates/core/parser/Cargo.toml index 2f0d62786..e73e09940 100644 --- a/crates/core/parser/Cargo.toml +++ b/crates/core/parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-parser" -version = "0.13.4" +version = "0.13.5" edition = "2021" license = "MIT" authors = ["Zomatree ", "Paul Makles "] diff --git a/crates/core/permissions/Cargo.toml b/crates/core/permissions/Cargo.toml index c9e775fea..3ffbf1b11 100644 --- a/crates/core/permissions/Cargo.toml +++ b/crates/core/permissions/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-permissions" -version = "0.13.4" +version = "0.13.5" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/core/presence/Cargo.toml b/crates/core/presence/Cargo.toml index faa0f0a27..f48182f78 100644 --- a/crates/core/presence/Cargo.toml +++ b/crates/core/presence/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-presence" -version = "0.13.4" +version = "0.13.5" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] diff --git a/crates/core/ratelimits/Cargo.toml b/crates/core/ratelimits/Cargo.toml index bf367893b..7d5be0c19 100644 --- a/crates/core/ratelimits/Cargo.toml +++ b/crates/core/ratelimits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-ratelimits" -version = "0.13.4" +version = "0.13.5" edition = "2024" license = "MIT" authors = ["Zomatree ", "Paul Makles "] diff --git a/crates/core/result/Cargo.toml b/crates/core/result/Cargo.toml index 736fbd332..25caa4965 100644 --- a/crates/core/result/Cargo.toml +++ b/crates/core/result/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-result" -version = "0.13.4" +version = "0.13.5" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/daemons/crond/Cargo.toml b/crates/daemons/crond/Cargo.toml index f17e5e77a..8b1d0376f 100644 --- a/crates/daemons/crond/Cargo.toml +++ b/crates/daemons/crond/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-crond" -version = "0.13.4" +version = "0.13.5" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2021" diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index 94f610f78..c47eb11a5 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-pushd" -version = "0.13.4" +version = "0.13.5" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/crates/daemons/voice-ingress/Cargo.toml b/crates/daemons/voice-ingress/Cargo.toml index 50218d480..05ea4a60c 100644 --- a/crates/daemons/voice-ingress/Cargo.toml +++ b/crates/daemons/voice-ingress/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-voice-ingress" -version = "0.13.4" +version = "0.13.5" license = "AGPL-3.0-or-later" edition = "2021" publish = false diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index 431a80a66..a74c5547b 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-delta" -version = "0.13.4" +version = "0.13.5" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2018" diff --git a/crates/services/autumn/Cargo.toml b/crates/services/autumn/Cargo.toml index aa77a337f..c45d85227 100644 --- a/crates/services/autumn/Cargo.toml +++ b/crates/services/autumn/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-autumn" -version = "0.13.4" +version = "0.13.5" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/crates/services/gifbox/Cargo.toml b/crates/services/gifbox/Cargo.toml index 03e3ee6e2..5fbcba088 100644 --- a/crates/services/gifbox/Cargo.toml +++ b/crates/services/gifbox/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-gifbox" -version = "0.13.4" +version = "0.13.5" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/crates/services/january/Cargo.toml b/crates/services/january/Cargo.toml index d8f1dac93..55ae526ed 100644 --- a/crates/services/january/Cargo.toml +++ b/crates/services/january/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-january" -version = "0.13.4" +version = "0.13.5" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/version.txt b/version.txt index dffa40ec3..c37136a84 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.13.4 +0.13.5 From 298742dbad4eafae356f976c56b9db23904b0c3a Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Sun, 17 May 2026 14:41:44 -0500 Subject: [PATCH 176/211] fix: include `minio` region as tests need it (#761) --- compose.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/compose.yml b/compose.yml index bf2c2ca1f..b7e73689d 100644 --- a/compose.yml +++ b/compose.yml @@ -34,6 +34,7 @@ services: environment: MINIO_ROOT_USER: minioautumn MINIO_ROOT_PASSWORD: minioautumn + MINIO_REGION: minio volumes: - ./.data/minio:/data ports: From 26a8692677c5eeeff37f35f1f267f2ae3eb0d81b Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Sun, 17 May 2026 14:54:57 -0500 Subject: [PATCH 177/211] ci: ignore test errors on main (#763) --- .github/workflows/rust.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/rust.yaml b/.github/workflows/rust.yaml index 08e210a3f..3b7a78d22 100644 --- a/.github/workflows/rust.yaml +++ b/.github/workflows/rust.yaml @@ -37,6 +37,7 @@ jobs: - name: Reference Test env: TEST_DB: REFERENCE + continue-on-error: ${{ github.ref_name == 'main' }} run: | mise test @@ -44,6 +45,7 @@ jobs: env: TEST_DB: MONGODB MONGODB: mongodb://localhost + continue-on-error: ${{ github.ref_name == 'main' }} run: | mise test From 494c8b7cabaae2a51039a7a5b559d5e2e5279554 Mon Sep 17 00:00:00 2001 From: Tom Date: Mon, 18 May 2026 10:51:19 -0700 Subject: [PATCH 178/211] fix: Use proper headers to determine IP when not behind cloudflare (#764) Signed-off-by: IAmTomahawkx --- crates/core/ratelimits/src/rocket.rs | 6 +++--- crates/delta/src/main.rs | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/crates/core/ratelimits/src/rocket.rs b/crates/core/ratelimits/src/rocket.rs index 046317bd4..f790abb9f 100644 --- a/crates/core/ratelimits/src/rocket.rs +++ b/crates/core/ratelimits/src/rocket.rs @@ -1,12 +1,12 @@ use async_trait::async_trait; use log::info; +use revolt_config::config; use rocket::fairing::{Fairing, Info, Kind}; use rocket::http::uri::Origin; use rocket::http::{Method, Status}; use rocket::request::{FromRequest, Outcome}; use rocket::serde::json::Json; use rocket::{Data, Request, Response, State}; -use revolt_config::config; use revolt_rocket_okapi::r#gen::OpenApiGenerator; use revolt_rocket_okapi::request::{OpenApiFromRequest, RequestHeaderInput}; @@ -28,8 +28,8 @@ pub type RatelimitStorage = crate::ratelimiter::RatelimitStorage) -> String { request - .remote() - .map(|x| x.ip().to_string()) + .client_ip() + .map(|r| r.to_string()) .unwrap_or_default() } diff --git a/crates/delta/src/main.rs b/crates/delta/src/main.rs index 15aa2d3b7..41f8fc026 100644 --- a/crates/delta/src/main.rs +++ b/crates/delta/src/main.rs @@ -152,6 +152,7 @@ pub async fn web() -> Rocket { limits: rocket::data::Limits::default().limit("string", 5.megabytes()), address: Ipv4Addr::new(0, 0, 0, 0).into(), port: 14702, + ip_header: Some("X-Forwarded-For".into()), ..Default::default() }) } From 2871632382395cb20cbe0047c542d3ac31ff3f03 Mon Sep 17 00:00:00 2001 From: Tom Date: Mon, 18 May 2026 10:56:01 -0700 Subject: [PATCH 179/211] fix: voice ingress crashing due to new Result in AMQP::new_auto() (#765) Signed-off-by: IAmTomahawkx --- crates/daemons/voice-ingress/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/daemons/voice-ingress/src/main.rs b/crates/daemons/voice-ingress/src/main.rs index 45191c2c5..727e1a259 100644 --- a/crates/daemons/voice-ingress/src/main.rs +++ b/crates/daemons/voice-ingress/src/main.rs @@ -13,7 +13,7 @@ mod guard; async fn main() -> Result<(), rocket::Error> { revolt_config::configure!(voice_ingress); - let amqp = AMQP::new_auto().await; + let amqp = AMQP::new_auto().await.unwrap(); let database = DatabaseInfo::Auto.connect().await.unwrap(); let voice_client = VoiceClient::from_revolt_config().await; From acbc087982e9aeb05cabc5ab4c9b1291f67490ad Mon Sep 17 00:00:00 2001 From: Tom Date: Mon, 18 May 2026 10:57:23 -0700 Subject: [PATCH 180/211] feat: Update FCM payload for android notifications (#766) * feat: modify fcm payload to jens will Signed-off-by: IAmTomahawkx * fix: add message id Signed-off-by: IAmTomahawkx * fix: rename field Signed-off-by: IAmTomahawkx * fix: whitespace Signed-off-by: IAmTomahawkx --------- Signed-off-by: IAmTomahawkx --- .../pushd/src/consumers/outbound/fcm.rs | 45 +++++++------------ 1 file changed, 16 insertions(+), 29 deletions(-) diff --git a/crates/daemons/pushd/src/consumers/outbound/fcm.rs b/crates/daemons/pushd/src/consumers/outbound/fcm.rs index 9ff70fc82..4ea21e0b1 100644 --- a/crates/daemons/pushd/src/consumers/outbound/fcm.rs +++ b/crates/daemons/pushd/src/consumers/outbound/fcm.rs @@ -11,7 +11,6 @@ use fcm_v1::{ }; use revolt_config::config; use revolt_database::{events::rabbit::*, Database}; -use revolt_models::v0::{Channel, PushNotification}; use serde_json::Value; /// Custom notification data @@ -31,10 +30,12 @@ pub enum NotificationData { image: Option, }, Message { - title: String, + message: String, body: String, image: String, - tag: String, + channel: String, + author: String, + author_name: String, }, DmCallStartEnd { initiator_id: String, @@ -81,15 +82,19 @@ impl NotificationData { } } NotificationData::Message { - title, + message, body, image, - tag, + channel, + author, + author_name, } => { - data.insert("title".to_string(), Value::String(title)); + data.insert("message".to_string(), Value::String(message)); data.insert("body".to_string(), Value::String(body)); data.insert("image".to_string(), Value::String(image)); - data.insert("tag".to_string(), Value::String(tag)); + data.insert("channel".to_string(), Value::String(channel)); + data.insert("author".to_string(), Value::String(author)); + data.insert("author_name".to_string(), Value::String(author_name)); } NotificationData::DmCallStartEnd { initiator_id, @@ -115,26 +120,6 @@ pub struct FcmOutboundConsumer { client: Client, } -impl FcmOutboundConsumer { - fn format_title(&self, notification: &PushNotification) -> String { - // ideally this changes depending on context - // in a server, it would look like "Sendername, #channelname in servername" - // in a group, it would look like "Sendername in groupname" - // in a dm it should just be "Sendername". - // not sure how feasible all those are given the PushNotification object as it currently stands. - - #[allow(deprecated)] - match ¬ification.channel { - Channel::DirectMessage { .. } => notification.author.clone(), - Channel::Group { name, .. } => format!("{}, #{}", notification.author, name), - Channel::TextChannel { name, .. } => { - format!("{} in #{}", notification.author, name) - } - _ => "Unknown".to_string(), - } - } -} - impl FcmOutboundConsumer { pub async fn new(db: Database) -> Result { let config = revolt_config::config().await; @@ -244,10 +229,12 @@ impl FcmOutboundConsumer { PayloadKind::MessageNotification(alert) => { let data = NotificationData::Message { - title: self.format_title(&alert), + message: alert.message.id, body: alert.body, image: alert.icon, - tag: alert.tag, + channel: alert.message.channel, + author: alert.message.author, + author_name: alert.author, }; let msg = Message { From af0d8aad14dc68d88159d0e1c714077d362e21e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0spik?= Date: Tue, 19 May 2026 00:51:43 +0300 Subject: [PATCH 181/211] feat: user slowmode events (#760) * feat: user slowmode events Signed-off-by: ispik * fix: remove debug print statement for slowmodes Signed-off-by: ispik * refactor: Send user slowmodes as websocket connects instead of trying to send it in ready payload Signed-off-by: ispik * refactor: optimize user slowmode handling with bulk operations Signed-off-by: ispik * chore: specify release version Release-As: 0.13.6 --------- Signed-off-by: ispik --- crates/bonfire/src/events/impl.rs | 1 + crates/bonfire/src/websocket.rs | 52 ++++++++- crates/core/database/src/events/client.rs | 100 ++++++++++++++---- crates/core/models/src/v0/channels.rs | 6 ++ .../delta/src/routes/channels/message_send.rs | 31 ++++++ 5 files changed, 166 insertions(+), 24 deletions(-) diff --git a/crates/bonfire/src/events/impl.rs b/crates/bonfire/src/events/impl.rs index 121135376..96a0f2ab0 100644 --- a/crates/bonfire/src/events/impl.rs +++ b/crates/bonfire/src/events/impl.rs @@ -1,6 +1,7 @@ use std::collections::{HashMap, HashSet}; use futures::future::join_all; +use redis_kiss::AsyncCommands; use revolt_database::{ events::client::{EventV1, ReadyPayloadFields}, util::permissions::DatabasePermissionQuery, diff --git a/crates/bonfire/src/websocket.rs b/crates/bonfire/src/websocket.rs index b5611bd05..ee5512896 100644 --- a/crates/bonfire/src/websocket.rs +++ b/crates/bonfire/src/websocket.rs @@ -13,7 +13,7 @@ use futures::{ stream::{SplitSink, SplitStream}, FutureExt, SinkExt, StreamExt, TryStreamExt, }; -use redis_kiss::{PayloadType, REDIS_PAYLOAD_TYPE, REDIS_URI}; +use redis_kiss::{get_connection, AsyncCommands, PayloadType, REDIS_PAYLOAD_TYPE, REDIS_URI}; use revolt_config::report_internal_error; use revolt_database::{ events::{client::EventV1, server::ClientMessage}, @@ -32,6 +32,7 @@ use sentry::Level; use crate::config::{ProtocolConfiguration, WebsocketHandshakeCallback}; use crate::events::state::{State, SubscriptionStateChange}; +use revolt_models::v0; type WsReader = SplitStream>; type WsWriter = SplitSink, async_tungstenite::tungstenite::Message>; @@ -128,6 +129,14 @@ pub async fn client(db: &'static Database, stream: TcpStream, addr: SocketAddr) return; } + let slowmodes = fetch_user_slowmodes(&user_id).await.unwrap_or_default(); + if !slowmodes.is_empty() { + let event = EventV1::UserSlowmodes { slowmodes }; + if report_internal_error!(write.send(config.encode(&event)).await).is_err() { + return; + } + } + // Create presence session. let (first_session, session_id) = create_session(&user_id, 0).await; @@ -527,4 +536,43 @@ async fn worker( } } } -} \ No newline at end of file +} + +async fn fetch_user_slowmodes(user_id: &str) -> Option> { + let mut conn = get_connection().await.ok()?.into_inner(); + let idx_key = format!("slowmode_idx:{}", user_id); + + let channel_ids: Vec = conn.smembers(&idx_key).await.unwrap_or_default(); + if channel_ids.is_empty() { + return Some(vec![]); + } + + // Bulk fetch all TTLs in one round trip + let mut pipe = redis_kiss::redis::pipe(); + for channel_id in &channel_ids { + pipe.ttl(format!("slowmode:{}:{}", user_id, channel_id)); + } + let ttls: Vec = pipe.query_async(&mut conn).await.unwrap_or_default(); + + // Partition into alive/expired in one pass + let mut slowmodes = vec![]; + let mut expired = vec![]; + for (channel_id, ttl) in channel_ids.iter().zip(ttls.iter()) { + if *ttl > 0 { + slowmodes.push(v0::ChannelSlowmode { + channel_id: channel_id.clone(), + duration: *ttl as u64, + retry_after: *ttl as u64, + }); + } else { + expired.push(channel_id.as_str()); + } + } + + // Bulk remove all expired members in one SREM call + if !expired.is_empty() { + conn.srem::<_, _, ()>(&idx_key, expired).await.ok(); + } + + Some(slowmodes) +} diff --git a/crates/core/database/src/events/client.rs b/crates/core/database/src/events/client.rs index 38c6f9417..31864cee3 100644 --- a/crates/core/database/src/events/client.rs +++ b/crates/core/database/src/events/client.rs @@ -3,7 +3,12 @@ use revolt_result::Error; use serde::{Deserialize, Serialize}; use revolt_models::v0::{ - AppendMessage, Channel, ChannelUnread, ChannelVoiceState, Emoji, FieldsChannel, FieldsMember, FieldsMessage, FieldsRole, FieldsServer, FieldsUser, FieldsWebhook, Member, MemberCompositeKey, Message, PartialChannel, PartialEmoji, PartialMember, PartialMessage, PartialRole, PartialServer, PartialUser, PartialUserVoiceState, PartialWebhook, PolicyChange, RemovalIntention, Report, Server, User, UserSettings, UserVoiceState, Webhook + AppendMessage, Channel, ChannelSlowmode, ChannelUnread, ChannelVoiceState, Emoji, + FieldsChannel, FieldsMember, FieldsMessage, FieldsRole, FieldsServer, FieldsUser, + FieldsWebhook, Member, MemberCompositeKey, Message, PartialChannel, PartialEmoji, + PartialMember, PartialMessage, PartialRole, PartialServer, PartialUser, PartialUserVoiceState, + PartialWebhook, PolicyChange, RemovalIntention, Report, Server, User, UserSettings, + UserVoiceState, Webhook, }; use crate::Database; @@ -51,9 +56,13 @@ impl Default for ReadyPayloadFields { #[serde(tag = "type")] pub enum EventV1 { /// Multiple events - Bulk { v: Vec }, + Bulk { + v: Vec, + }, /// Error event - Error { data: Error }, + Error { + data: Error, + }, /// Successfully authenticated Authenticated, @@ -84,7 +93,9 @@ pub enum EventV1 { }, /// Ping response - Pong { data: Ping }, + Pong { + data: Ping, + }, /// New message Message(Message), @@ -105,7 +116,10 @@ pub enum EventV1 { }, /// Delete message - MessageDelete { id: String, channel: String }, + MessageDelete { + id: String, + channel: String, + }, /// New reaction to a message MessageReact { @@ -131,7 +145,10 @@ pub enum EventV1 { }, /// Bulk delete messages - BulkMessageDelete { channel: String, ids: Vec }, + BulkMessageDelete { + channel: String, + ids: Vec, + }, /// New server ServerCreate { @@ -139,7 +156,7 @@ pub enum EventV1 { server: Server, channels: Vec, emojis: Vec, - voice_states: Vec + voice_states: Vec, }, /// Update existing server @@ -151,7 +168,9 @@ pub enum EventV1 { }, /// Delete server - ServerDelete { id: String }, + ServerDelete { + id: String, + }, /// Update existing server member ServerMemberUpdate { @@ -187,10 +206,16 @@ pub enum EventV1 { }, /// Server role deleted - ServerRoleDelete { id: String, role_id: String }, + ServerRoleDelete { + id: String, + role_id: String, + }, /// Server roles ranks updated - ServerRoleRanksUpdate { id: String, ranks: Vec }, + ServerRoleRanksUpdate { + id: String, + ranks: Vec, + }, /// Update existing user UserUpdate { @@ -202,9 +227,15 @@ pub enum EventV1 { }, /// Relationship with another user changed - UserRelationship { id: String, user: User }, + UserRelationship { + id: String, + user: User, + }, /// Settings updated remotely - UserSettingsUpdate { id: String, update: UserSettings }, + UserSettingsUpdate { + id: String, + update: UserSettings, + }, /// User has been platform banned or deleted their account /// @@ -215,7 +246,10 @@ pub enum EventV1 { /// - Server Memberships /// /// User flags are specified to explain why a wipe is occurring though not all reasons will necessarily ever appear. - UserPlatformWipe { user_id: String, flags: i32 }, + UserPlatformWipe { + user_id: String, + flags: i32, + }, /// New emoji EmojiCreate(Emoji), @@ -226,7 +260,9 @@ pub enum EventV1 { }, /// Delete emoji - EmojiDelete { id: String }, + EmojiDelete { + id: String, + }, /// New report ReportCreate(Report), @@ -242,19 +278,33 @@ pub enum EventV1 { }, /// Delete channel - ChannelDelete { id: String }, + ChannelDelete { + id: String, + }, /// User joins a group - ChannelGroupJoin { id: String, user: String }, + ChannelGroupJoin { + id: String, + user: String, + }, /// User leaves a group - ChannelGroupLeave { id: String, user: String }, + ChannelGroupLeave { + id: String, + user: String, + }, /// User started typing in a channel - ChannelStartTyping { id: String, user: String }, + ChannelStartTyping { + id: String, + user: String, + }, /// User stopped typing in a channel - ChannelStopTyping { id: String, user: String }, + ChannelStopTyping { + id: String, + user: String, + }, /// User acknowledged message in channel ChannelAck { @@ -274,7 +324,9 @@ pub enum EventV1 { }, /// Delete webhook - WebhookDelete { id: String }, + WebhookDelete { + id: String, + }, /// Auth events Auth(AuthifierEvent), @@ -292,7 +344,7 @@ pub enum EventV1 { user: String, from: String, to: String, - state: UserVoiceState + state: UserVoiceState, }, UserVoiceStateUpdate { id: String, @@ -304,7 +356,11 @@ pub enum EventV1 { from: String, to: String, token: String, - } + }, + /// User's active slowmodes + UserSlowmodes { + slowmodes: Vec, + }, } impl EventV1 { diff --git a/crates/core/models/src/v0/channels.rs b/crates/core/models/src/v0/channels.rs index d9fe8e14d..faddee749 100644 --- a/crates/core/models/src/v0/channels.rs +++ b/crates/core/models/src/v0/channels.rs @@ -314,6 +314,12 @@ auto_derived!( /// Only used when the user is the first one connected. pub recipients: Option>, } + + pub struct ChannelSlowmode { + pub channel_id: String, + pub duration: u64, + pub retry_after: u64, + } ); impl Channel { diff --git a/crates/delta/src/routes/channels/message_send.rs b/crates/delta/src/routes/channels/message_send.rs index 7406b6058..e6551d0c4 100644 --- a/crates/delta/src/routes/channels/message_send.rs +++ b/crates/delta/src/routes/channels/message_send.rs @@ -1,12 +1,14 @@ use std::time::Duration; use redis_kiss::{get_connection, redis, AsyncCommands}; +use revolt_database::events::client::EventV1; use revolt_database::util::permissions::DatabasePermissionQuery; use revolt_database::{ util::idempotency::IdempotencyKey, util::reference::Reference, Database, User, }; use revolt_database::{Channel, Interactions, Message, AMQP}; use revolt_models::v0; +use revolt_models::v0::ChannelSlowmode; use revolt_permissions::PermissionQuery; use revolt_permissions::{calculate_channel_permissions, ChannelPermission}; use revolt_result::{create_error, Result}; @@ -84,6 +86,16 @@ pub async fn message_send( .await .unwrap_or(None); + if set_result.is_some() { + let idx_key = format!("slowmode_idx:{}", user.id); + conn.sadd::<_, _, ()>(&idx_key, channel_id.as_str()) + .await + .ok(); + conn.expire::<_, ()>(&idx_key, *channel_slowmode as usize) + .await + .ok(); + } + // If `set_result` is None, the `NX` condition failed because the key already exists. // This means the user is currently in slowmode. if set_result.is_none() { @@ -92,10 +104,29 @@ pub async fn message_send( // Redis returns positive integers for valid TTLs if ttl > 0 { + EventV1::UserSlowmodes { + slowmodes: vec![ChannelSlowmode { + channel_id: channel_id.to_string(), + duration: *channel_slowmode, + retry_after: ttl as u64, + }], + } + .private(user.id.clone()) + .await; return Err(create_error!(InSlowmode { retry_after: ttl as u64 })); } + } else { + EventV1::UserSlowmodes { + slowmodes: vec![ChannelSlowmode { + channel_id: channel_id.to_string(), + duration: *channel_slowmode, + retry_after: *channel_slowmode, + }], + } + .private(user.id.clone()) + .await; } } // If Redis connection fails, just skip the slowmode check From 018afaf38f6330d92dad2a68b640c0cb3f6b639a Mon Sep 17 00:00:00 2001 From: Tom Date: Mon, 18 May 2026 15:11:44 -0700 Subject: [PATCH 182/211] fix: set env var for publishing crates (#768) * fix: set env var for publishing crates Signed-off-by: IAmTomahawkx Release-As: 0.13.6 --- .github/workflows/publish-crates.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/publish-crates.yml b/.github/workflows/publish-crates.yml index ce02d8418..5e35d3580 100644 --- a/.github/workflows/publish-crates.yml +++ b/.github/workflows/publish-crates.yml @@ -21,4 +21,6 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} - name: Publish + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} run: mise publish --workspace From 5b1985381ae829a92c80a19e91a414cd9dc4de93 Mon Sep 17 00:00:00 2001 From: Angelo Kontaxis Date: Mon, 18 May 2026 23:46:17 +0100 Subject: [PATCH 183/211] chore: switch to lapin (#767) * chore: begin switching to lapin fully Signed-off-by: Zomatree * chore: update rest of pushd to lapin Signed-off-by: Zomatree * chore: cleanup code Signed-off-by: Zomatree * chore: cleanup code Signed-off-by: Zomatree * fix: github webui sucks Signed-off-by: IAmTomahawkx --------- Signed-off-by: Zomatree Signed-off-by: Tom Signed-off-by: IAmTomahawkx Co-authored-by: Tom Release-As: 0.13.6 --- Cargo.lock | 41 +-- Cargo.toml | 1 - crates/core/database/Cargo.toml | 2 +- crates/core/database/src/amqp/amqp.rs | 301 ++++++++---------- crates/daemons/crond/src/tasks/acks.rs | 38 ++- crates/daemons/pushd/Cargo.toml | 2 +- .../pushd/src/consumers/inbound/ack.rs | 141 ++++---- .../pushd/src/consumers/inbound/dm_call.rs | 144 +++------ .../src/consumers/inbound/fr_accepted.rs | 138 +++----- .../src/consumers/inbound/fr_received.rs | 138 +++----- .../pushd/src/consumers/inbound/generic.rs | 138 +++----- .../pushd/src/consumers/inbound/internal.rs | 53 --- .../src/consumers/inbound/mass_mention.rs | 151 +++------ .../pushd/src/consumers/inbound/message.rs | 145 +++------ .../pushd/src/consumers/inbound/mod.rs | 1 - .../pushd/src/consumers/outbound/apn.rs | 159 +++++---- .../pushd/src/consumers/outbound/fcm.rs | 111 +++---- .../pushd/src/consumers/outbound/vapid.rs | 149 ++++----- crates/daemons/pushd/src/main.rs | 249 +++++++++------ crates/daemons/pushd/src/utils/consumer.rs | 91 ++++++ crates/daemons/pushd/src/utils/mod.rs | 3 + crates/daemons/voice-ingress/Cargo.toml | 3 - crates/daemons/voice-ingress/src/main.rs | 2 +- crates/delta/Cargo.toml | 2 +- crates/delta/src/main.rs | 37 +-- crates/delta/src/util/test.rs | 18 +- 26 files changed, 923 insertions(+), 1335 deletions(-) delete mode 100644 crates/daemons/pushd/src/consumers/inbound/internal.rs create mode 100644 crates/daemons/pushd/src/utils/consumer.rs diff --git a/Cargo.lock b/Cargo.lock index 9bccaccde..c65f954ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -174,31 +174,6 @@ dependencies = [ "url", ] -[[package]] -name = "amqp_serde" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5f450f572a1ec4cdb4af7af09cbd0c7c3e1b9da2bfc7414c059a780993a8e16" -dependencies = [ - "bytes 1.11.1", - "serde", - "serde_bytes", -] - -[[package]] -name = "amqprs" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f1b4afcbd862e16c272b7625b6b057930b052d63c720bc90f6afab0d9abe8a8" -dependencies = [ - "amqp_serde", - "async-trait", - "bytes 1.11.1", - "serde", - "serde_bytes_ng", - "tokio 1.51.0", -] - [[package]] name = "android_system_properties" version = "0.1.5" @@ -7633,7 +7608,6 @@ dependencies = [ name = "revolt-database" version = "0.13.5" dependencies = [ - "amqprs", "async-lock 2.8.0", "async-recursion", "async-std", @@ -7648,6 +7622,7 @@ dependencies = [ "indexmap 2.13.1", "isahc", "iso8601-timestamp", + "lapin", "linkify", "livekit-api", "livekit-protocol", @@ -7684,7 +7659,6 @@ dependencies = [ name = "revolt-delta" version = "0.13.5" dependencies = [ - "amqprs", "async-channel 2.5.0", "async-std", "authifier", @@ -7694,6 +7668,7 @@ dependencies = [ "futures", "impl_ops", "iso8601-timestamp", + "lapin", "lettre", "linkify", "livekit-api", @@ -7867,7 +7842,6 @@ dependencies = [ name = "revolt-pushd" version = "0.13.5" dependencies = [ - "amqprs", "anyhow", "async-trait", "authifier", @@ -7875,6 +7849,7 @@ dependencies = [ "fcm_v1", "isahc", "iso8601-timestamp", + "lapin", "log", "pretty_env_logger", "redis-kiss", @@ -7931,7 +7906,6 @@ dependencies = [ name = "revolt-voice-ingress" version = "0.13.5" dependencies = [ - "amqprs", "async-std", "chrono", "futures", @@ -8987,15 +8961,6 @@ dependencies = [ "serde_core", ] -[[package]] -name = "serde_bytes_ng" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdb0ebce8684e2253f964e8b6ce51f0ccc6666bbb448fb4a6788088bda6544b6" -dependencies = [ - "serde", -] - [[package]] name = "serde_core" version = "1.0.228" diff --git a/Cargo.toml b/Cargo.toml index 3b4977849..3b2b92fa2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -159,7 +159,6 @@ opentelemetry-appender-tracing = "0.31.1" authifier = "1.0.16" # RabbitMQ -amqprs = "1.7.0" lapin = "4.7.1" # Voice diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index 5031009de..dc213fd07 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -95,7 +95,7 @@ revolt_rocket_okapi = { workspace = true, optional = true } authifier = { workspace = true } # RabbitMQ -amqprs = { workspace = true } +lapin = { workspace = true, features = ["tokio"] } # Voice livekit-api = { workspace = true, features = ["rustls-tls-native-roots"], optional = true } diff --git a/crates/core/database/src/amqp/amqp.rs b/crates/core/database/src/amqp/amqp.rs index e0c644e51..b0e5e1750 100644 --- a/crates/core/database/src/amqp/amqp.rs +++ b/crates/core/database/src/amqp/amqp.rs @@ -1,103 +1,77 @@ use std::collections::HashSet; +use std::sync::Arc; use crate::events::rabbit::*; use crate::User; -use amqprs::channel::{ - BasicPublishArguments, ExchangeDeclareArguments, ExchangeType, QueueBindArguments, - QueueDeclareArguments, +use lapin::{ + options::BasicPublishOptions, + protocol::basic::AMQPProperties, + types::{AMQPValue, FieldTable}, + Channel, Connection, ConnectionProperties, Error as AMQPError, }; -use amqprs::connection::OpenConnectionArguments; -use amqprs::{channel::Channel, connection::Connection, error::Error as AMQPError}; -use amqprs::{BasicProperties, FieldTable}; use revolt_models::v0::PushNotification; use revolt_presence::filter_online; +use revolt_result::Result; use serde_json::to_string; #[derive(Clone)] pub struct AMQP { + friend_request_accepted: Arc, + friend_request_received: Arc, + generic_message: Arc, + message_sent: Arc, + mass_mention_message_sent: Arc, + ack_notification_message: Arc, + dm_call_updated: Arc, + process_ack: Arc, #[allow(unused)] - connection: Connection, - channel: Channel, + connection: Arc, } impl AMQP { - pub fn new(connection: Connection, channel: Channel) -> AMQP { - AMQP { + pub async fn new(connection: Arc) -> Self { + Self { + friend_request_accepted: Self::create_channel(&connection).await, + friend_request_received: Self::create_channel(&connection).await, + generic_message: Self::create_channel(&connection).await, + message_sent: Self::create_channel(&connection).await, + mass_mention_message_sent: Self::create_channel(&connection).await, + ack_notification_message: Self::create_channel(&connection).await, + dm_call_updated: Self::create_channel(&connection).await, + process_ack: Self::create_channel(&connection).await, connection, - channel, } } - pub async fn new_auto() -> revolt_result::Result { + pub async fn new_auto() -> Self { let config = revolt_config::config().await; - let connection = Connection::open(&OpenConnectionArguments::new( - &config.rabbit.host, - config.rabbit.port, - &config.rabbit.username, - &config.rabbit.password, - )) - .await - .expect("Failed to connect to RabbitMQ"); - - let channel = connection - .open_channel(None) + let connection = Arc::new( + Connection::connect( + &format!( + "amqp://{}:{}@{}:{}", + &config.rabbit.username, + &config.rabbit.password, + &config.rabbit.host, + &config.rabbit.port, + ), + ConnectionProperties::default(), + ) .await - .expect("Failed to open RabbitMQ channel"); - - let mut resp = AMQP::new(connection, channel); - //resp.configure_channels().await?; - Ok(resp) - } + .expect("Failed to connect to RabbitMQ"), + ); - pub async fn repoen_channel(&mut self) { - self.channel = self - .connection - .open_channel(None) - .await - .expect("Failed to open RabbitMQ channel"); + Self::new(connection).await } - pub async fn configure_channels(&mut self) -> revolt_result::Result<()> { - let config = revolt_config::config().await; - - if !self.channel.is_open() { - self.repoen_channel().await; - } - - self.channel - .exchange_declare( - ExchangeDeclareArguments::new( - &config.rabbit.default_exchange, - &ExchangeType::Topic.to_string(), - ) - .durable(true) - .finish(), - ) - .await - .expect("Failed to declare exchange"); - - // Configure acks channel & routing - self.channel - .queue_declare( - QueueDeclareArguments::new(&config.rabbit.queues.acks) - .durable(true) - .no_wait(true) - .finish(), - ) - .await - .expect("Failed to bind queue"); - - self.channel - .queue_bind(QueueBindArguments::new( - &config.rabbit.queues.acks, - &config.rabbit.default_exchange, - &config.rabbit.queues.acks, - )) - .await - .expect("Failed to bind channel"); - Ok(()) + async fn create_channel(connection: &Connection) -> Arc { + Arc::new( + connection + .create_channel() + .await + .expect("Failed to create channel"), + ) } pub async fn friend_request_accepted( @@ -117,19 +91,20 @@ impl AMQP { config.pushd.get_fr_accepted_routing_key(), payload ); - self.channel + + self.friend_request_accepted .basic_publish( - BasicProperties::default() - .with_content_type("application/json") - .with_persistence(true) - .finish(), - payload.into(), - BasicPublishArguments::new( - &config.pushd.exchange, - &config.pushd.get_fr_accepted_routing_key(), - ), + config.pushd.exchange.clone().into(), + config.pushd.get_fr_accepted_routing_key().into(), + BasicPublishOptions::default(), + payload.as_bytes(), + AMQPProperties::default() + .with_content_type("application/json".into()) + .with_delivery_mode(2), ) - .await + .await?; + + Ok(()) } pub async fn friend_request_received( @@ -150,19 +125,19 @@ impl AMQP { payload ); - self.channel + self.friend_request_received .basic_publish( - BasicProperties::default() - .with_content_type("application/json") - .with_persistence(true) - .finish(), - payload.into(), - BasicPublishArguments::new( - &config.pushd.exchange, - &config.pushd.get_fr_received_routing_key(), - ), + config.pushd.exchange.clone().into(), + config.pushd.get_fr_received_routing_key().into(), + BasicPublishOptions::default(), + payload.as_bytes(), + AMQPProperties::default() + .with_content_type("application/json".into()) + .with_delivery_mode(2), ) - .await + .await?; + + Ok(()) } pub async fn generic_message( @@ -187,19 +162,19 @@ impl AMQP { payload ); - self.channel + self.generic_message .basic_publish( - BasicProperties::default() - .with_content_type("application/json") - .with_persistence(true) - .finish(), - payload.into(), - BasicPublishArguments::new( - &config.pushd.exchange, - &config.pushd.get_generic_routing_key(), - ), + config.pushd.exchange.clone().into(), + config.pushd.get_generic_routing_key().into(), + BasicPublishOptions::default(), + payload.as_bytes(), + AMQPProperties::default() + .with_content_type("application/json".into()) + .with_delivery_mode(2), ) - .await + .await?; + + Ok(()) } pub async fn message_sent( @@ -230,19 +205,19 @@ impl AMQP { payload ); - self.channel + self.message_sent .basic_publish( - BasicProperties::default() - .with_content_type("application/json") - .with_persistence(true) - .finish(), - payload.into(), - BasicPublishArguments::new( - &config.pushd.exchange, - &config.pushd.get_message_routing_key(), - ), + config.pushd.exchange.clone().into(), + config.pushd.get_message_routing_key().into(), + BasicPublishOptions::default(), + payload.as_bytes(), + AMQPProperties::default() + .with_content_type("application/json".into()) + .with_delivery_mode(2), ) - .await + .await?; + + Ok(()) } pub async fn mass_mention_message_sent( @@ -265,16 +240,19 @@ impl AMQP { routing_key, payload ); - self.channel + self.mass_mention_message_sent .basic_publish( - BasicProperties::default() - .with_content_type("application/json") - .with_persistence(true) - .finish(), - payload.into(), - BasicPublishArguments::new(&config.pushd.exchange, routing_key.as_str()), + config.pushd.exchange.clone().into(), + routing_key.into(), + BasicPublishOptions::default(), + payload.as_bytes(), + AMQPProperties::default() + .with_content_type("application/json".into()) + .with_delivery_mode(2), ) - .await + .await?; + + Ok(()) } /// # Sends an ack to pushd to update badges on iPhones. @@ -299,23 +277,25 @@ impl AMQP { config.pushd.ack_queue, payload ); - let mut headers = FieldTable::new(); + let mut headers = FieldTable::default(); headers.insert( - "x-deduplication-header".try_into().unwrap(), - format!("{}-{}", &user_id, &channel_id).into(), + "x-deduplication-header".into(), + AMQPValue::LongString(format!("{}-{}", &user_id, &channel_id).into()), ); - self.channel + self.ack_notification_message .basic_publish( - BasicProperties::default() - .with_content_type("application/json") - .with_persistence(true) - //.with_headers(headers) - .finish(), - payload.into(), - BasicPublishArguments::new(&config.pushd.exchange, &config.pushd.ack_queue), + config.pushd.exchange.clone().into(), + config.pushd.ack_queue.into(), + BasicPublishOptions::default(), + payload.as_bytes(), + AMQPProperties::default() + .with_content_type("application/json".into()) + .with_delivery_mode(2), ) - .await + .await?; + + Ok(()) } /// # DM Call Update @@ -349,19 +329,19 @@ impl AMQP { payload ); - self.channel + self.dm_call_updated .basic_publish( - BasicProperties::default() - .with_content_type("application/json") - .with_persistence(true) - .finish(), - payload.into(), - BasicPublishArguments::new( - &config.pushd.exchange, - &config.pushd.get_dm_call_routing_key(), - ), + config.pushd.exchange.clone().into(), + config.pushd.get_dm_call_routing_key().into(), + BasicPublishOptions::default(), + payload.as_bytes(), + AMQPProperties::default() + .with_content_type("application/json".into()) + .with_delivery_mode(2), ) - .await + .await?; + + Ok(()) } /// # Send an ack to crond for processing @@ -385,19 +365,18 @@ impl AMQP { config.rabbit.default_exchange, config.rabbit.queues.acks, payload ); - self.channel + self.process_ack .basic_publish( - BasicProperties::default() - .with_content_type("application/json") - .with_persistence(true) - //.with_headers(headers) - .finish(), - payload.into(), - BasicPublishArguments::new( - &config.rabbit.default_exchange, - &config.rabbit.queues.acks, - ), + config.rabbit.default_exchange.clone().into(), + config.rabbit.queues.acks.into(), + BasicPublishOptions::default(), + payload.as_bytes(), + AMQPProperties::default() + .with_content_type("application/json".into()) + .with_delivery_mode(2), ) - .await + .await?; + + Ok(()) } } diff --git a/crates/daemons/crond/src/tasks/acks.rs b/crates/daemons/crond/src/tasks/acks.rs index 68b13144f..2a3dc3a66 100644 --- a/crates/daemons/crond/src/tasks/acks.rs +++ b/crates/daemons/crond/src/tasks/acks.rs @@ -3,7 +3,7 @@ use lapin::{ options::*, types::FieldTable, uri::{AMQPAuthority, AMQPQueryString, AMQPUri, AMQPUserInfo}, - ConnectionBuilder, ConnectionProperties, + ConnectionBuilder, ConnectionProperties, ExchangeKind, }; use log::info; use redis_kiss::{get_connection, AsyncCommands, Conn as RedisConnection}; @@ -46,6 +46,42 @@ pub async fn task(db: Database) -> Result<()> { .await .expect("Failed to create channel"); + reader_channel + .exchange_declare( + config.rabbit.default_exchange.clone().into(), + ExchangeKind::Topic, + ExchangeDeclareOptions { + durable: true, + ..Default::default() + }, + FieldTable::default(), + ) + .await + .expect("Failed to declare exchange"); + + reader_channel + .queue_declare( + config.rabbit.queues.acks.clone().into(), + QueueDeclareOptions { + durable: true, + ..Default::default() + }, + FieldTable::default(), + ) + .await + .expect("Failed to bind queue"); + + reader_channel + .queue_bind( + config.rabbit.queues.acks.clone().into(), + config.rabbit.default_exchange.into(), + config.rabbit.queues.acks.clone().into(), + QueueBindOptions::default(), + FieldTable::default(), + ) + .await + .expect("Failed to bind channel"); + let mut consumer = reader_channel .basic_consume( config.rabbit.queues.acks.into(), diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index c47eb11a5..8fb22999f 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -15,7 +15,7 @@ revolt-parser = { workspace = true } anyhow = { workspace = true } -amqprs = { workspace = true } +lapin = { workspace = true } fcm_v1 = { workspace = true } web-push = { workspace = true } isahc = { workspace = true, features = ["json"], optional = true } diff --git a/crates/daemons/pushd/src/consumers/inbound/ack.rs b/crates/daemons/pushd/src/consumers/inbound/ack.rs index 77dd5d444..77df8b272 100644 --- a/crates/daemons/pushd/src/consumers/inbound/ack.rs +++ b/crates/daemons/pushd/src/consumers/inbound/ack.rs @@ -1,96 +1,69 @@ -use crate::consumers::inbound::internal::*; -use amqprs::{ - channel::{BasicPublishArguments, Channel}, - connection::Connection, - consumer::AsyncConsumer, - BasicProperties, Deliver, -}; +use std::sync::Arc; + +use crate::utils::Consumer; +use anyhow::Result; use async_trait::async_trait; +use lapin::{message::Delivery, Channel, Connection}; use revolt_database::{events::rabbit::*, Database}; +#[derive(Clone)] +#[allow(unused)] pub struct AckConsumer { - #[allow(dead_code)] db: Database, authifier_db: authifier::Database, - conn: Option, - channel: Option, -} - -impl Channeled for AckConsumer { - fn get_connection(&self) -> Option<&Connection> { - if self.conn.is_none() { - None - } else { - Some(self.conn.as_ref().unwrap()) - } - } - - fn get_channel(&self) -> Option<&Channel> { - if self.channel.is_none() { - None - } else { - Some(self.channel.as_ref().unwrap()) - } - } - - fn set_connection(&mut self, conn: Connection) { - self.conn = Some(conn); - } - - fn set_channel(&mut self, channel: Channel) { - self.channel = Some(channel) - } + connection: Arc, + channel: Arc, } -impl AckConsumer { - pub fn new(db: Database, authifier_db: authifier::Database) -> AckConsumer { - AckConsumer { +#[async_trait] +impl Consumer for AckConsumer { + async fn create( + db: Database, + authifier_db: authifier::Database, + connection: Arc, + channel: Arc, + ) -> Self { + Self { db, authifier_db, - conn: None, - channel: None, + connection, + channel, } } -} -#[allow(unused_variables)] -#[async_trait] -impl AsyncConsumer for AckConsumer { + fn channel(&self) -> &Arc { + &self.channel + } + /// This consumer processes all acks the platform receives, and sends relevant badge updates to apple platforms. - async fn consume( - &mut self, - channel: &Channel, - deliver: Deliver, - basic_properties: BasicProperties, - content: Vec, - ) { - let content = String::from_utf8(content).unwrap(); - let payload: AckPayload = serde_json::from_str(content.as_str()).unwrap(); + async fn consume(&self, delivery: Delivery) -> Result<()> { + let payload: AckPayload = serde_json::from_slice(&delivery.data)?; // Step 1: fetch unreads and don't continue if there's no unreads - #[allow(clippy::disallowed_methods)] - let unreads = self.db.fetch_unread_mentions(&payload.user_id).await; + // #[allow(clippy::disallowed_methods)] debug!("Processing unreads for {:}", &payload.user_id); - if let Ok(u) = &unreads { + let unreads = if let Ok(u) = self.db.fetch_unread_mentions(&payload.user_id).await { if u.is_empty() { debug!( "Discarding unread task (no mentions found) for {:}", &payload.user_id ); - return; - } + return Ok(()); + }; + + u } else { - return; - } + return Ok(()); + }; if let Ok(sessions) = self.authifier_db.find_sessions(&payload.user_id).await { let config = revolt_config::config().await; // Step 2: find any apple sessions, since we don't need to calculate this for anything else. // If there's no apple sessions, we can return early - let apple_sessions: Vec<&authifier::models::Session> = sessions - .iter() + let mut apple_sessions = sessions + .into_iter() .filter(|session| { if let Some(sub) = &session.subscription { sub.endpoint == "apn" @@ -98,19 +71,19 @@ impl AsyncConsumer for AckConsumer { false } }) - .collect(); + .peekable(); - if apple_sessions.is_empty() { + if apple_sessions.peek().is_none() { debug!( "Discarding unread task (no apn sessions found) for {:}", &payload.user_id ); - return; + return Ok(()); } // Step 3: calculate the actual mention count, since we have to send it out let mut mention_count = 0; - for u in &unreads.unwrap() { + for u in &unreads { mention_count += u.mentions.as_ref().unwrap().len() } @@ -123,26 +96,22 @@ impl AsyncConsumer for AckConsumer { token: session.subscription.as_ref().unwrap().auth.clone(), extras: Default::default(), }; - let raw_service_payload = serde_json::to_string(&service_payload); - - if let Ok(p) = raw_service_payload { - let args = BasicPublishArguments::new( - config.pushd.exchange.as_str(), - config.pushd.apn.queue.as_str(), - ) - .finish(); - - log::debug!( - "Publishing ack to apn session {}", - session.subscription.as_ref().unwrap().auth - ); - - publish_message(self, p.into(), args).await; - } else { - log::warn!("Failed to serialize ack badge update payload!"); - revolt_config::capture_error(&raw_service_payload.unwrap_err()); - } + let payload = serde_json::to_string(&service_payload)?; + + log::debug!( + "Publishing ack to apn session {}", + session.subscription.as_ref().unwrap().auth + ); + + self.publish_message( + payload.as_bytes(), + &config.pushd.exchange, + &config.pushd.apn.queue, + ) + .await?; } } + + Ok(()) } } diff --git a/crates/daemons/pushd/src/consumers/inbound/dm_call.rs b/crates/daemons/pushd/src/consumers/inbound/dm_call.rs index 873b55ccd..3175d8d8f 100644 --- a/crates/daemons/pushd/src/consumers/inbound/dm_call.rs +++ b/crates/daemons/pushd/src/consumers/inbound/dm_call.rs @@ -1,70 +1,44 @@ -use std::collections::HashMap; - -use crate::consumers::inbound::internal::*; -use amqprs::{ - channel::{BasicPublishArguments, Channel}, - connection::Connection, - consumer::AsyncConsumer, - BasicProperties, Deliver, -}; +use std::{collections::HashMap, sync::Arc}; + +use crate::utils::Consumer; use anyhow::Result; use async_trait::async_trait; +use lapin::{message::Delivery, Channel, Connection}; use log::debug; use revolt_database::{events::rabbit::*, Database}; +#[derive(Clone)] +#[allow(unused)] pub struct DmCallConsumer { - #[allow(dead_code)] db: Database, authifier_db: authifier::Database, - conn: Option, - channel: Option, + connection: Arc, + channel: Arc, } -impl Channeled for DmCallConsumer { - fn get_connection(&self) -> Option<&Connection> { - if self.conn.is_none() { - None - } else { - Some(self.conn.as_ref().unwrap()) - } - } - - fn get_channel(&self) -> Option<&Channel> { - if self.channel.is_none() { - None - } else { - Some(self.channel.as_ref().unwrap()) - } - } - - fn set_connection(&mut self, conn: Connection) { - self.conn = Some(conn); - } - - fn set_channel(&mut self, channel: Channel) { - self.channel = Some(channel) - } -} - -impl DmCallConsumer { - pub fn new(db: Database, authifier_db: authifier::Database) -> DmCallConsumer { - DmCallConsumer { +#[async_trait] +impl Consumer for DmCallConsumer { + async fn create( + db: Database, + authifier_db: authifier::Database, + connection: Arc, + channel: Arc, + ) -> Self { + Self { db, authifier_db, - conn: None, - channel: None, + connection, + channel, } } - async fn consume_event( - &mut self, - _channel: &Channel, - _deliver: Deliver, - _basic_properties: BasicProperties, - content: Vec, - ) -> Result<()> { - let content = String::from_utf8(content)?; - let _p: InternalDmCallPayload = serde_json::from_str(content.as_str())?; + fn channel(&self) -> &Arc { + &self.channel + } + + /// This consumer handles delegating messages into their respective platform queues. + async fn consume(&self, delivery: Delivery) -> Result<()> { + let _p: InternalDmCallPayload = serde_json::from_slice(&delivery.data)?; let payload = _p.payload; debug!("Received dm call start/stop event"); @@ -107,36 +81,27 @@ impl DmCallConsumer { extras: HashMap::new(), }; - let args: BasicPublishArguments; - - if sub.endpoint == "apn" { - args = BasicPublishArguments::new( - config.pushd.exchange.as_str(), - config.pushd.apn.queue.as_str(), - ) - .finish(); - } else if sub.endpoint == "fcm" { - args = BasicPublishArguments::new( - config.pushd.exchange.as_str(), - config.pushd.fcm.queue.as_str(), - ) - .finish(); - } else { - // web push (vapid) - args = BasicPublishArguments::new( - config.pushd.exchange.as_str(), - config.pushd.vapid.queue.as_str(), - ) - .finish(); - sendable.extras.insert("p256dh".to_string(), sub.p256dh); - sendable - .extras - .insert("endpoint".to_string(), sub.endpoint.clone()); - } + let routing_key = match sub.endpoint.as_str() { + "apn" => &config.pushd.apn.queue, + "fcm" => &config.pushd.fcm.queue, + endpoint => { + sendable.extras.insert("p256dh".to_string(), sub.p256dh); + sendable + .extras + .insert("endpoint".to_string(), endpoint.to_string()); + + &config.pushd.vapid.queue + } + }; let payload = serde_json::to_string(&sendable)?; - publish_message(self, payload.into(), args).await; + self.publish_message( + payload.as_bytes(), + &config.pushd.exchange, + routing_key, + ) + .await?; } } } @@ -145,24 +110,3 @@ impl DmCallConsumer { Ok(()) } } - -#[allow(unused_variables)] -#[async_trait] -impl AsyncConsumer for DmCallConsumer { - /// This consumer handles delegating messages into their respective platform queues. - async fn consume( - &mut self, - channel: &Channel, - deliver: Deliver, - basic_properties: BasicProperties, - content: Vec, - ) { - if let Err(err) = self - .consume_event(channel, deliver, basic_properties, content) - .await - { - revolt_config::capture_anyhow(&err); - warn!("Failed to process dm call start/stop event: {err:?}"); - } - } -} diff --git a/crates/daemons/pushd/src/consumers/inbound/fr_accepted.rs b/crates/daemons/pushd/src/consumers/inbound/fr_accepted.rs index 115e4a264..bcfa1c2f0 100644 --- a/crates/daemons/pushd/src/consumers/inbound/fr_accepted.rs +++ b/crates/daemons/pushd/src/consumers/inbound/fr_accepted.rs @@ -1,70 +1,44 @@ -use std::collections::HashMap; +use std::{collections::HashMap, sync::Arc}; -use crate::consumers::inbound::internal::*; -use amqprs::{ - channel::{BasicPublishArguments, Channel}, - connection::Connection, - consumer::AsyncConsumer, - BasicProperties, Deliver, -}; +use crate::utils::Consumer; use anyhow::Result; use async_trait::async_trait; +use lapin::{message::Delivery, Channel, Connection}; use log::debug; use revolt_database::{events::rabbit::*, Database}; +#[derive(Clone)] +#[allow(unused)] pub struct FRAcceptedConsumer { - #[allow(dead_code)] db: Database, authifier_db: authifier::Database, - conn: Option, - channel: Option, + connection: Arc, + channel: Arc, } -impl Channeled for FRAcceptedConsumer { - fn get_connection(&self) -> Option<&Connection> { - if self.conn.is_none() { - None - } else { - Some(self.conn.as_ref().unwrap()) - } - } - - fn get_channel(&self) -> Option<&Channel> { - if self.channel.is_none() { - None - } else { - Some(self.channel.as_ref().unwrap()) - } - } - - fn set_connection(&mut self, conn: Connection) { - self.conn = Some(conn); - } - - fn set_channel(&mut self, channel: Channel) { - self.channel = Some(channel) - } -} - -impl FRAcceptedConsumer { - pub fn new(db: Database, authifier_db: authifier::Database) -> FRAcceptedConsumer { - FRAcceptedConsumer { +#[async_trait] +impl Consumer for FRAcceptedConsumer { + async fn create( + db: Database, + authifier_db: authifier::Database, + connection: Arc, + channel: Arc, + ) -> Self { + Self { db, authifier_db, - conn: None, - channel: None, + connection, + channel, } } - async fn consume_event( - &mut self, - _channel: &Channel, - _deliver: Deliver, - _basic_properties: BasicProperties, - content: Vec, - ) -> Result<()> { - let content = String::from_utf8(content)?; - let payload: FRAcceptedPayload = serde_json::from_str(content.as_str())?; + fn channel(&self) -> &Arc { + &self.channel + } + + /// This consumer handles delegating messages into their respective platform queues. + async fn consume(&self, delivery: Delivery) -> Result<()> { + let payload: FRAcceptedPayload = serde_json::from_slice(&delivery.data)?; debug!("Received FR accept event"); @@ -80,36 +54,23 @@ impl FRAcceptedConsumer { extras: HashMap::new(), }; - let args: BasicPublishArguments; - - if sub.endpoint == "apn" { - args = BasicPublishArguments::new( - config.pushd.exchange.as_str(), - config.pushd.apn.queue.as_str(), - ) - .finish(); - } else if sub.endpoint == "fcm" { - args = BasicPublishArguments::new( - config.pushd.exchange.as_str(), - config.pushd.fcm.queue.as_str(), - ) - .finish(); - } else { - // web push (vapid) - args = BasicPublishArguments::new( - config.pushd.exchange.as_str(), - config.pushd.vapid.queue.as_str(), - ) - .finish(); - sendable.extras.insert("p256dh".to_string(), sub.p256dh); - sendable - .extras - .insert("endpoint".to_string(), sub.endpoint.clone()); - } + let routing_key = match sub.endpoint.as_str() { + "apn" => &config.pushd.apn.queue, + "fcm" => &config.pushd.fcm.queue, + endpoint => { + sendable.extras.insert("p256dh".to_string(), sub.p256dh); + sendable + .extras + .insert("endpoint".to_string(), endpoint.to_string()); + + &config.pushd.vapid.queue + } + }; let payload = serde_json::to_string(&sendable)?; - publish_message(self, payload.into(), args).await; + self.publish_message(payload.as_bytes(), &config.pushd.exchange, routing_key) + .await?; } } } @@ -117,24 +78,3 @@ impl FRAcceptedConsumer { Ok(()) } } - -#[allow(unused_variables)] -#[async_trait] -impl AsyncConsumer for FRAcceptedConsumer { - /// This consumer handles delegating messages into their respective platform queues. - async fn consume( - &mut self, - channel: &Channel, - deliver: Deliver, - basic_properties: BasicProperties, - content: Vec, - ) { - if let Err(err) = self - .consume_event(channel, deliver, basic_properties, content) - .await - { - revolt_config::capture_anyhow(&err); - eprintln!("Failed to process friend request accepted event: {err:?}"); - } - } -} diff --git a/crates/daemons/pushd/src/consumers/inbound/fr_received.rs b/crates/daemons/pushd/src/consumers/inbound/fr_received.rs index c611dfaf9..66fce72df 100644 --- a/crates/daemons/pushd/src/consumers/inbound/fr_received.rs +++ b/crates/daemons/pushd/src/consumers/inbound/fr_received.rs @@ -1,70 +1,44 @@ -use std::collections::HashMap; +use std::{collections::HashMap, sync::Arc}; -use crate::consumers::inbound::internal::*; -use amqprs::{ - channel::{BasicPublishArguments, Channel}, - connection::Connection, - consumer::AsyncConsumer, - BasicProperties, Deliver, -}; +use crate::utils::Consumer; use anyhow::Result; use async_trait::async_trait; +use lapin::{message::Delivery, Channel, Connection}; use log::debug; use revolt_database::{events::rabbit::*, Database}; +#[derive(Clone)] +#[allow(unused)] pub struct FRReceivedConsumer { - #[allow(dead_code)] db: Database, authifier_db: authifier::Database, - conn: Option, - channel: Option, + connection: Arc, + channel: Arc, } -impl Channeled for FRReceivedConsumer { - fn get_connection(&self) -> Option<&Connection> { - if self.conn.is_none() { - None - } else { - Some(self.conn.as_ref().unwrap()) - } - } - - fn get_channel(&self) -> Option<&Channel> { - if self.channel.is_none() { - None - } else { - Some(self.channel.as_ref().unwrap()) - } - } - - fn set_connection(&mut self, conn: Connection) { - self.conn = Some(conn); - } - - fn set_channel(&mut self, channel: Channel) { - self.channel = Some(channel) - } -} - -impl FRReceivedConsumer { - pub fn new(db: Database, authifier_db: authifier::Database) -> FRReceivedConsumer { - FRReceivedConsumer { +#[async_trait] +impl Consumer for FRReceivedConsumer { + async fn create( + db: Database, + authifier_db: authifier::Database, + connection: Arc, + channel: Arc, + ) -> Self { + Self { db, authifier_db, - conn: None, - channel: None, + connection, + channel, } } - async fn consume_event( - &mut self, - _channel: &Channel, - _deliver: Deliver, - _basic_properties: BasicProperties, - content: Vec, - ) -> Result<()> { - let content = String::from_utf8(content)?; - let payload: FRReceivedPayload = serde_json::from_str(content.as_str())?; + fn channel(&self) -> &Arc { + &self.channel + } + + /// This consumer handles delegating messages into their respective platform queues. + async fn consume(&self, delivery: Delivery) -> Result<()> { + let payload: FRReceivedPayload = serde_json::from_slice(&delivery.data)?; debug!("Received FR received event"); @@ -80,36 +54,23 @@ impl FRReceivedConsumer { extras: HashMap::new(), }; - let args: BasicPublishArguments; - - if sub.endpoint == "apn" { - args = BasicPublishArguments::new( - config.pushd.exchange.as_str(), - config.pushd.apn.queue.as_str(), - ) - .finish(); - } else if sub.endpoint == "fcm" { - args = BasicPublishArguments::new( - config.pushd.exchange.as_str(), - config.pushd.fcm.queue.as_str(), - ) - .finish(); - } else { - // web push (vapid) - args = BasicPublishArguments::new( - config.pushd.exchange.as_str(), - config.pushd.vapid.queue.as_str(), - ) - .finish(); - sendable.extras.insert("p256dh".to_string(), sub.p256dh); - sendable - .extras - .insert("endpoint".to_string(), sub.endpoint.clone()); - } + let routing_key = match sub.endpoint.as_str() { + "apn" => &config.pushd.apn.queue, + "fcm" => &config.pushd.fcm.queue, + endpoint => { + sendable.extras.insert("p256dh".to_string(), sub.p256dh); + sendable + .extras + .insert("endpoint".to_string(), endpoint.to_string()); + + &config.pushd.vapid.queue + } + }; let payload = serde_json::to_string(&sendable)?; - publish_message(self, payload.into(), args).await; + self.publish_message(payload.as_bytes(), &config.pushd.exchange, routing_key) + .await?; } } } @@ -117,24 +78,3 @@ impl FRReceivedConsumer { Ok(()) } } - -#[allow(unused_variables)] -#[async_trait] -impl AsyncConsumer for FRReceivedConsumer { - /// This consumer handles delegating messages into their respective platform queues. - async fn consume( - &mut self, - channel: &Channel, - deliver: Deliver, - basic_properties: BasicProperties, - content: Vec, - ) { - if let Err(err) = self - .consume_event(channel, deliver, basic_properties, content) - .await - { - revolt_config::capture_anyhow(&err); - eprintln!("Failed to process friend request received event: {err:?}"); - } - } -} diff --git a/crates/daemons/pushd/src/consumers/inbound/generic.rs b/crates/daemons/pushd/src/consumers/inbound/generic.rs index 302b17007..f413661d8 100644 --- a/crates/daemons/pushd/src/consumers/inbound/generic.rs +++ b/crates/daemons/pushd/src/consumers/inbound/generic.rs @@ -1,70 +1,44 @@ -use std::collections::HashMap; +use std::{collections::HashMap, sync::Arc}; -use crate::consumers::inbound::internal::*; -use amqprs::{ - channel::{BasicPublishArguments, Channel}, - connection::Connection, - consumer::AsyncConsumer, - BasicProperties, Deliver, -}; +use crate::utils::Consumer; use anyhow::Result; use async_trait::async_trait; +use lapin::{message::Delivery, Channel, Connection}; use log::debug; use revolt_database::{events::rabbit::*, Database}; +#[derive(Clone)] +#[allow(unused)] pub struct GenericConsumer { - #[allow(dead_code)] db: Database, authifier_db: authifier::Database, - conn: Option, - channel: Option, + connection: Arc, + channel: Arc, } -impl Channeled for GenericConsumer { - fn get_connection(&self) -> Option<&Connection> { - if self.conn.is_none() { - None - } else { - Some(self.conn.as_ref().unwrap()) - } - } - - fn get_channel(&self) -> Option<&Channel> { - if self.channel.is_none() { - None - } else { - Some(self.channel.as_ref().unwrap()) - } - } - - fn set_connection(&mut self, conn: Connection) { - self.conn = Some(conn); - } - - fn set_channel(&mut self, channel: Channel) { - self.channel = Some(channel) - } -} - -impl GenericConsumer { - pub fn new(db: Database, authifier_db: authifier::Database) -> GenericConsumer { - GenericConsumer { +#[async_trait] +impl Consumer for GenericConsumer { + async fn create( + db: Database, + authifier_db: authifier::Database, + connection: Arc, + channel: Arc, + ) -> Self { + Self { db, authifier_db, - conn: None, - channel: None, + connection, + channel, } } - async fn consume_event( - &mut self, - _channel: &Channel, - _deliver: Deliver, - _basic_properties: BasicProperties, - content: Vec, - ) -> Result<()> { - let content = String::from_utf8(content)?; - let payload: MessageSentPayload = serde_json::from_str(content.as_str())?; + fn channel(&self) -> &Arc { + &self.channel + } + + /// This consumer handles delegating messages into their respective platform queues. + async fn consume(&self, delivery: Delivery) -> Result<()> { + let payload: MessageSentPayload = serde_json::from_slice(&delivery.data)?; debug!("Received message event on origin"); @@ -86,36 +60,23 @@ impl GenericConsumer { extras: HashMap::new(), }; - let args: BasicPublishArguments; - - if sub.endpoint == "apn" { - args = BasicPublishArguments::new( - config.pushd.exchange.as_str(), - config.pushd.apn.queue.as_str(), - ) - .finish(); - } else if sub.endpoint == "fcm" { - args = BasicPublishArguments::new( - config.pushd.exchange.as_str(), - config.pushd.fcm.queue.as_str(), - ) - .finish(); - } else { - // web push (vapid) - args = BasicPublishArguments::new( - config.pushd.exchange.as_str(), - config.pushd.vapid.queue.as_str(), - ) - .finish(); - sendable.extras.insert("p256dh".to_string(), sub.p256dh); - sendable - .extras - .insert("endpoint".to_string(), sub.endpoint.clone()); - } + let routing_key = match sub.endpoint.as_str() { + "apn" => &config.pushd.apn.queue, + "fcm" => &config.pushd.fcm.queue, + endpoint => { + sendable.extras.insert("p256dh".to_string(), sub.p256dh); + sendable + .extras + .insert("endpoint".to_string(), endpoint.to_string()); + + &config.pushd.vapid.queue + } + }; let payload = serde_json::to_string(&sendable)?; - publish_message(self, payload.into(), args).await; + self.publish_message(payload.as_bytes(), &config.pushd.exchange, routing_key) + .await?; } } } @@ -123,24 +84,3 @@ impl GenericConsumer { Ok(()) } } - -#[allow(unused_variables)] -#[async_trait] -impl AsyncConsumer for GenericConsumer { - /// This consumer handles delegating messages into their respective platform queues. - async fn consume( - &mut self, - channel: &Channel, - deliver: Deliver, - basic_properties: BasicProperties, - content: Vec, - ) { - if let Err(err) = self - .consume_event(channel, deliver, basic_properties, content) - .await - { - revolt_config::capture_anyhow(&err); - eprintln!("Failed to process generic event: {err:?}"); - } - } -} diff --git a/crates/daemons/pushd/src/consumers/inbound/internal.rs b/crates/daemons/pushd/src/consumers/inbound/internal.rs deleted file mode 100644 index 387c08b52..000000000 --- a/crates/daemons/pushd/src/consumers/inbound/internal.rs +++ /dev/null @@ -1,53 +0,0 @@ -use amqprs::{ - channel::{BasicPublishArguments, Channel}, - connection::{Connection, OpenConnectionArguments}, - BasicProperties, -}; -use log::{debug, warn}; - -pub(crate) trait Channeled { - #[allow(unused)] - fn get_connection(&self) -> Option<&Connection>; - fn get_channel(&self) -> Option<&Channel>; - fn set_connection(&mut self, conn: Connection); - fn set_channel(&mut self, channel: Channel); -} - -pub(crate) async fn make_channel(consumer: &mut T) { - let config = revolt_config::config().await; - - let args = OpenConnectionArguments::new( - &config.rabbit.host, - config.rabbit.port, - &config.rabbit.username, - &config.rabbit.password, - ); - let conn = amqprs::connection::Connection::open(&args).await.unwrap(); - - let channel = conn.open_channel(None).await.unwrap(); - - consumer.set_connection(conn); - consumer.set_channel(channel); -} - -pub(crate) async fn publish_message( - consumer: &mut T, - payload: Vec, - args: BasicPublishArguments, -) { - let routing_key = &args.routing_key.clone(); - let mut channel = consumer.get_channel(); - if channel.is_none() { - make_channel(consumer).await; - channel = consumer.get_channel(); - } - - if let Some(chnl) = channel { - chnl.basic_publish(BasicProperties::default(), payload.clone(), args.clone()) - .await - .unwrap(); - debug!("Sent message to queue for target {}", routing_key); - } else { - warn!("Failed to unwrap channel (including attempt to make a channel)!") - } -} diff --git a/crates/daemons/pushd/src/consumers/inbound/mass_mention.rs b/crates/daemons/pushd/src/consumers/inbound/mass_mention.rs index 8d43cce8c..55ab984f7 100644 --- a/crates/daemons/pushd/src/consumers/inbound/mass_mention.rs +++ b/crates/daemons/pushd/src/consumers/inbound/mass_mention.rs @@ -1,17 +1,13 @@ use std::{ collections::{HashMap, HashSet}, hash::RandomState, + sync::Arc, }; -use crate::{consumers::inbound::internal::*, utils}; -use amqprs::{ - channel::{BasicPublishArguments, Channel}, - connection::Connection, - consumer::AsyncConsumer, - BasicProperties, Deliver, -}; +use crate::utils::{render_notification_content, Consumer}; use anyhow::Result; use async_trait::async_trait; +use lapin::{message::Delivery, Channel, Connection}; use revolt_database::{ events::rabbit::*, util::bulk_permissions::BulkDatabasePermissionQuery, Database, Member, MessageFlagsValue, @@ -19,52 +15,18 @@ use revolt_database::{ use revolt_models::v0::{MessageFlags, PushNotification}; use revolt_result::ToRevoltError; +#[derive(Clone)] +#[allow(unused)] pub struct MassMessageConsumer { - #[allow(dead_code)] db: Database, authifier_db: authifier::Database, - conn: Option, - channel: Option, -} - -impl Channeled for MassMessageConsumer { - fn get_connection(&self) -> Option<&Connection> { - if self.conn.is_none() { - None - } else { - Some(self.conn.as_ref().unwrap()) - } - } - - fn get_channel(&self) -> Option<&Channel> { - if self.channel.is_none() { - None - } else { - Some(self.channel.as_ref().unwrap()) - } - } - - fn set_connection(&mut self, conn: Connection) { - self.conn = Some(conn); - } - - fn set_channel(&mut self, channel: Channel) { - self.channel = Some(channel) - } + connection: Arc, + channel: Arc, } impl MassMessageConsumer { - pub fn new(db: Database, authifier_db: authifier::Database) -> MassMessageConsumer { - MassMessageConsumer { - db, - authifier_db, - conn: None, - channel: None, - } - } - async fn fire_notification_for_users( - &mut self, + &self, push: &PushNotification, users: &[String], ) -> Result<()> { @@ -84,56 +46,58 @@ impl MassMessageConsumer { extras: HashMap::new(), }; - let args: BasicPublishArguments; - - if sub.endpoint == "apn" { - args = BasicPublishArguments::new( - config.pushd.exchange.as_str(), - config.pushd.apn.queue.as_str(), - ) - .finish(); - } else if sub.endpoint == "fcm" { - args = BasicPublishArguments::new( - config.pushd.exchange.as_str(), - config.pushd.fcm.queue.as_str(), - ) - .finish(); - } else { - // web push (vapid) - args = BasicPublishArguments::new( - config.pushd.exchange.as_str(), - config.pushd.vapid.queue.as_str(), - ) - .finish(); - sendable.extras.insert("p256dh".to_string(), sub.p256dh); - sendable - .extras - .insert("endpoint".to_string(), sub.endpoint.clone()); - } + let routing_key = match sub.endpoint.as_str() { + "apn" => &config.pushd.apn.queue, + "fcm" => &config.pushd.fcm.queue, + endpoint => { + sendable.extras.insert("p256dh".to_string(), sub.p256dh); + sendable + .extras + .insert("endpoint".to_string(), endpoint.to_string()); + + &config.pushd.vapid.queue + } + }; let payload = serde_json::to_string(&sendable)?; - publish_message(self, payload.into(), args).await; + self.publish_message(payload.as_bytes(), &config.pushd.exchange, routing_key) + .await?; } } } Ok(()) } +} - async fn consume_event( - &mut self, - _channel: &Channel, - _deliver: Deliver, - _basic_properties: BasicProperties, - content: Vec, - ) -> Result<()> { +#[async_trait] +impl Consumer for MassMessageConsumer { + async fn create( + db: Database, + authifier_db: authifier::Database, + connection: Arc, + channel: Arc, + ) -> Self { + Self { + db, + authifier_db, + connection, + channel, + } + } + + fn channel(&self) -> &Arc { + &self.channel + } + + /// This consumer handles adding mentions for all the users affected by a mass mention ping, and then sends out push notifications. + async fn consume(&self, delivery: Delivery) -> Result<()> { + let mut payload: MassMessageSentPayload = serde_json::from_slice(&delivery.data)?; let config = revolt_config::config().await; - let content = String::from_utf8(content)?; - let mut payload: MassMessageSentPayload = serde_json::from_str(content.as_str())?; for push in payload.notifications.iter_mut() { - if let Ok(body) = utils::render_notification_content(push, &self.db) + if let Ok(body) = render_notification_content(push, &self.db) .await .to_internal_error() { @@ -280,24 +244,3 @@ impl MassMessageConsumer { Ok(()) } } - -#[allow(unused_variables)] -#[async_trait] -impl AsyncConsumer for MassMessageConsumer { - /// This consumer handles adding mentions for all the users affected by a mass mention ping, and then sends out push notifications - async fn consume( - &mut self, - channel: &Channel, - deliver: Deliver, - basic_properties: BasicProperties, - content: Vec, - ) { - if let Err(err) = self - .consume_event(channel, deliver, basic_properties, content) - .await - { - revolt_config::capture_anyhow(&err); - eprintln!("Failed to process mass message event: {err:?}"); - } - } -} diff --git a/crates/daemons/pushd/src/consumers/inbound/message.rs b/crates/daemons/pushd/src/consumers/inbound/message.rs index 45de0b0b4..e4aa04d5b 100644 --- a/crates/daemons/pushd/src/consumers/inbound/message.rs +++ b/crates/daemons/pushd/src/consumers/inbound/message.rs @@ -1,76 +1,46 @@ -use std::collections::HashMap; +use std::{collections::HashMap, sync::Arc}; -use crate::{consumers::inbound::internal::*, utils}; -use amqprs::{ - channel::{BasicPublishArguments, Channel}, - connection::Connection, - consumer::AsyncConsumer, - BasicProperties, Deliver, -}; +use crate::utils::{render_notification_content, Consumer}; use anyhow::Result; use async_trait::async_trait; +use lapin::{message::Delivery, Channel, Connection}; use log::debug; use revolt_database::{events::rabbit::*, Database}; -use revolt_result::ToRevoltError; +#[derive(Clone)] +#[allow(unused)] pub struct MessageConsumer { - #[allow(dead_code)] db: Database, authifier_db: authifier::Database, - conn: Option, - channel: Option, + connection: Arc, + channel: Arc, } -impl Channeled for MessageConsumer { - fn get_connection(&self) -> Option<&Connection> { - if self.conn.is_none() { - None - } else { - Some(self.conn.as_ref().unwrap()) - } - } - - fn get_channel(&self) -> Option<&Channel> { - if self.channel.is_none() { - None - } else { - Some(self.channel.as_ref().unwrap()) - } - } - - fn set_connection(&mut self, conn: Connection) { - self.conn = Some(conn); - } - - fn set_channel(&mut self, channel: Channel) { - self.channel = Some(channel) - } -} - -impl MessageConsumer { - pub fn new(db: Database, authifier_db: authifier::Database) -> MessageConsumer { - MessageConsumer { +#[async_trait] +impl Consumer for MessageConsumer { + async fn create( + db: Database, + authifier_db: authifier::Database, + connection: Arc, + channel: Arc, + ) -> Self { + Self { db, authifier_db, - conn: None, - channel: None, + connection, + channel, } } - async fn consume_event( - &mut self, - _channel: &Channel, - _deliver: Deliver, - _basic_properties: BasicProperties, - content: Vec, - ) -> Result<()> { - let content = String::from_utf8(content)?; - let mut payload: MessageSentPayload = serde_json::from_str(content.as_str())?; + fn channel(&self) -> &Arc { + &self.channel + } - if let Ok(body) = utils::render_notification_content(&payload.notification, &self.db) - .await - .to_internal_error() - { + /// This consumer handles delegating messages into their respective platform queues. + async fn consume(&self, delivery: Delivery) -> Result<()> { + let mut payload: MessageSentPayload = serde_json::from_slice(&delivery.data)?; + + if let Ok(body) = render_notification_content(&payload.notification, &self.db).await { payload.notification.raw_body = Some(payload.notification.body); payload.notification.body = body; } @@ -95,36 +65,22 @@ impl MessageConsumer { extras: HashMap::new(), }; - let args: BasicPublishArguments; - - if sub.endpoint == "apn" { - args = BasicPublishArguments::new( - config.pushd.exchange.as_str(), - config.pushd.apn.queue.as_str(), - ) - .finish(); - } else if sub.endpoint == "fcm" { - args = BasicPublishArguments::new( - config.pushd.exchange.as_str(), - config.pushd.fcm.queue.as_str(), - ) - .finish(); - } else { - // web push (vapid) - args = BasicPublishArguments::new( - config.pushd.exchange.as_str(), - config.pushd.vapid.queue.as_str(), - ) - .finish(); - sendable.extras.insert("p256dh".to_string(), sub.p256dh); - sendable - .extras - .insert("endpoint".to_string(), sub.endpoint.clone()); - } + let routing_key = match sub.endpoint.as_str() { + "apn" => &config.pushd.apn.queue, + "fcm" => &config.pushd.fcm.queue, + endpoint => { + sendable.extras.insert("p256dh".to_string(), sub.p256dh); + sendable + .extras + .insert("endpoint".to_string(), endpoint.to_string()); + + &config.pushd.vapid.queue + } + }; let payload = serde_json::to_string(&sendable)?; - - publish_message(self, payload.into(), args).await; + self.publish_message(payload.as_bytes(), &config.pushd.exchange, routing_key) + .await?; } } } @@ -132,24 +88,3 @@ impl MessageConsumer { Ok(()) } } - -#[allow(unused_variables)] -#[async_trait] -impl AsyncConsumer for MessageConsumer { - /// This consumer handles delegating messages into their respective platform queues. - async fn consume( - &mut self, - channel: &Channel, - deliver: Deliver, - basic_properties: BasicProperties, - content: Vec, - ) { - if let Err(err) = self - .consume_event(channel, deliver, basic_properties, content) - .await - { - revolt_config::capture_anyhow(&err); - eprintln!("Failed to process message event: {err:?}"); - } - } -} diff --git a/crates/daemons/pushd/src/consumers/inbound/mod.rs b/crates/daemons/pushd/src/consumers/inbound/mod.rs index 4d6d36b23..7c93cdb64 100644 --- a/crates/daemons/pushd/src/consumers/inbound/mod.rs +++ b/crates/daemons/pushd/src/consumers/inbound/mod.rs @@ -3,6 +3,5 @@ pub mod dm_call; pub mod fr_accepted; pub mod fr_received; pub mod generic; -mod internal; pub mod mass_mention; pub mod message; diff --git a/crates/daemons/pushd/src/consumers/outbound/apn.rs b/crates/daemons/pushd/src/consumers/outbound/apn.rs index ec478c1f0..feb6cb94f 100644 --- a/crates/daemons/pushd/src/consumers/outbound/apn.rs +++ b/crates/daemons/pushd/src/consumers/outbound/apn.rs @@ -1,12 +1,13 @@ -use std::{borrow::Cow, collections::BTreeMap, io::Cursor}; +use std::{borrow::Cow, collections::BTreeMap, io::Cursor, sync::Arc}; -use amqprs::{channel::Channel as AmqpChannel, consumer::AsyncConsumer, BasicProperties, Deliver}; -use anyhow::{anyhow, Result}; +use crate::utils::Consumer; +use anyhow::Result; use async_trait::async_trait; use base64::{ engine::{self}, Engine as _, }; +use lapin::{message::Delivery, Channel as AMQPChannel, Connection}; use revolt_a2::{ request::{ notification::{DefaultAlert, NotificationOptions}, @@ -42,7 +43,7 @@ impl<'a> PayloadLike for MessagePayload<'a> { fn get_device_token(&self) -> &'a str { self.device_token } - fn get_options(&self) -> &NotificationOptions { + fn get_options(&self) -> &NotificationOptions<'a> { &self.options } } @@ -68,16 +69,20 @@ impl<'a> PayloadLike for CallStartStopPayload<'a> { fn get_device_token(&self) -> &'a str { self.device_token } - fn get_options(&self) -> &NotificationOptions { + fn get_options(&self) -> &NotificationOptions<'a> { &self.options } } // region: consumer +#[derive(Clone)] +#[allow(unused)] pub struct ApnsOutboundConsumer { - #[allow(dead_code)] db: Database, + authifier_db: authifier::Database, + connection: Arc, + channel: Arc, client: Client, } @@ -117,15 +122,21 @@ impl ApnsOutboundConsumer { } } -impl ApnsOutboundConsumer { - pub async fn new(db: Database) -> Result { +#[async_trait] +impl Consumer for ApnsOutboundConsumer { + async fn create( + db: Database, + authifier_db: authifier::Database, + connection: Arc, + channel: Arc, + ) -> Self { let config = revolt_config::config().await; if config.pushd.apn.pkcs8.is_empty() || config.pushd.apn.key_id.is_empty() || config.pushd.apn.team_id.is_empty() { - return Err("Missing APN keys."); + panic!("Missing APN keys."); } let endpoint = if config.pushd.apn.sandbox { @@ -148,18 +159,21 @@ impl ApnsOutboundConsumer { ) .expect("could not create APN client"); - Ok(ApnsOutboundConsumer { db, client }) + Self { + db, + authifier_db, + connection, + channel, + client, + } + } + + fn channel(&self) -> &Arc { + &self.channel } - async fn consume_event( - &mut self, - _channel: &AmqpChannel, - _deliver: Deliver, - _basic_properties: BasicProperties, - content: Vec, - ) -> Result<()> { - let content = String::from_utf8(content)?; - let payload: PayloadToService = serde_json::from_str(content.as_str())?; + async fn consume(&self, delivery: Delivery) -> Result<()> { + let payload: PayloadToService = serde_json::from_slice(&delivery.data)?; let payload_options = NotificationOptions { apns_id: None, @@ -170,20 +184,15 @@ impl ApnsOutboundConsumer { apns_collapse_id: None, }; - let resp: Result; - - match payload.notification { + let resp = match payload.notification { PayloadKind::FRReceived(alert) => { let loc_args = vec![Cow::from( - alert - .from_user - .display_name - .or(Some(format!( + alert.from_user.display_name.clone().unwrap_or_else(|| { + format!( "{}#{}", alert.from_user.username, alert.from_user.discriminator - ))) - .clone() - .ok_or_else(|| anyhow!("missing name"))?, + ) + }), )]; let apn_payload = Payload { @@ -216,20 +225,17 @@ impl ApnsOutboundConsumer { "Sending friend request received for user: {:}", &payload.user_id ); - resp = self.client.send(apn_payload).await; + self.client.send(apn_payload).await } PayloadKind::FRAccepted(alert) => { let loc_args = vec![Cow::from( - alert - .accepted_user - .display_name - .or(Some(format!( + alert.accepted_user.display_name.clone().unwrap_or_else(|| { + format!( "{}#{}", alert.accepted_user.username, alert.accepted_user.discriminator - ))) - .clone() - .ok_or_else(|| anyhow!("missing name"))?, + ) + }), )]; let apn_payload = Payload { @@ -262,7 +268,7 @@ impl ApnsOutboundConsumer { "Sending friend request accept for user: {:}", &payload.user_id ); - resp = self.client.send(apn_payload).await; + self.client.send(apn_payload).await } PayloadKind::Generic(alert) => { let apn_payload = Payload { @@ -295,7 +301,7 @@ impl ApnsOutboundConsumer { "Sending generic notification for user: {:}", &payload.user_id ); - resp = self.client.send(apn_payload).await; + self.client.send(apn_payload).await } PayloadKind::MessageNotification(alert) => { @@ -334,7 +340,7 @@ impl ApnsOutboundConsumer { "Sending message notification for user: {:}", &payload.user_id ); - resp = self.client.send(apn_payload).await; + self.client.send(apn_payload).await } PayloadKind::BadgeUpdate(badge) => { @@ -349,7 +355,7 @@ impl ApnsOutboundConsumer { }; debug!("Sending badge update for user: {:}", &payload.user_id); - resp = self.client.send(apn_payload).await; + self.client.send(apn_payload).await } PayloadKind::DmCallStartEnd(alert) => { @@ -378,58 +384,37 @@ impl ApnsOutboundConsumer { "Sending call start/stop notification for user: {:}", &payload.user_id ); - resp = self.client.send(apn_payload).await; + self.client.send(apn_payload).await } - } + }; - if let Err(err) = resp { - match err { - Error::ResponseError(Response { - error: - Some(ErrorBody { - reason: ErrorReason::BadDeviceToken | ErrorReason::Unregistered, - .. - }), - .. - }) => { - info!( - "Removing APNS subscription id {:} (user: {:}) due to invalid token", - &payload.session_id, &payload.user_id - ); - if let Err(err) = self - .db - .remove_push_subscription_by_session_id(&payload.session_id) - .await - { - revolt_config::capture_error(&err); - } - } - err => { + match resp { + Err(Error::ResponseError(Response { + error: + Some(ErrorBody { + reason: ErrorReason::BadDeviceToken | ErrorReason::Unregistered, + .. + }), + .. + })) => { + info!( + "Removing APNS subscription id {:} (user: {:}) due to invalid token", + &payload.session_id, &payload.user_id + ); + + if let Err(err) = self + .db + .remove_push_subscription_by_session_id(&payload.session_id) + .await + { revolt_config::capture_error(&err); } } - } + resp => { + resp?; + } + }; Ok(()) } } - -#[allow(unused_variables)] -#[async_trait] -impl AsyncConsumer for ApnsOutboundConsumer { - async fn consume( - &mut self, - channel: &AmqpChannel, - deliver: Deliver, - basic_properties: BasicProperties, - content: Vec, - ) { - if let Err(err) = self - .consume_event(channel, deliver, basic_properties, content) - .await - { - revolt_config::capture_anyhow(&err); - eprintln!("Failed to process APN event: {err:?}"); - } - } -} diff --git a/crates/daemons/pushd/src/consumers/outbound/fcm.rs b/crates/daemons/pushd/src/consumers/outbound/fcm.rs index 4ea21e0b1..e3bd185cf 100644 --- a/crates/daemons/pushd/src/consumers/outbound/fcm.rs +++ b/crates/daemons/pushd/src/consumers/outbound/fcm.rs @@ -1,14 +1,14 @@ -use std::{collections::HashMap, time::Duration}; +use std::{collections::HashMap, sync::Arc, time::Duration}; -use amqprs::{channel::Channel as AmqpChannel, consumer::AsyncConsumer, BasicProperties, Deliver}; - -use anyhow::{anyhow, bail, Result}; +use crate::utils::Consumer; +use anyhow::{bail, Result}; use async_trait::async_trait; use fcm_v1::{ auth::{Authenticator, ServiceAccountKey}, message::Message, Client, Error as FcmError, }; +use lapin::{message::Delivery, Channel as AMQPChannel, Connection}; use revolt_config::config; use revolt_database::{events::rabbit::*, Database}; use serde_json::Value; @@ -115,17 +115,31 @@ impl NotificationData { } } +#[derive(Clone)] +#[allow(unused)] pub struct FcmOutboundConsumer { db: Database, + authifier_db: authifier::Database, + connection: Arc, + channel: Arc, client: Client, } -impl FcmOutboundConsumer { - pub async fn new(db: Database) -> Result { +#[async_trait] +impl Consumer for FcmOutboundConsumer { + async fn create( + db: Database, + authifier_db: authifier::Database, + connection: Arc, + channel: Arc, + ) -> Self { let config = revolt_config::config().await; - Ok(FcmOutboundConsumer { + Self { db, + authifier_db, + connection, + channel, client: Client::new( Authenticator::service_account::<&str>(ServiceAccountKey { key_type: Some(config.pushd.fcm.key_type), @@ -145,33 +159,27 @@ impl FcmOutboundConsumer { false, Duration::from_secs(5), ), - }) + } } - async fn consume_event( - &mut self, - _channel: &AmqpChannel, - _deliver: Deliver, - _basic_properties: BasicProperties, - content: Vec, - ) -> Result<()> { - let content = String::from_utf8(content)?; - let payload: PayloadToService = serde_json::from_str(content.as_str())?; + fn channel(&self) -> &Arc { + &self.channel + } + + async fn consume(&self, delivery: Delivery) -> Result<()> { + let payload: PayloadToService = serde_json::from_slice(&delivery.data)?; #[allow(clippy::needless_late_init)] let resp: Result; match payload.notification { PayloadKind::FRReceived(alert) => { - let name = alert - .from_user - .display_name - .or(Some(format!( + let name = alert.from_user.display_name.clone().unwrap_or_else(|| { + format!( "{}#{}", alert.from_user.username, alert.from_user.discriminator - ))) - .clone() - .ok_or_else(|| anyhow!("missing name"))?; + ) + }); let data = NotificationData::FRReceived { id: alert.from_user.id, @@ -188,15 +196,12 @@ impl FcmOutboundConsumer { } PayloadKind::FRAccepted(alert) => { - let name = alert - .accepted_user - .display_name - .or(Some(format!( + let name = alert.accepted_user.display_name.clone().unwrap_or_else(|| { + format!( "{}#{}", alert.accepted_user.username, alert.accepted_user.discriminator - ))) - .clone() - .ok_or_else(|| anyhow!("missing name"))?; + ) + }); let data = NotificationData::FRAccepted { id: alert.accepted_user.id, @@ -269,43 +274,21 @@ impl FcmOutboundConsumer { } } - if let Err(err) = resp { - match err { - FcmError::Auth => { - if let Err(err) = self - .db - .remove_push_subscription_by_session_id(&payload.session_id) - .await - { - revolt_config::capture_error(&err); - } - } - err => { + match resp { + Err(FcmError::Auth) => { + if let Err(err) = self + .db + .remove_push_subscription_by_session_id(&payload.session_id) + .await + { revolt_config::capture_error(&err); } } - } + res => { + res?; + } + }; Ok(()) } } - -#[allow(unused_variables)] -#[async_trait] -impl AsyncConsumer for FcmOutboundConsumer { - async fn consume( - &mut self, - channel: &AmqpChannel, - deliver: Deliver, - basic_properties: BasicProperties, - content: Vec, - ) { - if let Err(err) = self - .consume_event(channel, deliver, basic_properties, content) - .await - { - revolt_config::capture_anyhow(&err); - eprintln!("Failed to process FCM event: {err:?}"); - } - } -} diff --git a/crates/daemons/pushd/src/consumers/outbound/vapid.rs b/crates/daemons/pushd/src/consumers/outbound/vapid.rs index 67ec31fb8..0acd8be9d 100644 --- a/crates/daemons/pushd/src/consumers/outbound/vapid.rs +++ b/crates/daemons/pushd/src/consumers/outbound/vapid.rs @@ -1,6 +1,6 @@ -use std::collections::HashMap; +use std::{collections::HashMap, sync::Arc}; -use amqprs::{channel::Channel as AmqpChannel, consumer::AsyncConsumer, BasicProperties, Deliver}; +use crate::utils::Consumer; use anyhow::{anyhow, bail, Result}; use async_trait::async_trait; @@ -8,46 +8,60 @@ use base64::{ engine::{self}, Engine as _, }; +use lapin::{message::Delivery, Channel as AMQPChannel, Connection}; use revolt_database::{events::rabbit::*, util::format_display_name, Database}; use web_push::{ ContentEncoding, IsahcWebPushClient, SubscriptionInfo, SubscriptionKeys, VapidSignatureBuilder, WebPushClient, WebPushError, WebPushMessageBuilder, }; +#[derive(Clone)] +#[allow(unused)] pub struct VapidOutboundConsumer { db: Database, + authifier_db: authifier::Database, + connection: Arc, + channel: Arc, client: IsahcWebPushClient, - pkey: Vec, + pkey: Arc>, } -impl VapidOutboundConsumer { - pub async fn new(db: Database) -> Result { +#[async_trait] +impl Consumer for VapidOutboundConsumer { + async fn create( + db: Database, + authifier_db: authifier::Database, + connection: Arc, + channel: Arc, + ) -> Self { let config = revolt_config::config().await; - if config.pushd.vapid.private_key.is_empty() | config.pushd.vapid.public_key.is_empty() { - bail!("no Vapid keys present"); + if config.pushd.vapid.private_key.is_empty() || config.pushd.vapid.public_key.is_empty() { + panic!("no Vapid keys present"); } - let web_push_private_key = engine::general_purpose::URL_SAFE_NO_PAD - .decode(config.pushd.vapid.private_key) - .expect("valid `VAPID_PRIVATE_KEY`"); + let web_push_private_key = Arc::new( + engine::general_purpose::URL_SAFE_NO_PAD + .decode(config.pushd.vapid.private_key) + .expect("valid `VAPID_PRIVATE_KEY`"), + ); - Ok(VapidOutboundConsumer { + Self { db, + authifier_db, + connection, + channel, client: IsahcWebPushClient::new().unwrap(), pkey: web_push_private_key, - }) + } + } + + fn channel(&self) -> &Arc { + &self.channel } - async fn consume_event( - &mut self, - _channel: &AmqpChannel, - _deliver: Deliver, - _basic_properties: BasicProperties, - content: Vec, - ) -> Result<()> { - let content = String::from_utf8(content)?; - let payload: PayloadToService = serde_json::from_str(content.as_str())?; + async fn consume(&self, delivery: Delivery) -> Result<()> { + let payload: PayloadToService = serde_json::from_slice(&delivery.data)?; let subscription = SubscriptionInfo { endpoint: payload @@ -65,10 +79,7 @@ impl VapidOutboundConsumer { }, }; - #[allow(clippy::needless_late_init)] - let payload_body: String; - - match payload.notification { + let payload_body = match payload.notification { PayloadKind::FRReceived(alert) => { let name = alert .from_user @@ -83,7 +94,7 @@ impl VapidOutboundConsumer { let mut body = HashMap::new(); body.insert("body", format!("{} sent you a friend request", name)); - payload_body = serde_json::to_string(&body)?; + serde_json::to_string(&body)? } PayloadKind::FRAccepted(alert) => { let name = alert @@ -99,14 +110,10 @@ impl VapidOutboundConsumer { let mut body = HashMap::new(); body.insert("body", format!("{} accepted your friend request", name)); - payload_body = serde_json::to_string(&body)?; - } - PayloadKind::Generic(alert) => { - payload_body = serde_json::to_string(&alert)?; - } - PayloadKind::MessageNotification(alert) => { - payload_body = serde_json::to_string(&alert)?; + serde_json::to_string(&body)? } + PayloadKind::Generic(alert) => serde_json::to_string(&alert)?, + PayloadKind::MessageNotification(alert) => serde_json::to_string(&alert)?, PayloadKind::DmCallStartEnd(alert) => { let initiator_name = if let Some(server_id) = self.db.fetch_channel(&alert.channel_id).await?.server() @@ -132,59 +139,41 @@ impl VapidOutboundConsumer { _ => bail!("Invalid DmCallStart/End channel type"), } - payload_body = serde_json::to_string(&body)?; + serde_json::to_string(&body)? } PayloadKind::BadgeUpdate(_) => { bail!("Vapid cannot handle badge updates and they should not be sent here."); } - } + }; - match VapidSignatureBuilder::from_pem(std::io::Cursor::new(&self.pkey), &subscription) { - Ok(sig_builder) => match sig_builder.build() { - Ok(signature) => { - let mut builder = WebPushMessageBuilder::new(&subscription); - builder.set_vapid_signature(signature); - - builder.set_payload(ContentEncoding::AesGcm, payload_body.as_bytes()); - - match builder.build() { - Ok(msg) => { - if let Err(err) = self.client.send(msg).await { - if err == WebPushError::Unauthorized { - self.db - .remove_push_subscription_by_session_id(&payload.session_id) - .await?; - } - } - - Ok(()) - } - Err(err) => Err(err.into()), - } + let signature = VapidSignatureBuilder::from_pem( + std::io::Cursor::new(self.pkey.as_ref()), + &subscription, + )? + .build()?; + + let mut builder = WebPushMessageBuilder::new(&subscription); + builder.set_vapid_signature(signature); + + builder.set_payload(ContentEncoding::AesGcm, payload_body.as_bytes()); + + let msg = builder.build()?; + + match self.client.send(msg).await { + Err(WebPushError::Unauthorized) => { + if let Err(err) = self + .db + .remove_push_subscription_by_session_id(&payload.session_id) + .await + { + revolt_config::capture_error(&err); } - Err(err) => Err(err.into()), - }, - Err(err) => Err(err.into()), - } - } -} + } + res => { + res?; + } + }; -#[allow(unused_variables)] -#[async_trait] -impl AsyncConsumer for VapidOutboundConsumer { - async fn consume( - &mut self, - channel: &AmqpChannel, - deliver: Deliver, - basic_properties: BasicProperties, - content: Vec, - ) { - if let Err(err) = self - .consume_event(channel, deliver, basic_properties, content) - .await - { - revolt_config::capture_anyhow(&err); - eprintln!("Failed to process Vapid event: {err:?}"); - } + Ok(()) } } diff --git a/crates/daemons/pushd/src/main.rs b/crates/daemons/pushd/src/main.rs index eaa2e1b81..b4824b650 100644 --- a/crates/daemons/pushd/src/main.rs +++ b/crates/daemons/pushd/src/main.rs @@ -1,17 +1,16 @@ #[macro_use] extern crate log; -use amqprs::{ - channel::{ - BasicConsumeArguments, Channel, ExchangeDeclareArguments, QueueBindArguments, - QueueDeclareArguments, - }, - connection::{Connection, OpenConnectionArguments}, - consumer::AsyncConsumer, - FieldTable, +use std::sync::Arc; + +use lapin::{ + options::{BasicConsumeOptions, ExchangeDeclareOptions, QueueBindOptions, QueueDeclareOptions}, + types::{AMQPValue, FieldTable}, + Channel, Connection, ConnectionProperties, }; use revolt_config::{config, Settings}; -use tokio::sync::Notify; +use revolt_database::Database; +use tokio::signal::ctrl_c; mod consumers; mod utils; @@ -24,6 +23,8 @@ use consumers::{ outbound::{apn::ApnsOutboundConsumer, fcm::FcmOutboundConsumer, vapid::VapidOutboundConsumer}, }; +use crate::utils::{Consumer, Delegate}; + #[tokio::main(flavor = "multi_thread", worker_threads = 2)] async fn main() { // Configure logging and environment @@ -43,7 +44,24 @@ async fn main() { panic!("Mongo is not in use, can't connect via authifier!") } - let mut connections: Vec<(Channel, Connection)> = Vec::new(); + let config = config().await; + + let connection = Arc::new( + Connection::connect( + &format!( + "amqp://{}:{}@{}:{}", + &config.rabbit.username, + &config.rabbit.password, + &config.rabbit.host, + &config.rabbit.port, + ), + ConnectionProperties::default(), + ) + .await + .expect("Failed to connect to RabbitMQ"), + ); + + let mut channels = Vec::new(); // An explainer of how this works: // The inbound connections are on separate routing keys, such that they only receive the proper payload @@ -54,171 +72,178 @@ async fn main() { // This'll require some interesting shimming if we need to add more events once this is in prod (different payloads between prod and test), // but that sounds like a problem for future us. - let config = config().await; - - // inbound: generic - connections.push( - make_queue_and_consume( + channels.push( + make_queue_and_consume::( + &db, + &authifier, + &connection, &config, &config.pushd.generic_queue, - config.pushd.get_generic_routing_key().as_str(), + &config.pushd.get_generic_routing_key(), None, - GenericConsumer::new(db.clone(), authifier.clone()), ) .await, ); - // inbound: messages - connections.push( - make_queue_and_consume( + channels.push( + make_queue_and_consume::( + &db, + &authifier, + &connection, &config, &config.pushd.message_queue, - config.pushd.get_message_routing_key().as_str(), + &config.pushd.get_message_routing_key(), None, - MessageConsumer::new(db.clone(), authifier.clone()), ) .await, ); - // inbound: FR received - connections.push( - make_queue_and_consume( + channels.push( + make_queue_and_consume::( + &db, + &authifier, + &connection, &config, &config.pushd.fr_received_queue, - config.pushd.get_fr_received_routing_key().as_str(), + &config.pushd.get_fr_received_routing_key(), None, - FRReceivedConsumer::new(db.clone(), authifier.clone()), ) .await, ); - // inbound: FR accepted - connections.push( - make_queue_and_consume( + channels.push( + make_queue_and_consume::( + &db, + &authifier, + &connection, &config, &config.pushd.fr_accepted_queue, - config.pushd.get_fr_accepted_routing_key().as_str(), + &config.pushd.get_fr_accepted_routing_key(), None, - FRAcceptedConsumer::new(db.clone(), authifier.clone()), ) .await, ); - // inbound: Mass Mentions - connections.push( - make_queue_and_consume( + channels.push( + make_queue_and_consume::( + &db, + &authifier, + &connection, &config, &config.pushd.mass_mention_queue, - config.pushd.get_mass_mention_routing_key().as_str(), + &config.pushd.get_mass_mention_routing_key(), None, - MassMessageConsumer::new(db.clone(), authifier.clone()), ) .await, ); - // inbound: Dm Calls - connections.push( - make_queue_and_consume( + channels.push( + make_queue_and_consume::( + &db, + &authifier, + &connection, &config, &config.pushd.dm_call_queue, - config.pushd.get_dm_call_routing_key().as_str(), + &config.pushd.get_dm_call_routing_key(), None, - DmCallConsumer::new(db.clone(), authifier.clone()), ) .await, ); if !config.pushd.apn.pkcs8.is_empty() { - connections.push( - make_queue_and_consume( + channels.push( + make_queue_and_consume::( + &db, + &authifier, + &connection, &config, &config.pushd.apn.queue, &config.pushd.apn.queue, None, - ApnsOutboundConsumer::new(db.clone()).await.unwrap(), ) .await, ); - let mut table = FieldTable::new(); - table.insert("x-message-deduplication".try_into().unwrap(), "true".into()); + let mut table = FieldTable::default(); + table.insert("x-message-deduplication".into(), AMQPValue::Boolean(true)); - connections.push( - make_queue_and_consume( + channels.push( + make_queue_and_consume::( + &db, + &authifier, + &connection, &config, &config.pushd.ack_queue, &config.pushd.ack_queue, Some(table), - AckConsumer::new(db.clone(), authifier.clone()), ) .await, ); } if !config.pushd.fcm.auth_uri.is_empty() { - connections.push( - make_queue_and_consume( + channels.push( + make_queue_and_consume::( + &db, + &authifier, + &connection, &config, &config.pushd.fcm.queue, &config.pushd.fcm.queue, None, - FcmOutboundConsumer::new(db.clone()).await.unwrap(), ) .await, - ) + ); } if !config.pushd.vapid.public_key.is_empty() { - connections.push( - make_queue_and_consume( + channels.push( + make_queue_and_consume::( + &db, + &authifier, + &connection, &config, &config.pushd.vapid.queue, &config.pushd.vapid.queue, None, - VapidOutboundConsumer::new(db.clone()).await.unwrap(), ) .await, - ) + ); } - let guard = Notify::new(); - guard.notified().await; + ctrl_c().await.unwrap(); - for (channel, conn) in connections { - channel.close().await.expect("Unable to close channel"); - conn.close().await.expect("Unable to close connection"); + for channel in channels { + let _ = channel.close(0, "close".into()).await; } } async fn make_queue_and_consume( + db: &Database, + authifier_db: &authifier::Database, + connection: &Arc, config: &Settings, queue_name: &str, routing_key: &str, queue_args: Option, - consumer: F, -) -> (Channel, Connection) +) -> Arc where - F: AsyncConsumer + Send + 'static, + F: Consumer, { - let connection = Connection::open(&OpenConnectionArguments::new( - &config.rabbit.host, - config.rabbit.port, - &config.rabbit.username, - &config.rabbit.password, - )) - .await - .unwrap(); - - let channel = connection.open_channel(None).await.unwrap(); + let channel = Arc::new(connection.create_channel().await.unwrap()); channel .exchange_declare( - ExchangeDeclareArguments::new(&config.pushd.exchange, "direct") - .durable(true) - .finish(), + config.pushd.exchange.clone().into(), + lapin::ExchangeKind::Direct, + ExchangeDeclareOptions { + durable: true, + ..Default::default() + }, + FieldTable::default(), ) .await - .expect("Failed to declare pushd exchange"); + .expect("Failed to declare exchange"); let mut queue_name = queue_name.to_string(); @@ -230,35 +255,59 @@ where let queue_name = queue_name.as_str(); - let mut args = QueueDeclareArguments::new(queue_name); - args.durable(true); + let args = QueueDeclareOptions { + durable: true, + ..Default::default() + }; - if let Some(arg) = queue_args { - args.arguments(arg); - } - - let args = args.finish(); - _ = channel.queue_declare(args).await.unwrap().unwrap(); + channel + .queue_declare(queue_name.into(), args, queue_args.unwrap_or_default()) + .await + .unwrap(); channel - .queue_bind(QueueBindArguments::new( - queue_name, - &config.pushd.exchange, - routing_key, - )) + .queue_bind( + queue_name.into(), + config.pushd.exchange.clone().into(), + routing_key.into(), + QueueBindOptions::default(), + FieldTable::default(), + ) .await .expect( "This probably means the revolt.notifications exchange does not exist in rabbitmq!", ); - let args = BasicConsumeArguments::new(queue_name, "") - .manual_ack(false) - .finish(); - - let routing_key = channel.basic_consume(consumer, args).await.unwrap(); + let consumer = channel + .basic_consume( + queue_name.into(), + "".into(), + BasicConsumeOptions { + no_ack: true, + ..Default::default() + }, + FieldTable::default(), + ) + .await + .unwrap(); info!( "Consuming routing key {} as queue {}, tag {}", - routing_key, queue_name, routing_key + routing_key, + queue_name, + consumer.tag() ); - (channel, connection) + + let delegate = Delegate( + F::create( + db.clone(), + authifier_db.clone(), + connection.clone(), + channel.clone(), + ) + .await, + ); + + consumer.set_delegate(delegate); + + channel } diff --git a/crates/daemons/pushd/src/utils/consumer.rs b/crates/daemons/pushd/src/utils/consumer.rs new file mode 100644 index 000000000..9006aa32c --- /dev/null +++ b/crates/daemons/pushd/src/utils/consumer.rs @@ -0,0 +1,91 @@ +use std::{ + future::{ready, Future}, + pin::Pin, + sync::Arc, +}; + +use anyhow::Result; +use async_trait::async_trait; +use lapin::{ + message::{Delivery, DeliveryResult}, + options::BasicPublishOptions, + BasicProperties, Channel, Connection, ConsumerDelegate, Error as AMQPError, +}; +use log::debug; +use revolt_database::Database; + +#[async_trait] +pub trait Consumer: Clone + Send + Sync + 'static { + async fn create( + db: Database, + authifier_db: authifier::Database, + connection: Arc, + channel: Arc, + ) -> Self; + fn channel(&self) -> &Arc; + async fn consume(&self, delivery: Delivery) -> Result<()>; + + async fn publish_message_with_options( + &self, + payload: &[u8], + exchange: &str, + routing_key: &str, + options: BasicPublishOptions, + properties: BasicProperties, + ) -> Result<(), AMQPError> { + let channel = self.channel(); + + channel + .basic_publish( + exchange.into(), + routing_key.into(), + options, + payload, + properties, + ) + .await?; + debug!("Sent message to queue for target {}", routing_key); + + Ok(()) + } + + async fn publish_message( + &self, + payload: &[u8], + exchange: &str, + routing_key: &str, + ) -> Result<(), AMQPError> { + self.publish_message_with_options( + payload, + exchange, + routing_key, + BasicPublishOptions::default(), + BasicProperties::default(), + ) + .await + } +} + +pub struct Delegate(pub C); + +impl ConsumerDelegate for Delegate { + fn on_new_delivery( + &self, + delivery: DeliveryResult, + ) -> Pin + Send>> { + match delivery { + Ok(Some(delivery)) => { + let consumer = self.0.clone(); + + Box::pin(async move { + if let Err(e) = consumer.consume(delivery).await { + revolt_config::capture_anyhow(&e); + log::error!("{e:?}"); + }; + }) + } + Ok(None) => Box::pin(ready(())), + Err(e) => Box::pin(async move { log::error!("Received bad delivery: {e:?}") }), + } + } +} diff --git a/crates/daemons/pushd/src/utils/mod.rs b/crates/daemons/pushd/src/utils/mod.rs index 62032e80b..2a6866e0f 100644 --- a/crates/daemons/pushd/src/utils/mod.rs +++ b/crates/daemons/pushd/src/utils/mod.rs @@ -1,2 +1,5 @@ mod renderer; +mod consumer; + pub use renderer::render_notification_content; +pub use consumer::{Consumer, Delegate}; \ No newline at end of file diff --git a/crates/daemons/voice-ingress/Cargo.toml b/crates/daemons/voice-ingress/Cargo.toml index 05ea4a60c..e69967425 100644 --- a/crates/daemons/voice-ingress/Cargo.toml +++ b/crates/daemons/voice-ingress/Cargo.toml @@ -44,6 +44,3 @@ revolt-permissions = { workspace = true } livekit-api = { workspace = true } livekit-protocol = { workspace = true } livekit-runtime = { workspace = true, features = ["tokio"] } - -# RabbitMQ -amqprs = { workspace = true } diff --git a/crates/daemons/voice-ingress/src/main.rs b/crates/daemons/voice-ingress/src/main.rs index 727e1a259..45191c2c5 100644 --- a/crates/daemons/voice-ingress/src/main.rs +++ b/crates/daemons/voice-ingress/src/main.rs @@ -13,7 +13,7 @@ mod guard; async fn main() -> Result<(), rocket::Error> { revolt_config::configure!(voice_ingress); - let amqp = AMQP::new_auto().await.unwrap(); + let amqp = AMQP::new_auto().await; let database = DatabaseInfo::Auto.connect().await.unwrap(); let voice_client = VoiceClient::from_revolt_config().await; diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index a74c5547b..535da2afb 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -64,7 +64,7 @@ schemars = { workspace = true } revolt_rocket_okapi = { workspace = true, features = ["swagger"] } # rabbit -amqprs = { workspace = true } +lapin = { workspace = true, features = ["tokio"] } # core authifier = { workspace = true } diff --git a/crates/delta/src/main.rs b/crates/delta/src/main.rs index 41f8fc026..c1dd1dac0 100644 --- a/crates/delta/src/main.rs +++ b/crates/delta/src/main.rs @@ -9,8 +9,7 @@ pub mod routes; pub mod util; use revolt_config::config; -use revolt_database::events::client::EventV1; -use revolt_database::AMQP; +use revolt_database::{AMQP, events::client::EventV1}; use revolt_ratelimits::rocket as ratelimiter; use rocket::{Build, Rocket}; use rocket_cors::{AllowedOrigins, CorsOptions}; @@ -18,10 +17,6 @@ use rocket_prometheus::PrometheusMetrics; use std::net::Ipv4Addr; use std::str::FromStr; -use amqprs::{ - channel::ExchangeDeclareArguments, - connection::{Connection, OpenConnectionArguments}, -}; use async_std::channel::unbounded; use authifier::AuthifierEvent; use revolt_database::voice::VoiceClient; @@ -36,7 +31,6 @@ pub async fn web() -> Rocket { // Setup database let db = revolt_database::DatabaseInfo::Auto.connect().await.unwrap(); - log::info!("database_here {db:?}"); db.migrate_database().await.unwrap(); // Setup Authifier event channel @@ -96,33 +90,8 @@ pub async fn web() -> Rocket { // Voice handler let voice_client = VoiceClient::new(config.api.livekit.nodes.clone()); // Configure Rabbit - let connection = Connection::open(&OpenConnectionArguments::new( - &config.rabbit.host, - config.rabbit.port, - &config.rabbit.username, - &config.rabbit.password, - )) - .await - .expect("Failed to connect to RabbitMQ"); - - let channel = connection - .open_channel(None) - .await - .expect("Failed to open RabbitMQ channel"); - - channel - .exchange_declare( - ExchangeDeclareArguments::new(&config.pushd.exchange, "direct") - .durable(true) - .finish(), - ) - .await - .expect("Failed to declare exchange"); - - let mut amqp = AMQP::new(connection, channel); - // amqp.configure_channels() - // .await - // .expect("Failed to configure channels"); + + let amqp = AMQP::new_auto().await; // Launch background task workers revolt_database::tasks::start_workers(db.clone(), amqp.clone()); diff --git a/crates/delta/src/util/test.rs b/crates/delta/src/util/test.rs index a62515091..3c8d6835c 100644 --- a/crates/delta/src/util/test.rs +++ b/crates/delta/src/util/test.rs @@ -4,7 +4,7 @@ use authifier::{ }; use futures::StreamExt; use rand::Rng; -use redis_kiss::redis::aio::PubSub; +use redis_kiss::{redis::aio::PubSub}; use revolt_database::{ events::client::EventV1, Channel, Database, Member, Message, PartialRole, Server, User, AMQP, }; @@ -25,8 +25,6 @@ pub struct TestHarness { impl TestHarness { pub async fn new() -> TestHarness { - let config = revolt_config::config().await; - let client = Client::tracked(crate::web().await) .await .expect("valid rocket instance"); @@ -49,19 +47,7 @@ impl TestHarness { .expect("`Authifier`") .clone(); - let connection = amqprs::connection::Connection::open( - &amqprs::connection::OpenConnectionArguments::new( - &config.rabbit.host, - config.rabbit.port, - &config.rabbit.username, - &config.rabbit.password, - ), - ) - .await - .unwrap(); - let channel = connection.open_channel(None).await.unwrap(); - - let amqp = AMQP::new(connection, channel); + let amqp = AMQP::new_auto().await; TestHarness { client, From 03b52655ff5006d5466133235633cc8bd7513109 Mon Sep 17 00:00:00 2001 From: "stoat-release[bot]" <245062572+stoat-release[bot]@users.noreply.github.com> Date: Mon, 18 May 2026 15:53:42 -0700 Subject: [PATCH 184/211] chore(main): release 0.13.6 (#762) * chore(main): release 0.13.6 * chore: update Cargo.lock Signed-off-by: github-actions[bot] --------- Signed-off-by: github-actions[bot] Co-authored-by: stoat-release[bot] <245062572+stoat-release[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] --- .release-please-manifest.json | 2 +- CHANGELOG.md | 21 +++++++++++++++ Cargo.lock | 36 ++++++++++++------------- Cargo.toml | 20 +++++++------- crates/bonfire/Cargo.toml | 2 +- crates/core/coalesced/Cargo.toml | 2 +- crates/core/config/Cargo.toml | 2 +- crates/core/database/Cargo.toml | 2 +- crates/core/files/Cargo.toml | 2 +- crates/core/models/Cargo.toml | 2 +- crates/core/parser/Cargo.toml | 2 +- crates/core/permissions/Cargo.toml | 2 +- crates/core/presence/Cargo.toml | 2 +- crates/core/ratelimits/Cargo.toml | 2 +- crates/core/result/Cargo.toml | 2 +- crates/daemons/crond/Cargo.toml | 2 +- crates/daemons/pushd/Cargo.toml | 2 +- crates/daemons/voice-ingress/Cargo.toml | 2 +- crates/delta/Cargo.toml | 2 +- crates/services/autumn/Cargo.toml | 2 +- crates/services/gifbox/Cargo.toml | 2 +- crates/services/january/Cargo.toml | 2 +- version.txt | 2 +- 23 files changed, 69 insertions(+), 48 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 429a83fc6..59c119ef9 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.13.5" + ".": "0.13.6" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 1921756b8..2a9c37a98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,26 @@ # Changelog +## [0.13.6](https://github.com/stoatchat/stoatchat/compare/v0.13.5...v0.13.6) (2026-05-18) + + +### Features + +* Update FCM payload for android notifications ([#766](https://github.com/stoatchat/stoatchat/issues/766)) ([acbc087](https://github.com/stoatchat/stoatchat/commit/acbc087982e9aeb05cabc5ab4c9b1291f67490ad)) +* user slowmode events ([#760](https://github.com/stoatchat/stoatchat/issues/760)) ([af0d8aa](https://github.com/stoatchat/stoatchat/commit/af0d8aad14dc68d88159d0e1c714077d362e21e4)) + + +### Bug Fixes + +* include `minio` region as tests need it ([#761](https://github.com/stoatchat/stoatchat/issues/761)) ([298742d](https://github.com/stoatchat/stoatchat/commit/298742dbad4eafae356f976c56b9db23904b0c3a)) +* set env var for publishing crates ([#768](https://github.com/stoatchat/stoatchat/issues/768)) ([018afaf](https://github.com/stoatchat/stoatchat/commit/018afaf38f6330d92dad2a68b640c0cb3f6b639a)) +* Use proper headers to determine IP when not behind cloudflare ([#764](https://github.com/stoatchat/stoatchat/issues/764)) ([494c8b7](https://github.com/stoatchat/stoatchat/commit/494c8b7cabaae2a51039a7a5b559d5e2e5279554)) +* voice ingress crashing due to new Result in AMQP::new_auto() ([#765](https://github.com/stoatchat/stoatchat/issues/765)) ([2871632](https://github.com/stoatchat/stoatchat/commit/2871632382395cb20cbe0047c542d3ac31ff3f03)) + + +### Miscellaneous Chores + +* switch to lapin ([#767](https://github.com/stoatchat/stoatchat/issues/767)) ([5b19853](https://github.com/stoatchat/stoatchat/commit/5b1985381ae829a92c80a19e91a414cd9dc4de93)) + ## [0.13.5](https://github.com/stoatchat/stoatchat/compare/v0.13.4...v0.13.5) (2026-05-17) diff --git a/Cargo.lock b/Cargo.lock index c65f954ef..69e48fdce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7488,7 +7488,7 @@ dependencies = [ [[package]] name = "revolt-autumn" -version = "0.13.5" +version = "0.13.6" dependencies = [ "axum", "axum-macros", @@ -7529,7 +7529,7 @@ dependencies = [ [[package]] name = "revolt-bonfire" -version = "0.13.5" +version = "0.13.6" dependencies = [ "async-channel 2.5.0", "async-std", @@ -7560,7 +7560,7 @@ dependencies = [ [[package]] name = "revolt-coalesced" -version = "0.13.5" +version = "0.13.6" dependencies = [ "indexmap 2.13.1", "lru", @@ -7569,7 +7569,7 @@ dependencies = [ [[package]] name = "revolt-config" -version = "0.13.5" +version = "0.13.6" dependencies = [ "async-std", "cached", @@ -7586,7 +7586,7 @@ dependencies = [ [[package]] name = "revolt-crond" -version = "0.13.5" +version = "0.13.6" dependencies = [ "futures-lite", "iso8601-timestamp", @@ -7606,7 +7606,7 @@ dependencies = [ [[package]] name = "revolt-database" -version = "0.13.5" +version = "0.13.6" dependencies = [ "async-lock 2.8.0", "async-recursion", @@ -7657,7 +7657,7 @@ dependencies = [ [[package]] name = "revolt-delta" -version = "0.13.5" +version = "0.13.6" dependencies = [ "async-channel 2.5.0", "async-std", @@ -7706,7 +7706,7 @@ dependencies = [ [[package]] name = "revolt-files" -version = "0.13.5" +version = "0.13.6" dependencies = [ "aes-gcm", "anyhow", @@ -7734,7 +7734,7 @@ dependencies = [ [[package]] name = "revolt-gifbox" -version = "0.13.5" +version = "0.13.6" dependencies = [ "axum", "axum-extra", @@ -7757,7 +7757,7 @@ dependencies = [ [[package]] name = "revolt-january" -version = "0.13.5" +version = "0.13.6" dependencies = [ "async-recursion", "axum", @@ -7787,7 +7787,7 @@ dependencies = [ [[package]] name = "revolt-models" -version = "0.13.5" +version = "0.13.6" dependencies = [ "indexmap 2.13.1", "iso8601-timestamp", @@ -7806,14 +7806,14 @@ dependencies = [ [[package]] name = "revolt-parser" -version = "0.13.5" +version = "0.13.6" dependencies = [ "logos", ] [[package]] name = "revolt-permissions" -version = "0.13.5" +version = "0.13.6" dependencies = [ "async-std", "async-trait", @@ -7828,7 +7828,7 @@ dependencies = [ [[package]] name = "revolt-presence" -version = "0.13.5" +version = "0.13.6" dependencies = [ "async-std", "log", @@ -7840,7 +7840,7 @@ dependencies = [ [[package]] name = "revolt-pushd" -version = "0.13.5" +version = "0.13.6" dependencies = [ "anyhow", "async-trait", @@ -7871,7 +7871,7 @@ dependencies = [ [[package]] name = "revolt-ratelimits" -version = "0.13.5" +version = "0.13.6" dependencies = [ "async-trait", "authifier", @@ -7888,7 +7888,7 @@ dependencies = [ [[package]] name = "revolt-result" -version = "0.13.5" +version = "0.13.6" dependencies = [ "axum", "log", @@ -7904,7 +7904,7 @@ dependencies = [ [[package]] name = "revolt-voice-ingress" -version = "0.13.5" +version = "0.13.6" dependencies = [ "async-std", "chrono", diff --git a/Cargo.toml b/Cargo.toml index 3b2b92fa2..d530ac309 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -191,13 +191,13 @@ futures-lite = "2.6.1" vergen = "7.5.0" # Local packages -revolt-coalesced = { version = "0.13.5", path = "crates/core/coalesced" } -revolt-config = { version = "0.13.5", path = "crates/core/config" } -revolt-database = { version = "0.13.5", path = "crates/core/database" } -revolt-files = { version = "0.13.5", path = "crates/core/files" } -revolt-models = { version = "0.13.5", path = "crates/core/models" } -revolt-parser = { version = "0.13.5", path = "crates/core/parser" } -revolt-permissions = { version = "0.13.5", path = "crates/core/permissions" } -revolt-presence = { version = "0.13.5", path = "crates/core/presence" } -revolt-ratelimits = { version = "0.13.5", path = "crates/core/ratelimits" } -revolt-result = { version = "0.13.5", path = "crates/core/result" } +revolt-coalesced = { version = "0.13.6", path = "crates/core/coalesced" } +revolt-config = { version = "0.13.6", path = "crates/core/config" } +revolt-database = { version = "0.13.6", path = "crates/core/database" } +revolt-files = { version = "0.13.6", path = "crates/core/files" } +revolt-models = { version = "0.13.6", path = "crates/core/models" } +revolt-parser = { version = "0.13.6", path = "crates/core/parser" } +revolt-permissions = { version = "0.13.6", path = "crates/core/permissions" } +revolt-presence = { version = "0.13.6", path = "crates/core/presence" } +revolt-ratelimits = { version = "0.13.6", path = "crates/core/ratelimits" } +revolt-result = { version = "0.13.6", path = "crates/core/result" } diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index c0fbe500c..d570b52be 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-bonfire" -version = "0.13.5" +version = "0.13.6" license = "AGPL-3.0-or-later" edition = "2021" publish = false diff --git a/crates/core/coalesced/Cargo.toml b/crates/core/coalesced/Cargo.toml index 7c8bdcb97..e501633d4 100644 --- a/crates/core/coalesced/Cargo.toml +++ b/crates/core/coalesced/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-coalesced" -version = "0.13.5" +version = "0.13.6" edition = "2021" license = "MIT" authors = ["Paul Makles ", "Zomatree "] diff --git a/crates/core/config/Cargo.toml b/crates/core/config/Cargo.toml index c8be6a4f6..d6a592450 100644 --- a/crates/core/config/Cargo.toml +++ b/crates/core/config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-config" -version = "0.13.5" +version = "0.13.6" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index dc213fd07..2294cc293 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-database" -version = "0.13.5" +version = "0.13.6" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] diff --git a/crates/core/files/Cargo.toml b/crates/core/files/Cargo.toml index a17be124e..b38620ff7 100644 --- a/crates/core/files/Cargo.toml +++ b/crates/core/files/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-files" -version = "0.13.5" +version = "0.13.6" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] diff --git a/crates/core/models/Cargo.toml b/crates/core/models/Cargo.toml index 75976fc5f..a94816d17 100644 --- a/crates/core/models/Cargo.toml +++ b/crates/core/models/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-models" -version = "0.13.5" +version = "0.13.6" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/core/parser/Cargo.toml b/crates/core/parser/Cargo.toml index e73e09940..7c217006f 100644 --- a/crates/core/parser/Cargo.toml +++ b/crates/core/parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-parser" -version = "0.13.5" +version = "0.13.6" edition = "2021" license = "MIT" authors = ["Zomatree ", "Paul Makles "] diff --git a/crates/core/permissions/Cargo.toml b/crates/core/permissions/Cargo.toml index 3ffbf1b11..bac29b7af 100644 --- a/crates/core/permissions/Cargo.toml +++ b/crates/core/permissions/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-permissions" -version = "0.13.5" +version = "0.13.6" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/core/presence/Cargo.toml b/crates/core/presence/Cargo.toml index f48182f78..c5743e5c2 100644 --- a/crates/core/presence/Cargo.toml +++ b/crates/core/presence/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-presence" -version = "0.13.5" +version = "0.13.6" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] diff --git a/crates/core/ratelimits/Cargo.toml b/crates/core/ratelimits/Cargo.toml index 7d5be0c19..1f17c28ad 100644 --- a/crates/core/ratelimits/Cargo.toml +++ b/crates/core/ratelimits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-ratelimits" -version = "0.13.5" +version = "0.13.6" edition = "2024" license = "MIT" authors = ["Zomatree ", "Paul Makles "] diff --git a/crates/core/result/Cargo.toml b/crates/core/result/Cargo.toml index 25caa4965..f5d23dd2a 100644 --- a/crates/core/result/Cargo.toml +++ b/crates/core/result/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-result" -version = "0.13.5" +version = "0.13.6" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/daemons/crond/Cargo.toml b/crates/daemons/crond/Cargo.toml index 8b1d0376f..249c11295 100644 --- a/crates/daemons/crond/Cargo.toml +++ b/crates/daemons/crond/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-crond" -version = "0.13.5" +version = "0.13.6" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2021" diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index 8fb22999f..3eeb084d5 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-pushd" -version = "0.13.5" +version = "0.13.6" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/crates/daemons/voice-ingress/Cargo.toml b/crates/daemons/voice-ingress/Cargo.toml index e69967425..f43f025bc 100644 --- a/crates/daemons/voice-ingress/Cargo.toml +++ b/crates/daemons/voice-ingress/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-voice-ingress" -version = "0.13.5" +version = "0.13.6" license = "AGPL-3.0-or-later" edition = "2021" publish = false diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index 535da2afb..4fda6be0a 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-delta" -version = "0.13.5" +version = "0.13.6" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2018" diff --git a/crates/services/autumn/Cargo.toml b/crates/services/autumn/Cargo.toml index c45d85227..ef46936b0 100644 --- a/crates/services/autumn/Cargo.toml +++ b/crates/services/autumn/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-autumn" -version = "0.13.5" +version = "0.13.6" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/crates/services/gifbox/Cargo.toml b/crates/services/gifbox/Cargo.toml index 5fbcba088..8bec9132b 100644 --- a/crates/services/gifbox/Cargo.toml +++ b/crates/services/gifbox/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-gifbox" -version = "0.13.5" +version = "0.13.6" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/crates/services/january/Cargo.toml b/crates/services/january/Cargo.toml index 55ae526ed..b1e36ccb1 100644 --- a/crates/services/january/Cargo.toml +++ b/crates/services/january/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-january" -version = "0.13.5" +version = "0.13.6" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/version.txt b/version.txt index c37136a84..ebf55b3d7 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.13.5 +0.13.6 From 0d9ae508d9d2199f0e408b8ca634d20489be6f61 Mon Sep 17 00:00:00 2001 From: Zomatree Date: Tue, 19 May 2026 07:38:07 +0100 Subject: [PATCH 185/211] fix: update mention count badge for channel acks (#769) Signed-off-by: Zomatree --- crates/daemons/crond/src/main.rs | 6 ++-- crates/daemons/crond/src/tasks/acks.rs | 49 +++++++++++++------------- 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/crates/daemons/crond/src/main.rs b/crates/daemons/crond/src/main.rs index c45780d5e..2b9a82f65 100644 --- a/crates/daemons/crond/src/main.rs +++ b/crates/daemons/crond/src/main.rs @@ -1,5 +1,5 @@ use revolt_config::configure; -use revolt_database::DatabaseInfo; +use revolt_database::{DatabaseInfo, AMQP}; use revolt_result::Result; use tasks::{acks, file_deletion, prune_dangling_files, prune_members}; use tokio::try_join; @@ -11,11 +11,13 @@ async fn main() -> Result<()> { configure!(crond); let db = DatabaseInfo::Auto.connect().await.expect("database"); + let amqp = AMQP::new_auto().await; + try_join!( file_deletion::task(db.clone()), prune_dangling_files::task(db.clone()), prune_members::task(db.clone()), - acks::task(db.clone()) + acks::task(db.clone(), amqp.clone()), ) .map(|_| ()) } diff --git a/crates/daemons/crond/src/tasks/acks.rs b/crates/daemons/crond/src/tasks/acks.rs index 2a3dc3a66..7576bac9b 100644 --- a/crates/daemons/crond/src/tasks/acks.rs +++ b/crates/daemons/crond/src/tasks/acks.rs @@ -5,14 +5,14 @@ use lapin::{ uri::{AMQPAuthority, AMQPQueryString, AMQPUri, AMQPUserInfo}, ConnectionBuilder, ConnectionProperties, ExchangeKind, }; -use log::info; +use log::{debug, info}; use redis_kiss::{get_connection, AsyncCommands, Conn as RedisConnection}; use revolt_config::config; -use revolt_database::{events::rabbit::AckEventPayload, Database}; +use revolt_database::{events::rabbit::AckEventPayload, Database, AMQP}; use revolt_result::{Result, ToRevoltError}; use serde_json; -pub async fn task(db: Database) -> Result<()> { +pub async fn task(db: Database, amqp: AMQP) -> Result<()> { let config = config().await; let mut redis = get_connection() @@ -94,12 +94,14 @@ pub async fn task(db: Database) -> Result<()> { while let Some(delivery) = consumer.next().await { if let Ok(delivery) = delivery { - let payload: std::result::Result = - serde_json::from_slice(&delivery.data); + let payload = serde_json::from_slice::(&delivery.data); + if let Ok(payload) = payload { - info!("{:?}", payload); + debug!("Received ack event: {payload:?}"); + if let Err(e) = process_channel_ack( &db, + &amqp, payload.user_id, payload.channel_id.unwrap(), &mut redis, @@ -125,6 +127,7 @@ pub async fn task(db: Database) -> Result<()> { #[allow(clippy::disallowed_methods)] async fn process_channel_ack( db: &Database, + amqp: &AMQP, user: String, channel: String, redis: &mut RedisConnection, @@ -135,28 +138,24 @@ async fn process_channel_ack( .to_internal_error()?; if let Some(message_id) = message_id { - // This will be uncommented eventually, but we need to sort out the transition to lapin first. For now we'll simply disable the badge update logic. - // We also drop a db request as a bonus. + let unread = db.fetch_unread(&user, &channel).await?; + let updated = db.acknowledge_message(&channel, &user, &message_id).await?; - //let unread = db.fetch_unread(&user, &channel).await?; - let _updated = db.acknowledge_message(&channel, &user, &message_id).await?; info!("Set new state for ack: {}:{}:{}", channel, user, message_id); - // if let (Some(before), Some(after)) = (unread, updated) { - // let before_mentions = before.mentions.unwrap_or_default().len(); - // let after_mentions = after.mentions.unwrap_or_default().len(); - - // let mentions_acked = before_mentions - after_mentions; - - // if mentions_acked > 0 { - // if let Err(err) = amqp - // .ack_message(user.to_string(), channel.to_string(), payload.message_id) - // .await - // { - // revolt_config::capture_error(&err); - // } - // }; - // } + if let (Some(before), Some(after)) = (unread, updated) { + let before_mentions = before.mentions.unwrap_or_default().len(); + let after_mentions = after.mentions.unwrap_or_default().len(); + + if after_mentions < before_mentions { + if let Err(err) = amqp + .ack_notification_message(user.to_string(), channel.to_string(), message_id) + .await + { + revolt_config::capture_error(&err); + } + }; + } Ok(()) } else { From 4815429952e4736b83baa8c4a57be82fc96cc79a Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Wed, 20 May 2026 13:58:18 -0500 Subject: [PATCH 186/211] ci: create Docker images for PR preview (#772) --- .github/workflows/docker-cleanup.yaml | 56 +++++++++++++++++++++++++++ .github/workflows/docker.yaml | 37 +++++++++++------- 2 files changed, 79 insertions(+), 14 deletions(-) create mode 100644 .github/workflows/docker-cleanup.yaml diff --git a/.github/workflows/docker-cleanup.yaml b/.github/workflows/docker-cleanup.yaml new file mode 100644 index 000000000..61121259c --- /dev/null +++ b/.github/workflows/docker-cleanup.yaml @@ -0,0 +1,56 @@ +name: Docker PR Image Cleanup + +on: + pull_request: + types: + - closed + +permissions: + contents: read + packages: write + +concurrency: + group: docker-cleanup-${{ github.event.pull_request.number }} + cancel-in-progress: false + +jobs: + enumerate: + runs-on: ubuntu-latest + if: ${{ !github.event.pull_request.head.repo.fork }} + outputs: + packages: ${{ steps.list.outputs.packages }} + steps: + - id: list + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + ORG: stoatchat + REPO: ${{ github.repository }} + run: | + set -euo pipefail + packages=$(gh api --paginate \ + "/orgs/${ORG}/packages?package_type=container" \ + --jq "[.[] | select(.repository.full_name == \"${REPO}\") | .name]") + echo "packages=${packages}" >> "$GITHUB_OUTPUT" + + cleanup: + needs: enumerate + runs-on: ubuntu-latest + if: ${{ needs.enumerate.outputs.packages != '[]' }} + strategy: + fail-fast: false + matrix: + package: ${{ fromJSON(needs.enumerate.outputs.packages) }} + steps: + - env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + ORG: stoatchat + PACKAGE: ${{ matrix.package }} + TAG: pr-${{ github.event.pull_request.number }} + run: | + set -euo pipefail + gh api --paginate \ + "/orgs/${ORG}/packages/container/${PACKAGE}/versions" \ + --jq ".[] | select(.metadata.container.tags | index(\"${TAG}\")) | .id" \ + | while read -r id; do + gh api -X DELETE "/orgs/${ORG}/packages/container/${PACKAGE}/versions/${id}" + done diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 2be1f4387..75aefeb63 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -5,8 +5,6 @@ on: tags: - "*" pull_request: - paths: - - "Dockerfile" workflow_dispatch: permissions: @@ -19,9 +17,9 @@ concurrency: jobs: base: - name: Test base image build + name: Test base image build (fork) runs-on: arc-runner-set - if: github.event_name == 'pull_request' + if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork steps: # Configure build environment - name: Checkout @@ -42,7 +40,7 @@ jobs: publish: runs-on: arc-runner-set - if: github.event_name != 'pull_request' + if: ${{ github.event_name != 'pull_request' || !github.event.pull_request.head.repo.fork }} name: Publish Docker images steps: # Configure build environment @@ -59,6 +57,15 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Determine base image tag + id: base + run: | + if [ "${{ github.event_name }}" = "pull_request" ]; then + echo "tag=pr-${{ github.event.number }}" >> "$GITHUB_OUTPUT" + else + echo "tag=latest" >> "$GITHUB_OUTPUT" + fi + # Build the image - name: Build base image uses: docker/build-push-action@v4 @@ -66,7 +73,9 @@ jobs: context: . push: true platforms: linux/amd64,linux/arm64 - tags: ghcr.io/${{ github.repository_owner }}/base:latest + tags: ghcr.io/${{ github.repository_owner }}/base:${{ steps.base.outputs.tag }} + cache-from: type=gha,scope=buildx-base-multi-arch + cache-to: type=gha,scope=buildx-base-multi-arch,mode=max # stoatchat/api - name: Docker meta @@ -84,7 +93,7 @@ jobs: file: crates/delta/Dockerfile tags: ${{ steps.meta-delta.outputs.tags }} build-args: | - BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest + BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:${{ steps.base.outputs.tag }} labels: ${{ steps.meta-delta.outputs.labels }} # stoatchat/events @@ -103,7 +112,7 @@ jobs: file: crates/bonfire/Dockerfile tags: ${{ steps.meta-bonfire.outputs.tags }} build-args: | - BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest + BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:${{ steps.base.outputs.tag }} labels: ${{ steps.meta-bonfire.outputs.labels }} # stoatchat/file-server @@ -122,7 +131,7 @@ jobs: file: crates/services/autumn/Dockerfile tags: ${{ steps.meta-autumn.outputs.tags }} build-args: | - BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest + BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:${{ steps.base.outputs.tag }} labels: ${{ steps.meta-autumn.outputs.labels }} # stoatchat/proxy @@ -141,7 +150,7 @@ jobs: file: crates/services/january/Dockerfile tags: ${{ steps.meta-january.outputs.tags }} build-args: | - BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest + BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:${{ steps.base.outputs.tag }} labels: ${{ steps.meta-january.outputs.labels }} # stoatchat/gifbox @@ -160,7 +169,7 @@ jobs: file: crates/services/gifbox/Dockerfile tags: ${{ steps.meta-gifbox.outputs.tags }} build-args: | - BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest + BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:${{ steps.base.outputs.tag }} labels: ${{ steps.meta-gifbox.outputs.labels }} # stoatchat/crond @@ -179,7 +188,7 @@ jobs: file: crates/daemons/crond/Dockerfile tags: ${{ steps.meta-crond.outputs.tags }} build-args: | - BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest + BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:${{ steps.base.outputs.tag }} labels: ${{ steps.meta-crond.outputs.labels }} # stoatchat/pushd @@ -198,7 +207,7 @@ jobs: file: crates/daemons/pushd/Dockerfile tags: ${{ steps.meta-pushd.outputs.tags }} build-args: | - BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest + BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:${{ steps.base.outputs.tag }} labels: ${{ steps.meta-pushd.outputs.labels }} # stoatchat/voice-ingress @@ -217,5 +226,5 @@ jobs: file: crates/daemons/voice-ingress/Dockerfile tags: ${{ steps.meta-voice-ingress.outputs.tags }} build-args: | - BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest + BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:${{ steps.base.outputs.tag }} labels: ${{ steps.meta-voice-ingress.outputs.labels }} From b38499a05be489a597f681d1ff4fafae69d60603 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Wed, 20 May 2026 14:10:09 -0500 Subject: [PATCH 187/211] ci: hard code packages, gh token limitation [skip ci] (#773) --- .github/workflows/docker-cleanup.yaml | 32 +++++++++------------------ 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/.github/workflows/docker-cleanup.yaml b/.github/workflows/docker-cleanup.yaml index 61121259c..830619495 100644 --- a/.github/workflows/docker-cleanup.yaml +++ b/.github/workflows/docker-cleanup.yaml @@ -14,32 +14,22 @@ concurrency: cancel-in-progress: false jobs: - enumerate: - runs-on: ubuntu-latest - if: ${{ !github.event.pull_request.head.repo.fork }} - outputs: - packages: ${{ steps.list.outputs.packages }} - steps: - - id: list - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - ORG: stoatchat - REPO: ${{ github.repository }} - run: | - set -euo pipefail - packages=$(gh api --paginate \ - "/orgs/${ORG}/packages?package_type=container" \ - --jq "[.[] | select(.repository.full_name == \"${REPO}\") | .name]") - echo "packages=${packages}" >> "$GITHUB_OUTPUT" - cleanup: - needs: enumerate runs-on: ubuntu-latest - if: ${{ needs.enumerate.outputs.packages != '[]' }} + if: ${{ !github.event.pull_request.head.repo.fork }} strategy: fail-fast: false matrix: - package: ${{ fromJSON(needs.enumerate.outputs.packages) }} + package: + - base + - api + - events + - file-server + - proxy + - gifbox + - crond + - pushd + - voice-ingress steps: - env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 2d308e03d58c19f27b5b4d65dc2a15ef20b56190 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0spik?= Date: Thu, 21 May 2026 18:21:43 +0300 Subject: [PATCH 188/211] fix: sanitize emoji input to handle variation selectors (#774) Signed-off-by: ispik --- crates/core/database/src/models/emojis/model.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/core/database/src/models/emojis/model.rs b/crates/core/database/src/models/emojis/model.rs index 3f380716a..55d13e8c3 100644 --- a/crates/core/database/src/models/emojis/model.rs +++ b/crates/core/database/src/models/emojis/model.rs @@ -12,7 +12,7 @@ use crate::Database; static PERMISSIBLE_EMOJIS: Lazy> = Lazy::new(|| { include_str!("unicode_emoji.txt") .split('\n') - .map(|x| x.into()) + .map(|x| x.replace('\u{FE0F}', "")) .collect() }); @@ -108,7 +108,8 @@ impl Emoji { db.fetch_emoji(emoji).await?; Ok(true) } else { - Ok(PERMISSIBLE_EMOJIS.contains(emoji)) + let sanitized_emoji = emoji.replace('\u{FE0F}', ""); + Ok(PERMISSIBLE_EMOJIS.contains(&sanitized_emoji)) } } } From 7937179db771b6cafb959da9e54dc9aff3bb56b3 Mon Sep 17 00:00:00 2001 From: "stoat-release[bot]" <245062572+stoat-release[bot]@users.noreply.github.com> Date: Thu, 21 May 2026 19:33:49 +0100 Subject: [PATCH 189/211] chore(main): release 0.13.7 (#770) Co-authored-by: github-actions[bot] Signed-off-by: github-actions[bot] --- .release-please-manifest.json | 2 +- CHANGELOG.md | 8 ++++++ Cargo.lock | 36 ++++++++++++------------- Cargo.toml | 20 +++++++------- crates/bonfire/Cargo.toml | 2 +- crates/core/coalesced/Cargo.toml | 2 +- crates/core/config/Cargo.toml | 2 +- crates/core/database/Cargo.toml | 2 +- crates/core/files/Cargo.toml | 2 +- crates/core/models/Cargo.toml | 2 +- crates/core/parser/Cargo.toml | 2 +- crates/core/permissions/Cargo.toml | 2 +- crates/core/presence/Cargo.toml | 2 +- crates/core/ratelimits/Cargo.toml | 2 +- crates/core/result/Cargo.toml | 2 +- crates/daemons/crond/Cargo.toml | 2 +- crates/daemons/pushd/Cargo.toml | 2 +- crates/daemons/voice-ingress/Cargo.toml | 2 +- crates/delta/Cargo.toml | 2 +- crates/services/autumn/Cargo.toml | 2 +- crates/services/gifbox/Cargo.toml | 2 +- crates/services/january/Cargo.toml | 2 +- version.txt | 2 +- 23 files changed, 56 insertions(+), 48 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 59c119ef9..297819281 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.13.6" + ".": "0.13.7" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a9c37a98..9912f5b65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [0.13.7](https://github.com/stoatchat/stoatchat/compare/v0.13.6...v0.13.7) (2026-05-21) + + +### Bug Fixes + +* sanitize emoji input to handle variation selectors ([#774](https://github.com/stoatchat/stoatchat/issues/774)) ([2d308e0](https://github.com/stoatchat/stoatchat/commit/2d308e03d58c19f27b5b4d65dc2a15ef20b56190)) +* update mention count badge for channel acks ([#769](https://github.com/stoatchat/stoatchat/issues/769)) ([0d9ae50](https://github.com/stoatchat/stoatchat/commit/0d9ae508d9d2199f0e408b8ca634d20489be6f61)) + ## [0.13.6](https://github.com/stoatchat/stoatchat/compare/v0.13.5...v0.13.6) (2026-05-18) diff --git a/Cargo.lock b/Cargo.lock index 69e48fdce..bcd1c5acb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7488,7 +7488,7 @@ dependencies = [ [[package]] name = "revolt-autumn" -version = "0.13.6" +version = "0.13.7" dependencies = [ "axum", "axum-macros", @@ -7529,7 +7529,7 @@ dependencies = [ [[package]] name = "revolt-bonfire" -version = "0.13.6" +version = "0.13.7" dependencies = [ "async-channel 2.5.0", "async-std", @@ -7560,7 +7560,7 @@ dependencies = [ [[package]] name = "revolt-coalesced" -version = "0.13.6" +version = "0.13.7" dependencies = [ "indexmap 2.13.1", "lru", @@ -7569,7 +7569,7 @@ dependencies = [ [[package]] name = "revolt-config" -version = "0.13.6" +version = "0.13.7" dependencies = [ "async-std", "cached", @@ -7586,7 +7586,7 @@ dependencies = [ [[package]] name = "revolt-crond" -version = "0.13.6" +version = "0.13.7" dependencies = [ "futures-lite", "iso8601-timestamp", @@ -7606,7 +7606,7 @@ dependencies = [ [[package]] name = "revolt-database" -version = "0.13.6" +version = "0.13.7" dependencies = [ "async-lock 2.8.0", "async-recursion", @@ -7657,7 +7657,7 @@ dependencies = [ [[package]] name = "revolt-delta" -version = "0.13.6" +version = "0.13.7" dependencies = [ "async-channel 2.5.0", "async-std", @@ -7706,7 +7706,7 @@ dependencies = [ [[package]] name = "revolt-files" -version = "0.13.6" +version = "0.13.7" dependencies = [ "aes-gcm", "anyhow", @@ -7734,7 +7734,7 @@ dependencies = [ [[package]] name = "revolt-gifbox" -version = "0.13.6" +version = "0.13.7" dependencies = [ "axum", "axum-extra", @@ -7757,7 +7757,7 @@ dependencies = [ [[package]] name = "revolt-january" -version = "0.13.6" +version = "0.13.7" dependencies = [ "async-recursion", "axum", @@ -7787,7 +7787,7 @@ dependencies = [ [[package]] name = "revolt-models" -version = "0.13.6" +version = "0.13.7" dependencies = [ "indexmap 2.13.1", "iso8601-timestamp", @@ -7806,14 +7806,14 @@ dependencies = [ [[package]] name = "revolt-parser" -version = "0.13.6" +version = "0.13.7" dependencies = [ "logos", ] [[package]] name = "revolt-permissions" -version = "0.13.6" +version = "0.13.7" dependencies = [ "async-std", "async-trait", @@ -7828,7 +7828,7 @@ dependencies = [ [[package]] name = "revolt-presence" -version = "0.13.6" +version = "0.13.7" dependencies = [ "async-std", "log", @@ -7840,7 +7840,7 @@ dependencies = [ [[package]] name = "revolt-pushd" -version = "0.13.6" +version = "0.13.7" dependencies = [ "anyhow", "async-trait", @@ -7871,7 +7871,7 @@ dependencies = [ [[package]] name = "revolt-ratelimits" -version = "0.13.6" +version = "0.13.7" dependencies = [ "async-trait", "authifier", @@ -7888,7 +7888,7 @@ dependencies = [ [[package]] name = "revolt-result" -version = "0.13.6" +version = "0.13.7" dependencies = [ "axum", "log", @@ -7904,7 +7904,7 @@ dependencies = [ [[package]] name = "revolt-voice-ingress" -version = "0.13.6" +version = "0.13.7" dependencies = [ "async-std", "chrono", diff --git a/Cargo.toml b/Cargo.toml index d530ac309..6d1335cc4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -191,13 +191,13 @@ futures-lite = "2.6.1" vergen = "7.5.0" # Local packages -revolt-coalesced = { version = "0.13.6", path = "crates/core/coalesced" } -revolt-config = { version = "0.13.6", path = "crates/core/config" } -revolt-database = { version = "0.13.6", path = "crates/core/database" } -revolt-files = { version = "0.13.6", path = "crates/core/files" } -revolt-models = { version = "0.13.6", path = "crates/core/models" } -revolt-parser = { version = "0.13.6", path = "crates/core/parser" } -revolt-permissions = { version = "0.13.6", path = "crates/core/permissions" } -revolt-presence = { version = "0.13.6", path = "crates/core/presence" } -revolt-ratelimits = { version = "0.13.6", path = "crates/core/ratelimits" } -revolt-result = { version = "0.13.6", path = "crates/core/result" } +revolt-coalesced = { version = "0.13.7", path = "crates/core/coalesced" } +revolt-config = { version = "0.13.7", path = "crates/core/config" } +revolt-database = { version = "0.13.7", path = "crates/core/database" } +revolt-files = { version = "0.13.7", path = "crates/core/files" } +revolt-models = { version = "0.13.7", path = "crates/core/models" } +revolt-parser = { version = "0.13.7", path = "crates/core/parser" } +revolt-permissions = { version = "0.13.7", path = "crates/core/permissions" } +revolt-presence = { version = "0.13.7", path = "crates/core/presence" } +revolt-ratelimits = { version = "0.13.7", path = "crates/core/ratelimits" } +revolt-result = { version = "0.13.7", path = "crates/core/result" } diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index d570b52be..b2687266a 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-bonfire" -version = "0.13.6" +version = "0.13.7" license = "AGPL-3.0-or-later" edition = "2021" publish = false diff --git a/crates/core/coalesced/Cargo.toml b/crates/core/coalesced/Cargo.toml index e501633d4..1c8102adb 100644 --- a/crates/core/coalesced/Cargo.toml +++ b/crates/core/coalesced/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-coalesced" -version = "0.13.6" +version = "0.13.7" edition = "2021" license = "MIT" authors = ["Paul Makles ", "Zomatree "] diff --git a/crates/core/config/Cargo.toml b/crates/core/config/Cargo.toml index d6a592450..e9e329c7a 100644 --- a/crates/core/config/Cargo.toml +++ b/crates/core/config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-config" -version = "0.13.6" +version = "0.13.7" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index 2294cc293..f820c899a 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-database" -version = "0.13.6" +version = "0.13.7" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] diff --git a/crates/core/files/Cargo.toml b/crates/core/files/Cargo.toml index b38620ff7..c60bf678e 100644 --- a/crates/core/files/Cargo.toml +++ b/crates/core/files/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-files" -version = "0.13.6" +version = "0.13.7" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] diff --git a/crates/core/models/Cargo.toml b/crates/core/models/Cargo.toml index a94816d17..c92f3f8a2 100644 --- a/crates/core/models/Cargo.toml +++ b/crates/core/models/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-models" -version = "0.13.6" +version = "0.13.7" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/core/parser/Cargo.toml b/crates/core/parser/Cargo.toml index 7c217006f..5bb079acf 100644 --- a/crates/core/parser/Cargo.toml +++ b/crates/core/parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-parser" -version = "0.13.6" +version = "0.13.7" edition = "2021" license = "MIT" authors = ["Zomatree ", "Paul Makles "] diff --git a/crates/core/permissions/Cargo.toml b/crates/core/permissions/Cargo.toml index bac29b7af..03ed629d6 100644 --- a/crates/core/permissions/Cargo.toml +++ b/crates/core/permissions/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-permissions" -version = "0.13.6" +version = "0.13.7" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/core/presence/Cargo.toml b/crates/core/presence/Cargo.toml index c5743e5c2..7868342d3 100644 --- a/crates/core/presence/Cargo.toml +++ b/crates/core/presence/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-presence" -version = "0.13.6" +version = "0.13.7" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] diff --git a/crates/core/ratelimits/Cargo.toml b/crates/core/ratelimits/Cargo.toml index 1f17c28ad..e606d151f 100644 --- a/crates/core/ratelimits/Cargo.toml +++ b/crates/core/ratelimits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-ratelimits" -version = "0.13.6" +version = "0.13.7" edition = "2024" license = "MIT" authors = ["Zomatree ", "Paul Makles "] diff --git a/crates/core/result/Cargo.toml b/crates/core/result/Cargo.toml index f5d23dd2a..9cc5db3f7 100644 --- a/crates/core/result/Cargo.toml +++ b/crates/core/result/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-result" -version = "0.13.6" +version = "0.13.7" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/daemons/crond/Cargo.toml b/crates/daemons/crond/Cargo.toml index 249c11295..bb2f6ced7 100644 --- a/crates/daemons/crond/Cargo.toml +++ b/crates/daemons/crond/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-crond" -version = "0.13.6" +version = "0.13.7" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2021" diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index 3eeb084d5..9f38020ef 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-pushd" -version = "0.13.6" +version = "0.13.7" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/crates/daemons/voice-ingress/Cargo.toml b/crates/daemons/voice-ingress/Cargo.toml index f43f025bc..e28e71205 100644 --- a/crates/daemons/voice-ingress/Cargo.toml +++ b/crates/daemons/voice-ingress/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-voice-ingress" -version = "0.13.6" +version = "0.13.7" license = "AGPL-3.0-or-later" edition = "2021" publish = false diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index 4fda6be0a..87028aba7 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-delta" -version = "0.13.6" +version = "0.13.7" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2018" diff --git a/crates/services/autumn/Cargo.toml b/crates/services/autumn/Cargo.toml index ef46936b0..7c134170a 100644 --- a/crates/services/autumn/Cargo.toml +++ b/crates/services/autumn/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-autumn" -version = "0.13.6" +version = "0.13.7" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/crates/services/gifbox/Cargo.toml b/crates/services/gifbox/Cargo.toml index 8bec9132b..a569b2cd9 100644 --- a/crates/services/gifbox/Cargo.toml +++ b/crates/services/gifbox/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-gifbox" -version = "0.13.6" +version = "0.13.7" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/crates/services/january/Cargo.toml b/crates/services/january/Cargo.toml index b1e36ccb1..f72f6572d 100644 --- a/crates/services/january/Cargo.toml +++ b/crates/services/january/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-january" -version = "0.13.6" +version = "0.13.7" edition = "2021" license = "AGPL-3.0-or-later" publish = false diff --git a/version.txt b/version.txt index ebf55b3d7..5daaa7ba8 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.13.6 +0.13.7 From bd987bf72aedb8271846629e05f072247179a22d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0spik?= Date: Fri, 29 May 2026 00:55:49 +0300 Subject: [PATCH 190/211] chore: update unicode emoji list (#781) Signed-off-by: ispik --- .../src/models/emojis/unicode_emoji.txt | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/crates/core/database/src/models/emojis/unicode_emoji.txt b/crates/core/database/src/models/emojis/unicode_emoji.txt index 06e8bf749..1b08dbe0b 100644 --- a/crates/core/database/src/models/emojis/unicode_emoji.txt +++ b/crates/core/database/src/models/emojis/unicode_emoji.txt @@ -1,4 +1,3 @@ - *️⃣ 0️⃣ 1️⃣ @@ -242,6 +241,7 @@ 🆘 🆙 🆚 +🇦 🇦🇨 🇦🇩 🇦🇪 @@ -259,6 +259,7 @@ 🇦🇼 🇦🇽 🇦🇿 +🇧 🇧🇦 🇧🇧 🇧🇩 @@ -280,6 +281,7 @@ 🇧🇼 🇧🇾 🇧🇿 +🇨 🇨🇦 🇨🇨 🇨🇩 @@ -301,6 +303,7 @@ 🇨🇽 🇨🇾 🇨🇿 +🇩 🇩🇪 🇩🇬 🇩🇯 @@ -308,6 +311,7 @@ 🇩🇲 🇩🇴 🇩🇿 +🇪 🇪🇦 🇪🇨 🇪🇪 @@ -317,12 +321,14 @@ 🇪🇸 🇪🇹 🇪🇺 +🇫 🇫🇮 🇫🇯 🇫🇰 🇫🇲 🇫🇴 🇫🇷 +🇬 🇬🇦 🇬🇧 🇬🇩 @@ -342,12 +348,14 @@ 🇬🇺 🇬🇼 🇬🇾 +🇭 🇭🇰 🇭🇲 🇭🇳 🇭🇷 🇭🇹 🇭🇺 +🇮 🇮🇨 🇮🇩 🇮🇪 @@ -359,10 +367,12 @@ 🇮🇷 🇮🇸 🇮🇹 +🇯 🇯🇪 🇯🇲 🇯🇴 🇯🇵 +🇰 🇰🇪 🇰🇬 🇰🇭 @@ -374,6 +384,7 @@ 🇰🇼 🇰🇾 🇰🇿 +🇱 🇱🇦 🇱🇧 🇱🇨 @@ -385,6 +396,7 @@ 🇱🇺 🇱🇻 🇱🇾 +🇲 🇲🇦 🇲🇨 🇲🇩 @@ -408,6 +420,7 @@ 🇲🇽 🇲🇾 🇲🇿 +🇳 🇳🇦 🇳🇨 🇳🇪 @@ -420,7 +433,9 @@ 🇳🇷 🇳🇺 🇳🇿 +🇴 🇴🇲 +🇵 🇵🇦 🇵🇪 🇵🇫 @@ -435,12 +450,15 @@ 🇵🇹 🇵🇼 🇵🇾 +🇶 🇶🇦 +🇷 🇷🇪 🇷🇴 🇷🇸 🇷🇺 🇷🇼 +🇸 🇸🇦 🇸🇧 🇸🇨 @@ -462,6 +480,7 @@ 🇸🇽 🇸🇾 🇸🇿 +🇹 🇹🇦 🇹🇨 🇹🇩 @@ -479,6 +498,7 @@ 🇹🇻 🇹🇼 🇹🇿 +🇺 🇺🇦 🇺🇬 🇺🇲 @@ -486,6 +506,7 @@ 🇺🇸 🇺🇾 🇺🇿 +🇻 🇻🇦 🇻🇨 🇻🇪 @@ -493,11 +514,15 @@ 🇻🇮 🇻🇳 🇻🇺 +🇼 🇼🇫 🇼🇸 +🇽 🇽🇰 +🇾 🇾🇪 🇾🇹 +🇿 🇿🇦 🇿🇲 🇿🇼 From 65acc640340bc35bd2fd4239c5d3ad60cb92e5b0 Mon Sep 17 00:00:00 2001 From: "stoat-tofu[bot]" <242700035+stoat-tofu[bot]@users.noreply.github.com> Date: Mon, 1 Jun 2026 13:28:27 +0000 Subject: [PATCH 191/211] chore: modify .github/workflows/renovate.yml --- .github/workflows/renovate.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/renovate.yml diff --git a/.github/workflows/renovate.yml b/.github/workflows/renovate.yml new file mode 100644 index 000000000..7ce0d5ba0 --- /dev/null +++ b/.github/workflows/renovate.yml @@ -0,0 +1,30 @@ +# DO NOT EDIT DIRECTLY IN REPOSITORY +# Managed in Terraform templates + +name: Renovate +on: + workflow_dispatch: + schedule: + - cron: '0/15 * * * *' +jobs: + renovate: + runs-on: ubuntu-latest + steps: + - id: app-token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.GH_STOAT_RELEASE_APP_ID }} + private-key: ${{ secrets.GH_STOAT_RELEASE_APP_PRIVATE_KEY }} + + - name: Setup Mise + uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2 + with: + github_token: ${{ steps.app-token.outputs.token }} + + - name: Self-hosted Renovate + uses: renovatebot/github-action@v46.1.14 + with: + token: '${{ steps.app-token.outputs.token }}' + env: + RENOVATE_PLATFORM_COMMIT: 'enabled' + RENOVATE_REPOSITORIES: '${{ github.repository }}' \ No newline at end of file From 0896e6888274451b7bfb8abb012ae1bf32ad224a Mon Sep 17 00:00:00 2001 From: "stoat-tofu[bot]" <242700035+stoat-tofu[bot]@users.noreply.github.com> Date: Mon, 1 Jun 2026 13:28:29 +0000 Subject: [PATCH 192/211] chore: modify renovate.json --- renovate.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 renovate.json diff --git a/renovate.json b/renovate.json new file mode 100644 index 000000000..9ccd60d51 --- /dev/null +++ b/renovate.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended" + ], + "cloneSubmodules": true, + "cloneSubmodulesFilter": [ + "*", + "!packages/client/assets" + ] +} \ No newline at end of file From 5b769b60de5f14ed5612cd337f19c6fb9afdb99d Mon Sep 17 00:00:00 2001 From: Tom Date: Tue, 2 Jun 2026 17:42:04 -0700 Subject: [PATCH 193/211] chore(docs): update header logo (#796) * chore(docs): update header logo Signed-off-by: IAmTomahawkx * fix: don't step on toes Signed-off-by: IAmTomahawkx --------- Signed-off-by: IAmTomahawkx --- docs/docusaurus.config.ts | 6 +++--- docs/static/img/navbar.dark.svg | 9 +++++++++ docs/static/img/navbar.light.svg | 22 ++++++++++++++++++++++ 3 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 docs/static/img/navbar.dark.svg create mode 100644 docs/static/img/navbar.light.svg diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts index 9edf29e9b..f2b6857bc 100644 --- a/docs/docusaurus.config.ts +++ b/docs/docusaurus.config.ts @@ -80,10 +80,10 @@ const config: Config = { respectPrefersColorScheme: true, }, navbar: { - title: 'Stoat Developers', logo: { - alt: 'Stoat', - src: 'https://stoat.chat/favicon.svg', + alt: 'Stoat for Developers', + src: '/img/navbar.light.svg', + srcDark: '/img/navbar.dark.svg' }, items: [ { diff --git a/docs/static/img/navbar.dark.svg b/docs/static/img/navbar.dark.svg new file mode 100644 index 000000000..6a5d88c0f --- /dev/null +++ b/docs/static/img/navbar.dark.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/docs/static/img/navbar.light.svg b/docs/static/img/navbar.light.svg new file mode 100644 index 000000000..83bc88b07 --- /dev/null +++ b/docs/static/img/navbar.light.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + From bebfe349227d8cc555e1b488eb343f2c28b28b88 Mon Sep 17 00:00:00 2001 From: Asraye Date: Thu, 4 Jun 2026 04:06:38 +1000 Subject: [PATCH 194/211] fix: point docs favicon to correct location (#789) chore(docs): update favicon Signed-off-by: Asraye --- docs/docusaurus.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts index f2b6857bc..928a02d1d 100644 --- a/docs/docusaurus.config.ts +++ b/docs/docusaurus.config.ts @@ -6,7 +6,7 @@ import type { ScalarOptions } from '@scalar/docusaurus'; const config: Config = { title: 'Stoat Developers', tagline: 'Developer documentation for Stoat', - favicon: 'https://stoat.chat/favicon.svg', + favicon: 'https://stoat.chat/favicon-stoat.svg', future: { v4: true, From c70459b10ce107611b9d478add26db372361baf2 Mon Sep 17 00:00:00 2001 From: Tom Date: Sun, 7 Jun 2026 16:56:00 -0700 Subject: [PATCH 195/211] fix: openapi using old naming (#777) * fix: openapi using old naming Signed-off-by: IAmTomahawkx * fix: remove january openapi security header Signed-off-by: IAmTomahawkx * fix(docs): more Revolt usage Signed-off-by: IAmTomahawkx --------- Signed-off-by: IAmTomahawkx --- crates/delta/src/routes/mod.rs | 98 ++++++++--------------------- crates/services/january/src/main.rs | 40 +++++------- 2 files changed, 42 insertions(+), 96 deletions(-) diff --git a/crates/delta/src/routes/mod.rs b/crates/delta/src/routes/mod.rs index cf1c4ace6..768531fcd 100644 --- a/crates/delta/src/routes/mod.rs +++ b/crates/delta/src/routes/mod.rs @@ -64,47 +64,6 @@ pub fn mount(config: Settings, mut rocket: Rocket) -> Rocket { }; } - if config.features.webhooks_enabled { - mount_endpoints_and_merged_docs! { - rocket, "/0.8".to_owned(), settings, - "/" => (vec![], custom_openapi_spec()), - "" => openapi_get_routes_spec![root::root], - "/users" => users::routes(), - "/bots" => bots::routes(), - "/channels" => channels::routes(), - "/servers" => servers::routes(), - "/invites" => invites::routes(), - "/custom" => customisation::routes(), - "/safety" => safety::routes(), - "/auth/account" => rocket_authifier::routes::account::routes(), - "/auth/session" => rocket_authifier::routes::session::routes(), - "/auth/mfa" => rocket_authifier::routes::mfa::routes(), - "/onboard" => onboard::routes(), - "/push" => push::routes(), - "/sync" => sync::routes(), - "/webhooks" => webhooks::routes() - }; - } else { - mount_endpoints_and_merged_docs! { - rocket, "/0.8".to_owned(), settings, - "/" => (vec![], custom_openapi_spec()), - "" => openapi_get_routes_spec![root::root], - "/users" => users::routes(), - "/bots" => bots::routes(), - "/channels" => channels::routes(), - "/servers" => servers::routes(), - "/invites" => invites::routes(), - "/custom" => customisation::routes(), - "/safety" => safety::routes(), - "/auth/account" => rocket_authifier::routes::account::routes(), - "/auth/session" => rocket_authifier::routes::session::routes(), - "/auth/mfa" => rocket_authifier::routes::mfa::routes(), - "/onboard" => onboard::routes(), - "/push" => push::routes(), - "/sync" => sync::routes() - }; - } - rocket } @@ -115,8 +74,8 @@ fn custom_openapi_spec() -> OpenApi { extensions.insert( "x-logo".to_owned(), json!({ - "url": "https://revolt.chat/header.png", - "altText": "Revolt Header" + "url": "https://stoat.chat/header.png", + "altText": "Stoat Header" }), ); @@ -124,7 +83,7 @@ fn custom_openapi_spec() -> OpenApi { "x-tagGroups".to_owned(), json!([ { - "name": "Revolt", + "name": "Stoat", "tags": [ "Core" ] @@ -205,18 +164,21 @@ fn custom_openapi_spec() -> OpenApi { OpenApi { openapi: OpenApi::default_version(), info: Info { - title: "Revolt API".to_owned(), + title: "Stoat API".to_owned(), description: Some("Open source user-first chat platform.".to_owned()), - terms_of_service: Some("https://revolt.chat/terms".to_owned()), + terms_of_service: Some("https://stoat.chat/terms".to_owned()), contact: Some(Contact { - name: Some("Revolt Support".to_owned()), - url: Some("https://revolt.chat".to_owned()), - email: Some("contact@revolt.chat".to_owned()), + name: Some("Stoat".to_owned()), + url: Some("https://stoat.chat".to_owned()), + email: Some("contact@stoat.chat".to_owned()), ..Default::default() }), license: Some(License { name: "AGPLv3".to_owned(), - url: Some("https://github.com/stoatchat/stoatchat/blob/main/crates/delta/LICENSE".to_owned()), + url: Some( + "https://github.com/stoatchat/stoatchat/blob/main/crates/delta/LICENSE" + .to_owned(), + ), ..Default::default() }), version: env!("CARGO_PKG_VERSION").to_string(), @@ -224,29 +186,19 @@ fn custom_openapi_spec() -> OpenApi { }, servers: vec![ Server { - url: "https://api.revolt.chat".to_owned(), - description: Some("Revolt Production".to_owned()), - ..Default::default() - }, - Server { - url: "https://revolt.chat/api".to_owned(), - description: Some("Revolt Staging".to_owned()), - ..Default::default() - }, - Server { - url: "http://local.revolt.chat:14702".to_owned(), - description: Some("Local Revolt Environment".to_owned()), + url: "https://api.stoat.chat".to_owned(), + description: Some("Stoat Production".to_owned()), ..Default::default() }, Server { - url: "http://local.revolt.chat:14702/0.8".to_owned(), - description: Some("Local Revolt Environment (v0.8)".to_owned()), + url: "https://beta.stoat.chat/api".to_owned(), + description: Some("Stoat Beta".to_owned()), ..Default::default() }, ], external_docs: Some(ExternalDocs { - url: "https://developers.revolt.chat".to_owned(), - description: Some("Revolt Developer Documentation".to_owned()), + url: "https://developers.stoat.chat".to_owned(), + description: Some("Stoat Developer Documentation".to_owned()), ..Default::default() }), extensions, @@ -254,19 +206,19 @@ fn custom_openapi_spec() -> OpenApi { Tag { name: "Core".to_owned(), description: Some( - "Use in your applications to determine information about the Revolt node" + "Use in your applications to determine information about the Stoat node" .to_owned(), ), ..Default::default() }, Tag { name: "User Information".to_owned(), - description: Some("Query and fetch users on Revolt".to_owned()), + description: Some("Query and fetch users on Stoat".to_owned()), ..Default::default() }, Tag { name: "Direct Messaging".to_owned(), - description: Some("Direct message other users on Revolt".to_owned()), + description: Some("Direct message other users on Stoat".to_owned()), ..Default::default() }, Tag { @@ -283,7 +235,7 @@ fn custom_openapi_spec() -> OpenApi { }, Tag { name: "Channel Information".to_owned(), - description: Some("Query and fetch channels on Revolt".to_owned()), + description: Some("Query and fetch channels on Stoat".to_owned()), ..Default::default() }, Tag { @@ -313,7 +265,7 @@ fn custom_openapi_spec() -> OpenApi { }, Tag { name: "Server Information".to_owned(), - description: Some("Query and fetch servers on Revolt".to_owned()), + description: Some("Query and fetch servers on Stoat".to_owned()), ..Default::default() }, Tag { @@ -349,7 +301,7 @@ fn custom_openapi_spec() -> OpenApi { Tag { name: "Onboarding".to_owned(), description: Some( - "After signing up to Revolt, users must pick a unique username".to_owned(), + "After signing up to Stoat, users must pick a unique username".to_owned(), ), ..Default::default() }, @@ -361,7 +313,7 @@ fn custom_openapi_spec() -> OpenApi { Tag { name: "Web Push".to_owned(), description: Some( - "Subscribe to and receive Revolt push notifications while offline".to_owned(), + "Subscribe to and receive Stoat push notifications while offline".to_owned(), ), ..Default::default() }, diff --git a/crates/services/january/src/main.rs b/crates/services/january/src/main.rs index b905b87d8..e203ce286 100644 --- a/crates/services/january/src/main.rs +++ b/crates/services/january/src/main.rs @@ -21,32 +21,26 @@ async fn main() -> Result<(), std::io::Error> { // Configure API schema #[derive(OpenApi)] #[openapi( - modifiers(&SecurityAddon), - paths( - api::root, - api::proxy, - api::embed - ), - components( - schemas( - api::RootResponse, - revolt_result::Error, - revolt_result::ErrorType, - revolt_models::v0::ImageSize, - revolt_models::v0::Image, - revolt_models::v0::Video, - revolt_models::v0::TwitchType, - revolt_models::v0::LightspeedType, - revolt_models::v0::BandcampType, - revolt_models::v0::Special, - revolt_models::v0::WebsiteMetadata, - revolt_models::v0::Text, - revolt_models::v0::Embed - ) - ) + paths(api::root, api::proxy, api::embed), + components(schemas( + api::RootResponse, + revolt_result::Error, + revolt_result::ErrorType, + revolt_models::v0::ImageSize, + revolt_models::v0::Image, + revolt_models::v0::Video, + revolt_models::v0::TwitchType, + revolt_models::v0::LightspeedType, + revolt_models::v0::BandcampType, + revolt_models::v0::Special, + revolt_models::v0::WebsiteMetadata, + revolt_models::v0::Text, + revolt_models::v0::Embed + )) )] struct ApiDoc; + #[allow(dead_code)] struct SecurityAddon; impl Modify for SecurityAddon { From aa907e28c3f7048e6879d8ef43ed9ebde43f529c Mon Sep 17 00:00:00 2001 From: Asraye Date: Sun, 21 Jun 2026 04:30:27 +1000 Subject: [PATCH 196/211] chore: update email favicons (#800) Signed-off-by: AsrayeDev --- crates/core/database/templates/deletion.html | 2 +- crates/core/database/templates/deletion.original.html | 2 +- crates/core/database/templates/reset-existing.html | 2 +- crates/core/database/templates/reset-existing.original.html | 2 +- crates/core/database/templates/reset.html | 2 +- crates/core/database/templates/reset.original.html | 2 +- crates/core/database/templates/suspension.html | 2 +- crates/core/database/templates/suspension.original.html | 2 +- crates/core/database/templates/verify.html | 2 +- crates/core/database/templates/verify.original.html | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/crates/core/database/templates/deletion.html b/crates/core/database/templates/deletion.html index e6cb83eae..c733a2861 100644 --- a/crates/core/database/templates/deletion.html +++ b/crates/core/database/templates/deletion.html @@ -42,7 +42,7 @@ diff --git a/crates/core/database/templates/deletion.original.html b/crates/core/database/templates/deletion.original.html index e3ad4e508..53d89d3ee 100644 --- a/crates/core/database/templates/deletion.original.html +++ b/crates/core/database/templates/deletion.original.html @@ -9,7 +9,7 @@
- Stoat Logo + Stoat Logo

Account Deletion

diff --git a/crates/core/database/templates/reset-existing.html b/crates/core/database/templates/reset-existing.html index 1ed6424d3..51052966c 100644 --- a/crates/core/database/templates/reset-existing.html +++ b/crates/core/database/templates/reset-existing.html @@ -42,7 +42,7 @@

diff --git a/crates/core/database/templates/reset-existing.original.html b/crates/core/database/templates/reset-existing.original.html index a68c3d35d..a76f1099c 100644 --- a/crates/core/database/templates/reset-existing.original.html +++ b/crates/core/database/templates/reset-existing.original.html @@ -9,7 +9,7 @@
Stoat Logo
diff --git a/crates/core/database/templates/reset.html b/crates/core/database/templates/reset.html index b2f05cf2e..647d2d1f2 100644 --- a/crates/core/database/templates/reset.html +++ b/crates/core/database/templates/reset.html @@ -42,7 +42,7 @@
diff --git a/crates/core/database/templates/reset.original.html b/crates/core/database/templates/reset.original.html index 76b7b5c6e..e93286e67 100644 --- a/crates/core/database/templates/reset.original.html +++ b/crates/core/database/templates/reset.original.html @@ -9,7 +9,7 @@
- Stoat Logo + Stoat Logo

Password Reset

You requested a password reset, click below to continue.

diff --git a/crates/core/database/templates/suspension.html b/crates/core/database/templates/suspension.html index 27b7331e7..b9995a6ef 100644 --- a/crates/core/database/templates/suspension.html +++ b/crates/core/database/templates/suspension.html @@ -42,7 +42,7 @@
diff --git a/crates/core/database/templates/suspension.original.html b/crates/core/database/templates/suspension.original.html index de49512d2..e5980613e 100644 --- a/crates/core/database/templates/suspension.original.html +++ b/crates/core/database/templates/suspension.original.html @@ -9,7 +9,7 @@
- Stoat Logo + Stoat Logo

Account Suspended

Your account has been suspended, for one or more reasons:

diff --git a/crates/core/database/templates/verify.html b/crates/core/database/templates/verify.html index 10a4ab6ae..363e38de2 100644 --- a/crates/core/database/templates/verify.html +++ b/crates/core/database/templates/verify.html @@ -42,7 +42,7 @@
diff --git a/crates/core/database/templates/verify.original.html b/crates/core/database/templates/verify.original.html index 107d73077..21da66a7c 100644 --- a/crates/core/database/templates/verify.original.html +++ b/crates/core/database/templates/verify.original.html @@ -9,7 +9,7 @@
- Stoat Logo + Stoat Logo

Almost there!

To complete your sign up, we just need to verify your email.

From 0af376c26b149a5a0286608ebe3869587780a949 Mon Sep 17 00:00:00 2001 From: Kenyon Hopkins <133072610+bluecords@users.noreply.github.com> Date: Sat, 20 Jun 2026 14:33:28 -0400 Subject: [PATCH 197/211] fix: server owner should bypass rank check on channel role-permission overrides (#805) fix: allow true server owner to bypass rank check on channel role-permission overrides The set_role_permissions route blocks editing a role's channel permission overrides whenever role.rank <= the acting member's rank (NotElevated), to prevent privilege-escalation loops. However this check has no exemption for the server's true owner (server.owner == user.id). If an owner has assigned themselves their own top-level role (e.g. "Admin"/"Server Admin" - extremely common since most server setups have the owner hold their highest role for visible status/cosmetics), that role's rank is necessarily equal to their own computed member rank, so the check incorrectly throws NotElevated for the owner too - even though server owners by definition outrank every role and every member, owner-held roles included. This produces a confusing experience: the owner cannot edit channel-level overrides for their own top role via the UI, with no clear explanation, and may reasonably believe something is broken or their permissions are miscconfigured (they aren't). This adds a short-circuit: if the acting user is the server's owner, skip the rank comparison entirely, matching how Stoat already treats true ownership as an absolute bypass elsewhere in the permission system (e.g. channel-visibility lockout cascades). Signed-off-by: bluecords <133072610+bluecords@users.noreply.github.com> --- crates/delta/src/routes/channels/permissions_set.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/delta/src/routes/channels/permissions_set.rs b/crates/delta/src/routes/channels/permissions_set.rs index 545f6bb8d..7ab648d1c 100644 --- a/crates/delta/src/routes/channels/permissions_set.rs +++ b/crates/delta/src/routes/channels/permissions_set.rs @@ -29,7 +29,9 @@ pub async fn set_role_permissions( if let Some(server) = query.server_ref() { if let Some(role) = server.roles.get(&role_id) { - if role.rank <= query.get_member_rank().unwrap_or(i64::MIN) { + if server.owner != user.id + && role.rank <= query.get_member_rank().unwrap_or(i64::MIN) + { return Err(create_error!(NotElevated)); } From a7af24b38d0a38d6f04187464a89e67d459d1708 Mon Sep 17 00:00:00 2001 From: Kenyon Hopkins <133072610+bluecords@users.noreply.github.com> Date: Sat, 20 Jun 2026 14:34:54 -0400 Subject: [PATCH 198/211] fix: channel role permissions fail with 400 InvalidOperation for server owners/admins (#802) fix: channel role permissions fail with InvalidOperation for owners/admins Fix: explicitly populate the server reference via set_server_from_channel() before relying on server_ref(). Signed-off-by: bluecords <133072610+bluecords@users.noreply.github.com> --- crates/delta/src/routes/channels/permissions_set.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/delta/src/routes/channels/permissions_set.rs b/crates/delta/src/routes/channels/permissions_set.rs index 7ab648d1c..c0d89f11c 100644 --- a/crates/delta/src/routes/channels/permissions_set.rs +++ b/crates/delta/src/routes/channels/permissions_set.rs @@ -2,7 +2,7 @@ use revolt_database::{ util::{permissions::DatabasePermissionQuery, reference::Reference}, voice::{sync_voice_permissions, VoiceClient}, Database, User }; use revolt_models::v0; -use revolt_permissions::{calculate_channel_permissions, ChannelPermission, Override}; +use revolt_permissions::{calculate_channel_permissions, ChannelPermission, Override, PermissionQuery}; use revolt_result::{create_error, Result}; use rocket::{serde::json::Json, State}; @@ -25,6 +25,8 @@ pub async fn set_role_permissions( let mut query = DatabasePermissionQuery::new(db, &user).channel(&channel); let permissions: revolt_permissions::PermissionValue = calculate_channel_permissions(&mut query).await; + query.set_server_from_channel().await; + permissions.throw_if_lacking_channel_permission(ChannelPermission::ManagePermissions)?; if let Some(server) = query.server_ref() { From d27917b824684c62410f1cfc3b5a11f00c115776 Mon Sep 17 00:00:00 2001 From: Zomatree Date: Sun, 21 Jun 2026 00:50:06 +0100 Subject: [PATCH 199/211] chore: migrate authifier into codebase (#658) Co-authored-by: izzy Signed-off-by: Zomatree Signed-off-by: izzy --- Cargo.lock | 1209 +- Cargo.toml | 8 +- crates/bonfire/Cargo.toml | 1 - crates/bonfire/src/websocket.rs | 27 +- crates/core/config/Cargo.toml | 3 +- crates/core/config/Revolt.test.toml | 11 + crates/core/config/Revolt.toml | 9 + crates/core/config/src/lib.rs | 89 +- crates/core/database/Cargo.toml | 24 +- crates/core/database/assets/pwned100k.txt | 100005 +++++++++++++++ .../database/assets/revolt_source_list.txt | 555 + crates/core/database/src/drivers/mod.rs | 151 +- crates/core/database/src/drivers/reference.rs | 6 +- crates/core/database/src/events/client.rs | 18 +- .../src/models/account_invites/mod.rs | 5 + .../src/models/account_invites/model.rs | 25 + .../src/models/account_invites/ops.rs | 16 + .../src/models/account_invites/ops/mongodb.rs | 31 + .../models/account_invites/ops/reference.rs | 21 + .../core/database/src/models/accounts/axum.rs | 22 + .../core/database/src/models/accounts/mod.rs | 11 + .../database/src/models/accounts/model.rs | 656 + .../core/database/src/models/accounts/ops.rs | 34 + .../src/models/accounts/ops/mongodb.rs | 118 + .../src/models/accounts/ops/reference.rs | 99 + .../database/src/models/accounts/rocket.rs | 32 + .../database/src/models/accounts/schema.rs | 32 + .../admin_migrations/ops/mongodb/init.rs | 96 + .../admin_migrations/ops/mongodb/scripts.rs | 222 +- .../database/src/models/channels/model.rs | 9 +- .../core/database/src/models/channels/ops.rs | 8 +- .../src/models/channels/ops/mongodb.rs | 51 +- .../src/models/channels/ops/reference.rs | 37 +- .../core/database/src/models/messages/ops.rs | 2 + .../src/models/messages/ops/mongodb.rs | 6 + .../src/models/messages/ops/reference.rs | 43 +- .../database/src/models/mfa_tickets/axum.rs | 67 + .../database/src/models/mfa_tickets/mod.rs | 11 + .../database/src/models/mfa_tickets/model.rs | 105 + .../database/src/models/mfa_tickets/ops.rs | 22 + .../src/models/mfa_tickets/ops/mongodb.rs | 67 + .../src/models/mfa_tickets/ops/reference.rs | 57 + .../database/src/models/mfa_tickets/rocket.rs | 81 + .../database/src/models/mfa_tickets/schema.rs | 80 + crates/core/database/src/models/mod.rs | 12 + .../database/src/models/server_members/ops.rs | 3 + .../src/models/server_members/ops/mongodb.rs | 11 + .../models/server_members/ops/reference.rs | 9 + .../core/database/src/models/servers/ops.rs | 2 + .../src/models/servers/ops/mongodb.rs | 11 + .../src/models/servers/ops/reference.rs | 10 + .../core/database/src/models/sessions/axum.rs | 24 + .../core/database/src/models/sessions/mod.rs | 11 + .../database/src/models/sessions/model.rs | 68 + .../core/database/src/models/sessions/ops.rs | 37 + .../src/models/sessions/ops/mongodb.rs | 142 + .../src/models/sessions/ops/reference.rs | 101 + .../database/src/models/sessions/rocket.rs | 30 + .../database/src/models/sessions/schema.rs | 32 + .../core/database/src/models/users/model.rs | 95 +- crates/core/database/src/models/users/ops.rs | 11 +- .../database/src/models/users/ops/mongodb.rs | 52 +- .../src/models/users/ops/reference.rs | 29 +- .../core/database/src/models/users/rocket.rs | 8 +- .../database/src/tasks/authifier_relay.rs | 29 - crates/core/database/src/tasks/mod.rs | 3 - crates/core/database/src/util/bridge/v0.rs | 89 + crates/core/database/src/util/captcha.rs | 42 + crates/core/database/src/util/chunked.rs | 63 + crates/core/database/src/util/email.rs | 271 + crates/core/database/src/util/ip.rs | 56 + crates/core/database/src/util/mod.rs | 7 + crates/core/database/src/util/password.rs | 72 + crates/core/database/src/util/shield.rs | 118 + crates/core/models/Cargo.toml | 1 + crates/core/models/src/v0/accounts.rs | 70 + crates/core/models/src/v0/mfa_tickets.rs | 68 + crates/core/models/src/v0/mod.rs | 6 + crates/core/models/src/v0/sessions.rs | 88 + crates/core/ratelimits/Cargo.toml | 1 - crates/core/ratelimits/src/axum.rs | 27 +- crates/core/ratelimits/src/rocket.rs | 25 +- crates/core/result/src/axum.rs | 29 +- crates/core/result/src/lib.rs | 23 + crates/core/result/src/rocket.rs | 26 + crates/daemons/crond/Cargo.toml | 1 + crates/daemons/crond/src/main.rs | 52 +- .../crond/src/tasks/delete_accounts.rs | 23 + .../daemons/crond/src/tasks/file_deletion.rs | 10 +- crates/daemons/crond/src/tasks/mod.rs | 2 + .../crond/src/tasks/prune_dangling_files.rs | 2 +- .../daemons/crond/src/tasks/prune_members.rs | 2 +- .../crond/src/tasks/prune_mfa_tickets.rs | 14 + crates/daemons/pushd/Cargo.toml | 2 - .../pushd/src/consumers/inbound/ack.rs | 5 +- .../pushd/src/consumers/inbound/dm_call.rs | 5 +- .../src/consumers/inbound/fr_accepted.rs | 5 +- .../src/consumers/inbound/fr_received.rs | 5 +- .../pushd/src/consumers/inbound/generic.rs | 7 +- .../src/consumers/inbound/mass_mention.rs | 7 +- .../pushd/src/consumers/inbound/message.rs | 7 +- .../pushd/src/consumers/outbound/apn.rs | 3 - .../pushd/src/consumers/outbound/fcm.rs | 3 - .../pushd/src/consumers/outbound/vapid.rs | 3 - crates/daemons/pushd/src/main.rs | 23 - crates/daemons/pushd/src/utils/consumer.rs | 1 - crates/delta/Cargo.toml | 5 +- crates/delta/src/main.rs | 27 +- .../delta/src/routes/account/change_email.rs | 187 + .../src/routes/account/change_password.rs | 187 + .../src/routes/account/confirm_deletion.rs | 59 + .../src/routes/account/create_account.rs | 347 + .../src/routes/account/delete_account.rs | 64 + .../src/routes/account/disable_account.rs | 67 + .../delta/src/routes/account/fetch_account.rs | 40 + crates/delta/src/routes/account/mod.rs | 30 + .../src/routes/account/password_reset.rs | 140 + .../src/routes/account/resend_verification.rs | 155 + .../src/routes/account/send_password_reset.rs | 122 + .../delta/src/routes/account/verify_email.rs | 104 + crates/delta/src/routes/mfa/create_ticket.rs | 157 + crates/delta/src/routes/mfa/fetch_recovery.rs | 45 + crates/delta/src/routes/mfa/fetch_status.rs | 37 + .../delta/src/routes/mfa/generate_recovery.rs | 66 + .../delta/src/routes/mfa/get_mfa_methods.rs | 71 + crates/delta/src/routes/mfa/mod.rs | 24 + crates/delta/src/routes/mfa/totp_disable.rs | 49 + crates/delta/src/routes/mfa/totp_enable.rs | 102 + .../src/routes/mfa/totp_generate_secret.rs | 59 + crates/delta/src/routes/mod.rs | 15 +- crates/delta/src/routes/onboard/complete.rs | 3 +- crates/delta/src/routes/onboard/hello.rs | 3 +- crates/delta/src/routes/push/subscribe.rs | 14 +- crates/delta/src/routes/push/unsubscribe.rs | 10 +- .../delta/src/routes/servers/server_edit.rs | 6 +- crates/delta/src/routes/session/edit.rs | 67 + crates/delta/src/routes/session/fetch_all.rs | 52 + crates/delta/src/routes/session/login.rs | 588 + crates/delta/src/routes/session/logout.rs | 79 + crates/delta/src/routes/session/mod.rs | 20 + crates/delta/src/routes/session/revoke.rs | 114 + crates/delta/src/routes/session/revoke_all.rs | 196 + .../delta/src/routes/users/change_username.rs | 3 +- crates/delta/src/util/mod.rs | 2 + crates/delta/src/util/test.rs | 89 +- 145 files changed, 108392 insertions(+), 1189 deletions(-) create mode 100644 crates/core/database/assets/pwned100k.txt create mode 100644 crates/core/database/assets/revolt_source_list.txt create mode 100644 crates/core/database/src/models/account_invites/mod.rs create mode 100644 crates/core/database/src/models/account_invites/model.rs create mode 100644 crates/core/database/src/models/account_invites/ops.rs create mode 100644 crates/core/database/src/models/account_invites/ops/mongodb.rs create mode 100644 crates/core/database/src/models/account_invites/ops/reference.rs create mode 100644 crates/core/database/src/models/accounts/axum.rs create mode 100644 crates/core/database/src/models/accounts/mod.rs create mode 100644 crates/core/database/src/models/accounts/model.rs create mode 100644 crates/core/database/src/models/accounts/ops.rs create mode 100644 crates/core/database/src/models/accounts/ops/mongodb.rs create mode 100644 crates/core/database/src/models/accounts/ops/reference.rs create mode 100644 crates/core/database/src/models/accounts/rocket.rs create mode 100644 crates/core/database/src/models/accounts/schema.rs create mode 100644 crates/core/database/src/models/mfa_tickets/axum.rs create mode 100644 crates/core/database/src/models/mfa_tickets/mod.rs create mode 100644 crates/core/database/src/models/mfa_tickets/model.rs create mode 100644 crates/core/database/src/models/mfa_tickets/ops.rs create mode 100644 crates/core/database/src/models/mfa_tickets/ops/mongodb.rs create mode 100644 crates/core/database/src/models/mfa_tickets/ops/reference.rs create mode 100644 crates/core/database/src/models/mfa_tickets/rocket.rs create mode 100644 crates/core/database/src/models/mfa_tickets/schema.rs create mode 100644 crates/core/database/src/models/sessions/axum.rs create mode 100644 crates/core/database/src/models/sessions/mod.rs create mode 100644 crates/core/database/src/models/sessions/model.rs create mode 100644 crates/core/database/src/models/sessions/ops.rs create mode 100644 crates/core/database/src/models/sessions/ops/mongodb.rs create mode 100644 crates/core/database/src/models/sessions/ops/reference.rs create mode 100644 crates/core/database/src/models/sessions/rocket.rs create mode 100644 crates/core/database/src/models/sessions/schema.rs delete mode 100644 crates/core/database/src/tasks/authifier_relay.rs create mode 100644 crates/core/database/src/util/captcha.rs create mode 100644 crates/core/database/src/util/chunked.rs create mode 100644 crates/core/database/src/util/email.rs create mode 100644 crates/core/database/src/util/ip.rs create mode 100644 crates/core/database/src/util/password.rs create mode 100644 crates/core/database/src/util/shield.rs create mode 100644 crates/core/models/src/v0/accounts.rs create mode 100644 crates/core/models/src/v0/mfa_tickets.rs create mode 100644 crates/core/models/src/v0/sessions.rs create mode 100644 crates/daemons/crond/src/tasks/delete_accounts.rs create mode 100644 crates/daemons/crond/src/tasks/prune_mfa_tickets.rs create mode 100644 crates/delta/src/routes/account/change_email.rs create mode 100644 crates/delta/src/routes/account/change_password.rs create mode 100644 crates/delta/src/routes/account/confirm_deletion.rs create mode 100644 crates/delta/src/routes/account/create_account.rs create mode 100644 crates/delta/src/routes/account/delete_account.rs create mode 100644 crates/delta/src/routes/account/disable_account.rs create mode 100644 crates/delta/src/routes/account/fetch_account.rs create mode 100644 crates/delta/src/routes/account/mod.rs create mode 100644 crates/delta/src/routes/account/password_reset.rs create mode 100644 crates/delta/src/routes/account/resend_verification.rs create mode 100644 crates/delta/src/routes/account/send_password_reset.rs create mode 100644 crates/delta/src/routes/account/verify_email.rs create mode 100644 crates/delta/src/routes/mfa/create_ticket.rs create mode 100644 crates/delta/src/routes/mfa/fetch_recovery.rs create mode 100644 crates/delta/src/routes/mfa/fetch_status.rs create mode 100644 crates/delta/src/routes/mfa/generate_recovery.rs create mode 100644 crates/delta/src/routes/mfa/get_mfa_methods.rs create mode 100644 crates/delta/src/routes/mfa/mod.rs create mode 100644 crates/delta/src/routes/mfa/totp_disable.rs create mode 100644 crates/delta/src/routes/mfa/totp_enable.rs create mode 100644 crates/delta/src/routes/mfa/totp_generate_secret.rs create mode 100644 crates/delta/src/routes/session/edit.rs create mode 100644 crates/delta/src/routes/session/fetch_all.rs create mode 100644 crates/delta/src/routes/session/login.rs create mode 100644 crates/delta/src/routes/session/logout.rs create mode 100644 crates/delta/src/routes/session/mod.rs create mode 100644 crates/delta/src/routes/session/revoke.rs create mode 100644 crates/delta/src/routes/session/revoke_all.rs diff --git a/Cargo.lock b/Cargo.lock index bcd1c5acb..b9c27cd5f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,7 +23,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" dependencies = [ - "crypto-common", + "crypto-common 0.1.7", "generic-array 0.14.7", ] @@ -126,9 +126,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "amq-protocol" -version = "10.3.0" +version = "10.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5b2e8843d88d935a75cbdb1c5b9ad80987da6e6472c2703914e41dc14560990" +checksum = "46b92ce9a8b7d332c4b54ef7ea1b00570692bd94fe225901eab63bd12930c63f" dependencies = [ "amq-protocol-tcp", "amq-protocol-types", @@ -140,9 +140,9 @@ dependencies = [ [[package]] name = "amq-protocol-tcp" -version = "10.3.0" +version = "10.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "998fb81655e11de5a336bb609042c11633678fc01f90b0772fb9a7886b6cc4c2" +checksum = "06f3177d5d2aff2ec51e1d77ac433fcd1b297ea2bb97c2089152a7d2a58a7e3f" dependencies = [ "amq-protocol-uri", "async-rs", @@ -153,9 +153,9 @@ dependencies = [ [[package]] name = "amq-protocol-types" -version = "10.3.0" +version = "10.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee5b3a9e458bd2e452536995c8cf861b01c17283f55c4bbe0a1b9626b8253add" +checksum = "7b9f2a0015cd0471a2b823060f3424760a7a84787ee89edd1039ca8d715f6de0" dependencies = [ "cookie-factory", "nom 8.0.0", @@ -165,9 +165,9 @@ dependencies = [ [[package]] name = "amq-protocol-uri" -version = "10.3.0" +version = "10.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dca3316970d20cdcca9123f4e8feb7a2c1c8fdca572a9692fc10002db35407aa" +checksum = "69f66f887c5445e087e811794d7e5d071145c81e83568f77529e2f1203b68202" dependencies = [ "amq-protocol-types", "percent-encoding", @@ -238,9 +238,9 @@ dependencies = [ [[package]] name = "asn1-rs" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56624a96882bb8c26d61312ae18cb45868e5a9992ea73c58e45c3101e56a1e60" +checksum = "b7f43a50ac4fdca5df8e885c21b835997f0a1cdee65494a6847694a98652d9d8" dependencies = [ "asn1-rs-derive", "asn1-rs-impl", @@ -318,7 +318,7 @@ dependencies = [ "futures-io", "once_cell", "pin-project-lite 0.2.17", - "tokio 1.51.0", + "tokio 1.52.3", ] [[package]] @@ -329,7 +329,7 @@ checksum = "c96bf972d85afc50bf5ab8fe2d54d1586b4e0b46c97c50a0c9e71e2f7bcd812a" dependencies = [ "async-task", "concurrent-queue", - "fastrand 2.4.0", + "fastrand 2.4.1", "futures-lite", "pin-project-lite 0.2.17", "slab", @@ -349,7 +349,7 @@ dependencies = [ "futures-lite", "once_cell", "tokio 0.2.25", - "tokio 1.51.0", + "tokio 1.52.3", ] [[package]] @@ -363,7 +363,7 @@ dependencies = [ "async-lock 3.4.2", "blocking", "futures-lite", - "tokio 1.51.0", + "tokio 1.52.3", ] [[package]] @@ -435,9 +435,9 @@ dependencies = [ [[package]] name = "async-rs" -version = "0.8.5" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e32bd31386d41d0c06bd79b0397ec96e544d69d9dbd6db0236c7ceefe1ad61b" +checksum = "53bf71bee8a75907b6e3c81c5476efa7fcbb34df6e12d30b706888abded72091" dependencies = [ "async-compat", "async-global-executor 3.1.0", @@ -445,15 +445,15 @@ dependencies = [ "futures-core", "futures-io", "hickory-resolver 0.26.1", - "tokio 1.51.0", + "tokio 1.52.3", "tokio-stream", ] [[package]] name = "async-signal" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43c070bbf59cd3570b6b2dd54cd772527c7c3620fce8be898406dd3ed6adc64c" +checksum = "52b5aaafa020cf5053a01f2a60e8ff5dccf550f0f77ec54a4e47285ac2bab485" dependencies = [ "async-io", "async-lock 3.4.2", @@ -580,41 +580,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "authifier" -version = "1.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d6163caecbb985d91406c2c6dc7710c46b38e6461d93d5e843b2f0eac43910c" -dependencies = [ - "async-std", - "async-trait", - "base32", - "bson", - "chrono", - "futures", - "handlebars", - "iso8601-timestamp", - "lazy_static", - "lettre", - "log", - "mongodb", - "nanoid", - "rand 0.8.5", - "regex", - "reqwest 0.11.27", - "revolt_okapi", - "revolt_rocket_okapi", - "rocket", - "rust-argon2", - "schemars", - "serde", - "serde_json", - "sha1", - "totp-lite", - "ulid 0.5.0", - "validator 0.15.0", -] - [[package]] name = "auto_ops" version = "0.3.0" @@ -663,18 +628,18 @@ dependencies = [ [[package]] name = "avif-serialize" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "375082f007bd67184fb9c0374614b29f9aaa604ec301635f72338bb65386a53d" +checksum = "e7178fe5f7d460b13895ebb9dcb28a3a6216d2df2574a0806cb51b555d297f38" dependencies = [ "arrayvec", ] [[package]] name = "aws-config" -version = "1.8.15" +version = "1.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11493b0bad143270fb8ad284a096dd529ba91924c5409adeac856cc1bf047dbc" +checksum = "50f156acdd2cf55f5aa53ee416c4ac851cf1222694506c0b1f78c85695e9ca9d" dependencies = [ "aws-credential-types", "aws-runtime", @@ -689,12 +654,12 @@ dependencies = [ "aws-smithy-types", "aws-types", "bytes 1.11.1", - "fastrand 2.4.0", + "fastrand 2.4.1", "hex", "http 1.4.0", - "sha1", + "sha1 0.10.6", "time", - "tokio 1.51.0", + "tokio 1.52.3", "tracing", "url", "zeroize", @@ -714,9 +679,9 @@ dependencies = [ [[package]] name = "aws-lc-rs" -version = "1.16.2" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a054912289d18629dc78375ba2c3726a3afe3ff71b4edba9dedfca0e3446d1fc" +checksum = "5ec2f1fc3ec205783a5da9a7e6c1509cc69dedf09a1949e412c1e18469326d00" dependencies = [ "aws-lc-sys", "zeroize", @@ -724,9 +689,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.39.1" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a25cf98105baa966497416dbd42565ce3a8cf8dbfd59803ec9ad46f3126399" +checksum = "1a2f9779ce85b93ab6170dd940ad0169b5766ff848247aff13bb788b832fe3f4" dependencies = [ "cc", "cmake", @@ -736,9 +701,9 @@ dependencies = [ [[package]] name = "aws-runtime" -version = "1.7.2" +version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc0651c57e384202e47153c1260b84a9936e19803d747615edf199dc3b98d17" +checksum = "5dcd93c82209ac7413532388067dce79be5a8780c1786e5fae3df22e4dee2864" dependencies = [ "aws-credential-types", "aws-sigv4", @@ -751,7 +716,7 @@ dependencies = [ "aws-types", "bytes 1.11.1", "bytes-utils", - "fastrand 2.4.0", + "fastrand 2.4.1", "http 0.2.12", "http 1.4.0", "http-body 0.4.6", @@ -764,9 +729,9 @@ dependencies = [ [[package]] name = "aws-sdk-s3" -version = "1.128.0" +version = "1.132.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99304b64672e0d81a3c100a589b93d9ef5e9c0ce12e21c848fd39e50f493c2a1" +checksum = "5575840a3a6b11f6011463ebe359320dfe5b67babb5e9b06fed6ddf809a9ab40" dependencies = [ "aws-credential-types", "aws-runtime", @@ -783,25 +748,25 @@ dependencies = [ "aws-smithy-xml", "aws-types", "bytes 1.11.1", - "fastrand 2.4.0", + "fastrand 2.4.1", "hex", - "hmac", + "hmac 0.13.0", "http 0.2.12", "http 1.4.0", "http-body 1.0.1", "lru", "percent-encoding", "regex-lite", - "sha2", + "sha2 0.11.0", "tracing", "url", ] [[package]] name = "aws-sdk-sso" -version = "1.97.0" +version = "1.98.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aadc669e184501caaa6beafb28c6267fc1baef0810fb58f9b205485ca3f2567" +checksum = "d69c77aafa20460c68b6b3213c84f6423b6e76dbf89accd3e1789a686ffd9489" dependencies = [ "aws-credential-types", "aws-runtime", @@ -814,7 +779,7 @@ dependencies = [ "aws-smithy-types", "aws-types", "bytes 1.11.1", - "fastrand 2.4.0", + "fastrand 2.4.1", "http 0.2.12", "http 1.4.0", "regex-lite", @@ -823,9 +788,9 @@ dependencies = [ [[package]] name = "aws-sdk-ssooidc" -version = "1.99.0" +version = "1.100.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1342a7db8f358d3de0aed2007a0b54e875458e39848d54cc1d46700b2bfcb0a8" +checksum = "1c7e7b09346d5ca22a2a08267555843a6a0127fb20d8964cb6ecfb8fdb190225" dependencies = [ "aws-credential-types", "aws-runtime", @@ -838,7 +803,7 @@ dependencies = [ "aws-smithy-types", "aws-types", "bytes 1.11.1", - "fastrand 2.4.0", + "fastrand 2.4.1", "http 0.2.12", "http 1.4.0", "regex-lite", @@ -847,9 +812,9 @@ dependencies = [ [[package]] name = "aws-sdk-sts" -version = "1.101.0" +version = "1.103.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab41ad64e4051ecabeea802d6a17845a91e83287e1dd249e6963ea1ba78c428a" +checksum = "c2249b81a2e73a8027c41c378463a81ec39b8510f184f2caab87de912af0f49b" dependencies = [ "aws-credential-types", "aws-runtime", @@ -863,7 +828,7 @@ dependencies = [ "aws-smithy-types", "aws-smithy-xml", "aws-types", - "fastrand 2.4.0", + "fastrand 2.4.1", "http 0.2.12", "http 1.4.0", "regex-lite", @@ -872,9 +837,9 @@ dependencies = [ [[package]] name = "aws-sigv4" -version = "1.4.2" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0b660013a6683ab23797778e21f1f854744fdf05f68204b4cca4c8c04b5d1f4" +checksum = "68dc0b907359b120170613b5c09ccc61304eac3998ff6274b97d93ee6490115a" dependencies = [ "aws-credential-types", "aws-smithy-eventstream", @@ -885,13 +850,13 @@ dependencies = [ "crypto-bigint 0.5.5", "form_urlencoded", "hex", - "hmac", + "hmac 0.13.0", "http 0.2.12", "http 1.4.0", "p256 0.11.1", "percent-encoding", "ring", - "sha2", + "sha2 0.11.0", "subtle", "time", "tracing", @@ -906,14 +871,14 @@ checksum = "2ffcaf626bdda484571968400c326a244598634dc75fd451325a54ad1a59acfc" dependencies = [ "futures-util", "pin-project-lite 0.2.17", - "tokio 1.51.0", + "tokio 1.52.3", ] [[package]] name = "aws-smithy-checksums" -version = "0.64.6" +version = "0.64.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6750f3dd509b0694a4377f0293ed2f9630d710b1cebe281fa8bac8f099f88bc6" +checksum = "10efbbcec1e044b81600e2fc562a391951d291152d95b482d5b7e7132299d762" dependencies = [ "aws-smithy-http", "aws-smithy-types", @@ -923,10 +888,10 @@ dependencies = [ "http 1.4.0", "http-body 1.0.1", "http-body-util", - "md-5", + "md-5 0.11.0", "pin-project-lite 0.2.17", - "sha1", - "sha2", + "sha1 0.11.0", + "sha2 0.11.0", "tracing", ] @@ -973,21 +938,21 @@ dependencies = [ "aws-smithy-runtime-api", "aws-smithy-types", "h2 0.3.27", - "h2 0.4.13", + "h2 0.4.14", "http 0.2.12", "http 1.4.0", "http-body 0.4.6", "hyper 0.14.32", "hyper 1.9.0", "hyper-rustls 0.24.2", - "hyper-rustls 0.27.7", + "hyper-rustls 0.27.9", "hyper-util", "pin-project-lite 0.2.17", "rustls 0.21.12", - "rustls 0.23.37", + "rustls 0.23.40", "rustls-native-certs 0.8.3", "rustls-pki-types", - "tokio 1.51.0", + "tokio 1.52.3", "tokio-rustls 0.26.4", "tower", "tracing", @@ -1023,9 +988,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime" -version = "1.10.3" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "028999056d2d2fd58a697232f9eec4a643cf73a71cf327690a7edad1d2af2110" +checksum = "0504b1ab12debb5959e5165ee5fe97dd387e7aa7ea6a477bfd7635dfe769a4f5" dependencies = [ "aws-smithy-async", "aws-smithy-http", @@ -1034,7 +999,7 @@ dependencies = [ "aws-smithy-runtime-api", "aws-smithy-types", "bytes 1.11.1", - "fastrand 2.4.0", + "fastrand 2.4.1", "http 0.2.12", "http 1.4.0", "http-body 0.4.6", @@ -1042,27 +1007,39 @@ dependencies = [ "http-body-util", "pin-project-lite 0.2.17", "pin-utils", - "tokio 1.51.0", + "tokio 1.52.3", "tracing", ] [[package]] name = "aws-smithy-runtime-api" -version = "1.11.6" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876ab3c9c29791ba4ba02b780a3049e21ec63dabda09268b175272c3733a79e6" +checksum = "b71a13df6ada0aafbf21a73bdfcdf9324cfa9df77d96b8446045be3cde61b42e" dependencies = [ "aws-smithy-async", + "aws-smithy-runtime-api-macros", "aws-smithy-types", "bytes 1.11.1", "http 0.2.12", "http 1.4.0", "pin-project-lite 0.2.17", - "tokio 1.51.0", + "tokio 1.52.3", "tracing", "zeroize", ] +[[package]] +name = "aws-smithy-runtime-api-macros" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d7396fd9500589e62e460e987ecb671bad374934e55ec3b5f498cc7a8a8a7b7" +dependencies = [ + "proc-macro2", + "quote 1.0.45", + "syn 2.0.117", +] + [[package]] name = "aws-smithy-types" version = "1.4.7" @@ -1085,7 +1062,7 @@ dependencies = [ "ryu", "serde", "time", - "tokio 1.51.0", + "tokio 1.52.3", "tokio-util", ] @@ -1100,9 +1077,9 @@ dependencies = [ [[package]] name = "aws-types" -version = "1.3.14" +version = "1.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47c8323699dd9b3c8d5b3c13051ae9cdef58fd179957c882f8374dd8725962d9" +checksum = "2f4bbcaa9304ea40902d3d5f42a0428d1bd895a2b0f6999436fb279ffddc58ac" dependencies = [ "aws-credential-types", "aws-smithy-async", @@ -1141,7 +1118,7 @@ dependencies = [ "serde_path_to_error", "serde_urlencoded", "sync_wrapper 1.0.2", - "tokio 1.51.0", + "tokio 1.52.3", "tower", "tower-layer", "tower-service", @@ -1178,7 +1155,7 @@ dependencies = [ "axum", "axum-core", "bytes 1.11.1", - "fastrand 2.4.0", + "fastrand 2.4.1", "futures-util", "headers", "http 1.4.0", @@ -1219,7 +1196,7 @@ dependencies = [ "futures-util", "tempfile", "thiserror 1.0.69", - "tokio 1.51.0", + "tokio 1.52.3", "uuid", ] @@ -1243,7 +1220,7 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cffb0e931875b666fc4fcb20fee52e9bbd1ef836fd9e9e04ec21555f9f85f7ef" dependencies = [ - "fastrand 2.4.0", + "fastrand 2.4.1", ] [[package]] @@ -1360,17 +1337,17 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" [[package]] name = "bitstream-io" -version = "4.9.0" +version = "4.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60d4bd9d1db2c6bdf285e223a7fa369d5ce98ec767dec949c6ca62863ce61757" +checksum = "7eff00be299a18769011411c9def0d827e8f2d7bf0c3dbf53633147a8867fd1f" dependencies = [ - "core2", + "no_std_io2", ] [[package]] @@ -1405,6 +1382,15 @@ dependencies = [ "generic-array 0.14.7", ] +[[package]] +name = "block-buffer" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" +dependencies = [ + "hybrid-array", +] + [[package]] name = "block-padding" version = "0.3.3" @@ -1458,10 +1444,10 @@ dependencies = [ "getrandom 0.2.17", "getrandom 0.3.4", "hex", - "indexmap 2.13.1", + "indexmap 2.14.0", "js-sys", "once_cell", - "rand 0.9.2", + "rand 0.9.4", "serde", "serde_bytes", "serde_json", @@ -1535,7 +1521,7 @@ dependencies = [ "instant", "once_cell", "thiserror 1.0.69", - "tokio 1.51.0", + "tokio 1.52.3", ] [[package]] @@ -1577,9 +1563,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.59" +version = "1.2.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7a4d3ec6524d28a329fc53654bbadc9bdd7b0431f5d65f1a56ffb28a1ee5283" +checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" dependencies = [ "find-msvc-tools", "jobserver", @@ -1646,7 +1632,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "crypto-common", + "crypto-common 0.1.7", "inout", ] @@ -1659,6 +1645,12 @@ dependencies = [ "cc", ] +[[package]] +name = "cmov" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f88a43d011fc4a6876cb7344703e297c71dda42494fee094d5f7c76bf13f746" + [[package]] name = "cms" version = "0.2.3" @@ -1698,7 +1690,7 @@ dependencies = [ "futures-core", "memchr", "pin-project-lite 0.2.17", - "tokio 1.51.0", + "tokio 1.52.3", "tokio-util", ] @@ -1742,6 +1734,12 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + [[package]] name = "const-random" version = "0.1.18" @@ -1829,15 +1827,6 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" -[[package]] -name = "core2" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" -dependencies = [ - "memchr", -] - [[package]] name = "core_maths" version = "0.1.1" @@ -1876,9 +1865,9 @@ dependencies = [ [[package]] name = "crc-catalog" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" +checksum = "217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853" [[package]] name = "crc-fast" @@ -1887,7 +1876,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fd92aca2c6001b1bf5ba0ff84ee74ec8501b52bbef0cac80bf25a6c1d87a83d" dependencies = [ "crc", - "digest", + "digest 0.10.7", "rustversion", "spin 0.10.0", ] @@ -1997,6 +1986,15 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-common" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" +dependencies = [ + "hybrid-array", +] + [[package]] name = "cssparser" version = "0.31.2" @@ -2035,6 +2033,15 @@ dependencies = [ "cipher", ] +[[package]] +name = "ctutils" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" +dependencies = [ + "cmov", +] + [[package]] name = "curl" version = "0.4.49" @@ -2075,7 +2082,7 @@ dependencies = [ "cfg-if", "cpufeatures 0.2.17", "curve25519-dalek-derive", - "digest", + "digest 0.10.7", "fiat-crypto", "rustc_version", "subtle", @@ -2247,9 +2254,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" +checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8" [[package]] name = "data-url" @@ -2264,7 +2271,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72ff1266be84e4e04a81e2d1cbb998cb271b374fb73ce780245ef96c037c50cd" dependencies = [ "crossbeam-queue", - "tokio 1.51.0", + "tokio 1.52.3", ] [[package]] @@ -2433,6 +2440,21 @@ dependencies = [ "cipher", ] +[[package]] +name = "device-info" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2ca8e71544c1b67dcdbc2699ab258828aff985e5bc8d5f6b486d90d7df2f848" +dependencies = [ + "core-foundation 0.10.1", + "jni 0.21.1", + "libc", + "thiserror 2.0.18", + "wasm-bindgen", + "web-sys", + "windows-sys 0.59.0", +] + [[package]] name = "devise" version = "0.4.2" @@ -2459,7 +2481,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b035a542cf7abf01f2e3c4d5a7acbaebfefe120ae4efc7bde3df98186e4b8af7" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "proc-macro2", "proc-macro2-diagnostics", "quote 1.0.45", @@ -2472,19 +2494,31 @@ version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", + "block-buffer 0.10.4", "const-oid 0.9.6", - "crypto-common", + "crypto-common 0.1.7", "subtle", ] +[[package]] +name = "digest" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +dependencies = [ + "block-buffer 0.12.0", + "const-oid 0.10.2", + "crypto-common 0.2.1", + "ctutils", +] + [[package]] name = "dispatch2" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "objc2", ] @@ -2551,7 +2585,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ "der 0.7.10", - "digest", + "digest 0.10.7", "elliptic-curve 0.13.8", "rfc6979 0.4.0", "signature 2.2.0", @@ -2572,7 +2606,7 @@ dependencies = [ "once_cell", "openssl", "serde", - "sha2", + "sha2 0.10.9", "thiserror 1.0.69", ] @@ -2588,12 +2622,12 @@ dependencies = [ [[package]] name = "ed25519-compact" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ce99a9e19c84beb4cc35ece85374335ccc398240712114c85038319ed709bd" +checksum = "f5c0284a5d4b1a2fae017a9fe55fd7d01699711f1b572493f16593e173ea2801" dependencies = [ "ct-codecs", - "getrandom 0.3.4", + "getrandom 0.4.2", ] [[package]] @@ -2605,7 +2639,7 @@ dependencies = [ "curve25519-dalek", "ed25519", "serde", - "sha2", + "sha2 0.10.9", "subtle", "zeroize", ] @@ -2631,7 +2665,7 @@ dependencies = [ "base16ct 0.1.1", "crypto-bigint 0.4.9", "der 0.6.1", - "digest", + "digest 0.10.7", "ff 0.12.1", "generic-array 0.14.7", "group 0.12.1", @@ -2650,7 +2684,7 @@ checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct 0.2.0", "crypto-bigint 0.5.5", - "digest", + "digest 0.10.7", "ff 0.13.1", "generic-array 0.14.7", "group 0.13.0", @@ -2840,29 +2874,15 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a043dc74da1e37d6afe657061213aa6f425f855399a11d3463c6ecccc4dfda1f" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" [[package]] name = "fax" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f05de7d48f37cd6730705cbca900770cab77a89f413d23e100ad7fad7795a0ab" -dependencies = [ - "fax_derive", -] - -[[package]] -name = "fax_derive" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0aca10fb742cb43f9e7bb8467c91aa9bcb8e3ffbc6a6f7389bb93ffc920577d" -dependencies = [ - "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", -] +checksum = "caf1079563223d5d59d83c85886a56e586cfd5c1a26292e971a0fa266531ac5a" [[package]] name = "fcm_v1" @@ -3103,11 +3123,11 @@ dependencies = [ "futures", "log", "parking_lot", - "rand 0.8.5", + "rand 0.8.6", "redis-protocol", "semver", "socket2 0.5.10", - "tokio 1.51.0", + "tokio 1.52.3", "tokio-stream", "tokio-util", "url", @@ -3190,7 +3210,7 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" dependencies = [ - "fastrand 2.4.0", + "fastrand 2.4.1", "futures-core", "futures-io", "parking", @@ -3205,7 +3225,7 @@ checksum = "45ec6fe3675af967e67c5536c0b9d44e34e6c52f86bedc4ea49c5317b8e94d06" dependencies = [ "futures-channel", "futures-task", - "tokio 1.51.0", + "tokio 1.52.3", ] [[package]] @@ -3226,7 +3246,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f2f12607f92c69b12ed746fabf9ca4f5c482cba46679c1a75b874ed7c26adb" dependencies = [ "futures-io", - "rustls 0.23.37", + "rustls 0.23.40", "rustls-pki-types", ] @@ -3300,9 +3320,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "1.3.5" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf57c49a95fd1fe24b90b3033bee6dc7e8f1288d51494cb44e627c295e38542" +checksum = "dab9e9188e97a93276e1fe7b56401b851e2b45a46d045ca658100c1303ada649" dependencies = [ "rustversion", "typenum", @@ -3351,11 +3371,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi 6.0.0", "rand_core 0.10.1", "wasip2", "wasip3", + "wasm-bindgen", ] [[package]] @@ -3392,9 +3414,9 @@ dependencies = [ [[package]] name = "gif" -version = "0.14.1" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5df2ba84018d80c213569363bdcd0c64e6933c67fe4c1d60ecf822971a3c35e" +checksum = "ee8cfcc411d9adbbaba82fb72661cc1bcca13e8bba98b364e62b2dba8f960159" dependencies = [ "color_quant", "weezl", @@ -3471,18 +3493,18 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.13.1", + "indexmap 2.14.0", "slab", - "tokio 1.51.0", + "tokio 1.52.3", "tokio-util", "tracing", ] [[package]] name = "h2" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733" dependencies = [ "atomic-waker", "bytes 1.11.1", @@ -3490,9 +3512,9 @@ dependencies = [ "futures-core", "futures-sink", "http 1.4.0", - "indexmap 2.13.1", + "indexmap 2.14.0", "slab", - "tokio 1.51.0", + "tokio 1.52.3", "tokio-util", "tracing", ] @@ -3563,6 +3585,12 @@ dependencies = [ "foldhash 0.2.0", ] +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + [[package]] name = "headers" version = "0.4.1" @@ -3575,7 +3603,7 @@ dependencies = [ "http 1.4.0", "httpdate", "mime", - "sha1", + "sha1 0.10.6", ] [[package]] @@ -3639,7 +3667,7 @@ dependencies = [ "rand 0.10.1", "thiserror 2.0.18", "tinyvec", - "tokio 1.51.0", + "tokio 1.52.3", "tracing", "url", ] @@ -3660,11 +3688,11 @@ dependencies = [ "idna 1.1.0", "ipnet", "once_cell", - "rand 0.9.2", + "rand 0.9.4", "ring", "thiserror 2.0.18", "tinyvec", - "tokio 1.51.0", + "tokio 1.52.3", "tracing", "url", ] @@ -3702,11 +3730,11 @@ dependencies = [ "moka", "once_cell", "parking_lot", - "rand 0.9.2", + "rand 0.9.4", "resolv-conf", "smallvec", "thiserror 2.0.18", - "tokio 1.51.0", + "tokio 1.52.3", "tracing", ] @@ -3732,7 +3760,7 @@ dependencies = [ "smallvec", "system-configuration 0.7.0", "thiserror 2.0.18", - "tokio 1.51.0", + "tokio 1.52.3", "tracing", ] @@ -3742,7 +3770,7 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ - "hmac", + "hmac 0.12.1", ] [[package]] @@ -3751,7 +3779,16 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest", + "digest 0.10.7", +] + +[[package]] +name = "hmac" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" +dependencies = [ + "digest 0.11.3", ] [[package]] @@ -3766,7 +3803,7 @@ version = "1.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec9d92d097f4749b64e8cc33d924d9f40a2d4eb91402b458014b781f5733d60f" dependencies = [ - "digest", + "digest 0.10.7", ] [[package]] @@ -3775,7 +3812,7 @@ version = "1.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "019ece39bbefc17f13f677a690328cb978dbf6790e141a3c24e66372cb38588b" dependencies = [ - "digest", + "digest 0.10.7", ] [[package]] @@ -3888,6 +3925,15 @@ dependencies = [ "quick-error 1.2.3", ] +[[package]] +name = "hybrid-array" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da" +dependencies = [ + "typenum", +] + [[package]] name = "hyper" version = "0.14.32" @@ -3906,7 +3952,7 @@ dependencies = [ "itoa", "pin-project-lite 0.2.17", "socket2 0.5.10", - "tokio 1.51.0", + "tokio 1.52.3", "tower-service", "tracing", "want", @@ -3922,7 +3968,7 @@ dependencies = [ "bytes 1.11.1", "futures-channel", "futures-core", - "h2 0.4.13", + "h2 0.4.14", "http 1.4.0", "http-body 1.0.1", "httparse", @@ -3930,7 +3976,7 @@ dependencies = [ "itoa", "pin-project-lite 0.2.17", "smallvec", - "tokio 1.51.0", + "tokio 1.52.3", "want", ] @@ -3946,7 +3992,7 @@ dependencies = [ "log", "rustls 0.21.12", "rustls-native-certs 0.6.3", - "tokio 1.51.0", + "tokio 1.52.3", "tokio-rustls 0.24.1", ] @@ -3962,7 +4008,7 @@ dependencies = [ "hyper-util", "rustls 0.22.4", "rustls-pki-types", - "tokio 1.51.0", + "tokio 1.52.3", "tokio-rustls 0.25.0", "tower-service", "webpki-roots 0.26.11", @@ -3970,17 +4016,16 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.7" +version = "0.27.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" dependencies = [ "http 1.4.0", "hyper 1.9.0", "hyper-util", - "rustls 0.23.37", + "rustls 0.23.40", "rustls-native-certs 0.8.3", - "rustls-pki-types", - "tokio 1.51.0", + "tokio 1.52.3", "tokio-rustls 0.26.4", "tower-service", ] @@ -3994,7 +4039,7 @@ dependencies = [ "bytes 1.11.1", "hyper 0.14.32", "native-tls", - "tokio 1.51.0", + "tokio 1.52.3", "tokio-native-tls", ] @@ -4017,7 +4062,7 @@ dependencies = [ "pin-project-lite 0.2.17", "socket2 0.6.3", "system-configuration 0.7.0", - "tokio 1.51.0", + "tokio 1.52.3", "tower-service", "tracing", "windows-registry", @@ -4141,17 +4186,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" -[[package]] -name = "idna" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - [[package]] name = "idna" version = "0.3.0" @@ -4185,9 +4219,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" dependencies = [ "icu_normalizer", "icu_properties", @@ -4209,7 +4243,7 @@ dependencies = [ "byteorder-lite", "color_quant", "exr", - "gif 0.14.1", + "gif 0.14.2", "image-webp 0.2.4", "moxcms", "num-traits", @@ -4251,9 +4285,9 @@ checksum = "edcd27d72f2f071c64249075f42e205ff93c9a4c5f6c6da53e79ed9f9832c285" [[package]] name = "imgref" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c5cedc30da3a610cac6b4ba17597bdf7152cf974e8aab3afb3d54455e371c8" +checksum = "40fac9d56ed6437b198fddba683305e8e2d651aa42647f00f5ae542e7f5c94a2" [[package]] name = "impl_ops" @@ -4274,12 +4308,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.13.1" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45a8a2b9cb3e0b0c1803dbb0758ffac5de2f425b23c28f518faabd9d805342ff" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.16.1", + "hashbrown 0.17.1", "serde", "serde_core", ] @@ -4351,16 +4385,6 @@ dependencies = [ "serde", ] -[[package]] -name = "iri-string" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20" -dependencies = [ - "memchr", - "serde", -] - [[package]] name = "is-terminal" version = "0.4.17" @@ -4374,9 +4398,9 @@ dependencies = [ [[package]] name = "isahc" -version = "1.8.0" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49980b382c0e59635b99bb2d9ef4c039a90aefa1b821d5d7a8526d4504e14594" +checksum = "82d93e1769c5c2b13a8e0d8ca9b6466c60bafade047326f25e3bcb97a947d875" dependencies = [ "async-channel 2.5.0", "castaway", @@ -4406,7 +4430,7 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d4e5d712dd664b11e778d1cfc06c79ba2700d6bc1771e44fb7b6a4656b487d" dependencies = [ - "generic-array 1.3.5", + "generic-array 1.4.1", "schemars", "serde", "time", @@ -4531,9 +4555,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.94" +version = "0.3.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e04e2ef80ce82e13552136fabeef8a5ed1f985a96805761cbb9a2c34e7664d9" +checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08" dependencies = [ "cfg-if", "futures-util", @@ -4554,23 +4578,24 @@ dependencies = [ [[package]] name = "jsonwebtoken" -version = "10.3.0" +version = "10.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0529410abe238729a60b108898784df8984c87f6054c9c4fcacc47e4803c1ce1" +checksum = "eba32bfb4ffdeaca3e34431072faf01745c9b26d25504aa7a6cf5684334fc4fc" dependencies = [ "base64 0.22.1", "ed25519-dalek", "getrandom 0.2.17", - "hmac", + "hmac 0.12.1", "js-sys", "p256 0.13.2", "p384", - "rand 0.8.5", + "rand 0.8.6", "rsa 0.9.10", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "signature 2.2.0", + "zeroize", ] [[package]] @@ -4590,7 +4615,7 @@ dependencies = [ "k256", "p256 0.13.2", "p384", - "rand 0.8.5", + "rand 0.8.6", "rsa 0.7.2", "serde", "serde_json", @@ -4789,7 +4814,7 @@ dependencies = [ "ecdsa 0.16.9", "elliptic-curve 0.13.8", "once_cell", - "sha2", + "sha2 0.10.9", "signature 2.2.0", ] @@ -4824,9 +4849,9 @@ dependencies = [ [[package]] name = "lapin" -version = "4.7.1" +version = "4.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478790661081f7434e111a31953acc1cf23654cf2a2d815d0e12cef9a2aed720" +checksum = "f296d806dbacc044135c9686a0d3e78b5122907d4d6604c72a825316139e9f2d" dependencies = [ "amq-protocol", "async-rs", @@ -4904,14 +4929,14 @@ dependencies = [ "once_cell", "quoted_printable", "socket2 0.4.10", - "tokio 1.51.0", + "tokio 1.52.3", ] [[package]] name = "libc" -version = "0.2.184" +version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libfuzzer-sys" @@ -5008,11 +5033,12 @@ checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" [[package]] name = "livekit-api" -version = "0.4.18" +version = "0.4.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2247e3127fc52f9cc30f2763726f0508120d0424bd5159464d731cb58e2bea1" +checksum = "6479ff15fd0108f8ebd698b4458dce5091686b8c11e130e08e99a925f1cc1881" dependencies = [ "base64 0.21.7", + "device-info", "http 1.4.0", "jsonwebtoken", "livekit-protocol", @@ -5021,34 +5047,29 @@ dependencies = [ "parking_lot", "pbjson-types", "prost", - "rand 0.9.2", + "rand 0.9.4", "reqwest 0.12.28", - "rustls-native-certs 0.6.3", + "rustls-native-certs 0.8.3", "scopeguard", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "thiserror 2.0.18", - "tokio-rustls 0.24.1", + "tokio-rustls 0.26.4", "tokio-tungstenite", "url", ] [[package]] name = "livekit-protocol" -version = "0.7.4" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d080ff1e4806c4b57427db696dc093e1a6817de9500a262167259cf7bab646e" +checksum = "dd59f3759f1a14e60b6bc6d4d415414e1aed686c8e4d2c7862542d95301cdc70" dependencies = [ - "futures-util", - "livekit-runtime", - "parking_lot", "pbjson", "pbjson-types", "prost", "serde", - "thiserror 2.0.18", - "tokio 1.51.0", ] [[package]] @@ -5057,7 +5078,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "532e84c6cdc5fe774f2b5d9912597b5f3bea561927a48296d03e24549d21c3f6" dependencies = [ - "tokio 1.51.0", + "tokio 1.52.3", "tokio-stream", ] @@ -5139,9 +5160,9 @@ dependencies = [ [[package]] name = "lru" -version = "0.16.3" +version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1dc47f592c06f33f8e3aea9591776ec7c9f9e4124778ff8a3c3b87159f7e593" +checksum = "7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39" dependencies = [ "hashbrown 0.16.1", ] @@ -5241,12 +5262,6 @@ dependencies = [ "regex-automata", ] -[[package]] -name = "matches" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" - [[package]] name = "matchit" version = "0.7.3" @@ -5270,7 +5285,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" dependencies = [ "cfg-if", - "digest", + "digest 0.10.7", +] + +[[package]] +name = "md-5" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69b6441f590336821bb897fb28fc622898ccceb1d6cea3fde5ea86b090c4de98" +dependencies = [ + "cfg-if", + "digest 0.11.3", ] [[package]] @@ -5346,7 +5371,7 @@ dependencies = [ "log", "metrics", "thiserror 1.0.69", - "tokio 1.51.0", + "tokio 1.52.3", "tracing", "tracing-subscriber", ] @@ -5401,12 +5426,12 @@ checksum = "224484c5d09285a7b8cb0a0c117e847ebd14cb6e4470ecf68cdb89c503b0edb9" [[package]] name = "mongodb" -version = "3.5.2" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c5941683db2ab2697f71e58dc0319024e808d3b28e7cf20f4bfb445fe54a30b" +checksum = "1ef2c933617431ad0246fb5b43c425ebdae18c7f7259c87de0726d93b0e7e91b" dependencies = [ "base64 0.22.1", - "bitflags 2.11.0", + "bitflags 2.11.1", "bson", "derive-where", "derive_more 2.1.1", @@ -5416,40 +5441,40 @@ dependencies = [ "hex", "hickory-proto 0.25.2", "hickory-resolver 0.25.2", - "hmac", + "hmac 0.12.1", "macro_magic", - "md-5", + "md-5 0.10.6", "mongocrypt", "mongodb-internal-macros", "pbkdf2", "percent-encoding", - "rand 0.9.2", + "rand 0.9.4", "rustc_version_runtime", - "rustls 0.23.37", + "rustls 0.23.40", "rustversion", "serde", "serde_bytes", "serde_with", - "sha1", - "sha2", + "sha1 0.10.6", + "sha2 0.10.9", "socket2 0.6.3", "stringprep", "strsim 0.11.1", "take_mut", "thiserror 2.0.18", - "tokio 1.51.0", + "tokio 1.52.3", "tokio-rustls 0.26.4", "tokio-util", "typed-builder", "uuid", - "webpki-roots 1.0.6", + "webpki-roots 1.0.7", ] [[package]] name = "mongodb-internal-macros" -version = "3.5.2" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47021a12bbf0dffde9c890fa2d36ff6ae342c532016226b04a42301b2b912660" +checksum = "9e5758dc828eb2d02ec30563cba365609d56ddd833190b192beaee2b475a7bb3" dependencies = [ "macro_magic", "proc-macro2", @@ -5481,7 +5506,7 @@ dependencies = [ "memchr", "mime", "spin 0.9.8", - "tokio 1.51.0", + "tokio 1.52.3", "tokio-util", "version_check", ] @@ -5504,7 +5529,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ffa00dec017b5b1a8b7cf5e2c008bfda1aa7e0697ac1508b491fdf2622fb4d8" dependencies = [ - "rand 0.8.5", + "rand 0.8.6", ] [[package]] @@ -5542,12 +5567,21 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "cfg-if", "cfg_aliases", "libc", ] +[[package]] +name = "no_std_io2" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418abd1b6d34fbf6cae440dc874771b0525a604428704c76e48b29a5e67b8003" +dependencies = [ + "memchr", +] + [[package]] name = "nom" version = "7.1.3" @@ -5612,16 +5646,16 @@ dependencies = [ "num-integer", "num-iter", "num-traits", - "rand 0.8.5", + "rand 0.8.6", "smallvec", "zeroize", ] [[package]] name = "num-conv" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" [[package]] name = "num-derive" @@ -5730,7 +5764,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "objc2", "objc2-foundation", ] @@ -5751,7 +5785,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "dispatch2", "objc2", ] @@ -5762,7 +5796,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "dispatch2", "objc2", "objc2-core-foundation", @@ -5795,7 +5829,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "objc2", "objc2-core-foundation", "objc2-core-graphics", @@ -5813,7 +5847,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "block2", "libc", "objc2", @@ -5826,7 +5860,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "objc2", "objc2-core-foundation", ] @@ -5837,7 +5871,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "objc2", "objc2-core-foundation", "objc2-foundation", @@ -5849,7 +5883,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "block2", "objc2", "objc2-cloud-kit", @@ -5916,15 +5950,14 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.76" +version = "0.10.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "951c002c75e16ea2c65b8c7e4d3d51d5530d8dfa7d060b4776828c88cfb18ecf" +checksum = "a45fa2aa886c42762255da344f0a0d313e254066c46aad76f300c3d3da62d967" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "cfg-if", "foreign-types 0.3.2", "libc", - "once_cell", "openssl-macros", "openssl-sys", ] @@ -5954,9 +5987,9 @@ checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] name = "openssl-sys" -version = "0.9.112" +version = "0.9.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d55af3b3e226502be1526dfdba67ab0e9c96fc293004e79576b2b9edb0dbdb" +checksum = "f28a22dc7140cda5f096e5e7724a6962ca81a7f8bfd2979f9b18c11af56318c4" dependencies = [ "cc", "libc", @@ -6008,13 +6041,13 @@ dependencies = [ "der 0.7.10", "des", "hex", - "hmac", + "hmac 0.12.1", "pkcs12", "pkcs5", "rand 0.10.1", "rc2", - "sha1", - "sha2", + "sha1 0.10.6", + "sha2 0.10.9", "thiserror 2.0.18", "x509-parser", ] @@ -6027,7 +6060,7 @@ checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" dependencies = [ "ecdsa 0.14.8", "elliptic-curve 0.12.3", - "sha2", + "sha2 0.10.9", ] [[package]] @@ -6039,7 +6072,7 @@ dependencies = [ "ecdsa 0.16.9", "elliptic-curve 0.13.8", "primeorder", - "sha2", + "sha2 0.10.9", ] [[package]] @@ -6051,7 +6084,7 @@ dependencies = [ "ecdsa 0.16.9", "elliptic-curve 0.13.8", "primeorder", - "sha2", + "sha2 0.10.9", ] [[package]] @@ -6144,8 +6177,8 @@ version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ - "digest", - "hmac", + "digest 0.10.7", + "hmac 0.12.1", ] [[package]] @@ -6184,7 +6217,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "sha2", + "sha2 0.10.9", "url", ] @@ -6356,7 +6389,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89815c69d36021a140146f26659a81d6c2afa33d216d736dd4be5381a7362220" dependencies = [ "pest", - "sha2", + "sha2 0.10.9", ] [[package]] @@ -6366,7 +6399,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.13.1", + "indexmap 2.14.0", ] [[package]] @@ -6415,7 +6448,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" dependencies = [ "phf_shared 0.10.0", - "rand 0.8.5", + "rand 0.8.6", ] [[package]] @@ -6425,7 +6458,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ "phf_shared 0.11.3", - "rand 0.8.5", + "rand 0.8.6", ] [[package]] @@ -6456,7 +6489,7 @@ version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" dependencies = [ - "siphasher 1.0.2", + "siphasher 1.0.3", ] [[package]] @@ -6467,18 +6500,18 @@ checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" [[package]] name = "pin-project" -version = "1.1.11" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.11" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote 1.0.45", @@ -6510,7 +6543,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c835479a4443ded371d6c535cbfd8d31ad92c5d23ae9770a61bc155e4992a3c1" dependencies = [ "atomic-waker", - "fastrand 2.4.0", + "fastrand 2.4.1", "futures-io", ] @@ -6546,7 +6579,7 @@ dependencies = [ "cms", "const-oid 0.9.6", "der 0.7.10", - "digest", + "digest 0.10.7", "spki 0.7.3", "x509-cert", "zeroize", @@ -6563,7 +6596,7 @@ dependencies = [ "der 0.7.10", "pbkdf2", "scrypt", - "sha2", + "sha2 0.10.9", "spki 0.7.3", ] @@ -6589,9 +6622,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" [[package]] name = "png" @@ -6612,7 +6645,7 @@ version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "crc32fast", "fdeflate", "flate2", @@ -6683,9 +6716,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "prefix-trie" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f561214012d3fc240a1f9c817cc4d57f5310910d066069c1b093f766bb5966" +checksum = "4cf6e3177f0684016a5c209b00882e15f8bdd3f3bb48f0491df10cd102d0c6e7" dependencies = [ "either", "ipnet", @@ -6801,18 +6834,18 @@ dependencies = [ [[package]] name = "profiling" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773" +checksum = "3d595e54a326bc53c1c197b32d295e14b169e3cfeaa8dc82b529f947fba6bcf5" dependencies = [ "profiling-procmacros", ] [[package]] name = "profiling-procmacros" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52717f9a02b6965224f95ca2a81e2e0c5c43baacd28ca057577988930b6c3d5b" +checksum = "4488a4a36b9a4ba6b9334a32a39971f77c1436ec82c38707bce707699cc3bbcb" dependencies = [ "quote 1.0.45", "syn 2.0.117", @@ -6918,7 +6951,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4aeaa1f2460f1d348eeaeed86aea999ce98c1bded6f089ff8514c9d9dbdc973" dependencies = [ "anyhow", - "indexmap 2.13.1", + "indexmap 2.14.0", "log", "protobuf", "protobuf-support", @@ -6948,9 +6981,9 @@ dependencies = [ [[package]] name = "pxfm" -version = "0.1.28" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5a041e753da8b807c9255f28de81879c78c876392ff2469cde94799b2896b9d" +checksum = "e0c5ccf5294c6ccd63a74f1565028353830a9c2f5eb0c682c355c471726a6e3f" [[package]] name = "qoi" @@ -6991,10 +7024,10 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.23.37", + "rustls 0.23.40", "socket2 0.6.3", "thiserror 2.0.18", - "tokio 1.51.0", + "tokio 1.52.3", "tracing", "web-time", ] @@ -7009,10 +7042,10 @@ dependencies = [ "bytes 1.11.1", "getrandom 0.3.4", "lru-slab", - "rand 0.9.2", + "rand 0.9.4", "ring", "rustc-hash", - "rustls 0.23.37", + "rustls 0.23.40", "rustls-pki-types", "slab", "thiserror 2.0.18", @@ -7076,9 +7109,9 @@ checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" [[package]] name = "rand" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" dependencies = [ "libc", "rand_chacha 0.3.1", @@ -7087,9 +7120,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.2" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.5", @@ -7177,7 +7210,7 @@ dependencies = [ "num-traits", "paste", "profiling", - "rand 0.9.2", + "rand 0.9.4", "rand_chacha 0.9.0", "simd_helpers", "thiserror 2.0.18", @@ -7202,9 +7235,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" dependencies = [ "either", "rayon-core", @@ -7245,7 +7278,7 @@ dependencies = [ "ryu", "sha1_smol", "socket2 0.4.10", - "tokio 1.51.0", + "tokio 1.52.3", "tokio-util", "url", ] @@ -7286,7 +7319,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", ] [[package]] @@ -7374,7 +7407,7 @@ dependencies = [ "serde_urlencoded", "sync_wrapper 0.1.2", "system-configuration 0.5.1", - "tokio 1.51.0", + "tokio 1.52.3", "tokio-native-tls", "tower-service", "url", @@ -7397,24 +7430,24 @@ dependencies = [ "http-body 1.0.1", "http-body-util", "hyper 1.9.0", - "hyper-rustls 0.27.7", + "hyper-rustls 0.27.9", "hyper-util", "js-sys", "log", "percent-encoding", "pin-project-lite 0.2.17", "quinn", - "rustls 0.23.37", + "rustls 0.23.40", "rustls-native-certs 0.8.3", "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", "sync_wrapper 1.0.2", - "tokio 1.51.0", + "tokio 1.52.3", "tokio-rustls 0.26.4", "tower", - "tower-http 0.6.8", + "tower-http 0.6.11", "tower-service", "url", "wasm-bindgen", @@ -7424,20 +7457,20 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801" +checksum = "62e0021ea2c22aed41653bc7e1419abb2c97e038ff2c33d0e1309e49a97deec0" dependencies = [ "base64 0.22.1", "bytes 1.11.1", "encoding_rs", "futures-core", - "h2 0.4.13", + "h2 0.4.14", "http 1.4.0", "http-body 1.0.1", "http-body-util", "hyper 1.9.0", - "hyper-rustls 0.27.7", + "hyper-rustls 0.27.9", "hyper-util", "js-sys", "log", @@ -7445,17 +7478,17 @@ dependencies = [ "percent-encoding", "pin-project-lite 0.2.17", "quinn", - "rustls 0.23.37", + "rustls 0.23.40", "rustls-pki-types", - "rustls-platform-verifier 0.6.2", + "rustls-platform-verifier", "serde", "serde_json", "serde_urlencoded", "sync_wrapper 1.0.2", - "tokio 1.51.0", + "tokio 1.52.3", "tokio-rustls 0.26.4", "tower", - "tower-http 0.6.8", + "tower-http 0.6.11", "tower-service", "url", "wasm-bindgen", @@ -7511,16 +7544,16 @@ dependencies = [ "revolt_clamav-client", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "simdutf8", "strum_macros", "tempfile", "thumbhash", - "tokio 1.51.0", + "tokio 1.52.3", "tower-http 0.5.2", "tracing", "tracing-subscriber", - "ulid 1.2.1", + "ulid", "url-escape", "utoipa", "utoipa-scalar", @@ -7534,7 +7567,6 @@ dependencies = [ "async-channel 2.5.0", "async-std", "async-tungstenite", - "authifier", "bincode", "fred", "futures", @@ -7555,16 +7587,16 @@ dependencies = [ "sentry", "serde", "serde_json", - "ulid 1.2.1", + "ulid", ] [[package]] name = "revolt-coalesced" version = "0.13.7" dependencies = [ - "indexmap 2.13.1", + "indexmap 2.14.0", "lru", - "tokio 1.51.0", + "tokio 1.52.3", ] [[package]] @@ -7576,7 +7608,6 @@ dependencies = [ "config", "futures-locks", "log", - "once_cell", "pretty_env_logger", "revolt-result", "sentry", @@ -7588,6 +7619,7 @@ dependencies = [ name = "revolt-crond" version = "0.13.7" dependencies = [ + "futures", "futures-lite", "iso8601-timestamp", "lapin", @@ -7601,7 +7633,7 @@ dependencies = [ "revolt_optional_struct", "serde", "serde_json", - "tokio 1.51.0", + "tokio 1.52.3", ] [[package]] @@ -7612,17 +7644,19 @@ dependencies = [ "async-recursion", "async-std", "async-trait", - "authifier", "axum", + "base32", "base64 0.21.7", "bson", "deadqueue", "decancer", "futures", - "indexmap 2.13.1", + "handlebars", + "indexmap 2.14.0", "isahc", "iso8601-timestamp", "lapin", + "lettre", "linkify", "livekit-api", "livekit-protocol", @@ -7632,9 +7666,10 @@ dependencies = [ "mongodb", "nanoid", "once_cell", - "rand 0.8.5", + "rand 0.8.6", "redis-kiss", "regex", + "reqwest 0.13.3", "revolt-coalesced", "revolt-config", "revolt-models", @@ -7646,13 +7681,17 @@ dependencies = [ "revolt_optional_struct", "revolt_rocket_okapi", "rocket", + "rust-argon2", "schemars", "serde", "serde_json", - "ulid 1.2.1", + "sha1 0.10.6", + "totp-lite", + "ulid", "unicode-segmentation", "url-escape", - "validator 0.16.1", + "utoipa", + "validator", ] [[package]] @@ -7661,7 +7700,6 @@ version = "0.13.7" dependencies = [ "async-channel 2.5.0", "async-std", - "authifier", "bitfield", "chrono", "dashmap", @@ -7678,10 +7716,10 @@ dependencies = [ "nanoid", "num_enum", "once_cell", - "rand 0.8.5", + "rand 0.8.6", "redis-kiss", "regex", - "reqwest 0.13.2", + "reqwest 0.13.3", "revolt-config", "revolt-database", "revolt-models", @@ -7691,16 +7729,15 @@ dependencies = [ "revolt-result", "revolt_rocket_okapi", "rocket", - "rocket_authifier", "rocket_cors", "rocket_empty", "rocket_prometheus", "schemars", "serde", "serde_json", - "ulid 1.2.1", + "ulid", "url", - "validator 0.16.1", + "validator", "vergen", ] @@ -7724,7 +7761,7 @@ dependencies = [ "tempfile", "thiserror 2.0.18", "tiny-skia", - "tokio 1.51.0", + "tokio 1.52.3", "tracing", "typenum", "usvg", @@ -7739,7 +7776,7 @@ dependencies = [ "axum", "axum-extra", "lru_time_cache", - "reqwest 0.13.2", + "reqwest 0.13.3", "revolt-coalesced", "revolt-config", "revolt-database", @@ -7748,7 +7785,7 @@ dependencies = [ "revolt-result", "serde", "serde_json", - "tokio 1.51.0", + "tokio 1.52.3", "tower-http 0.5.2", "tracing", "utoipa", @@ -7768,7 +7805,7 @@ dependencies = [ "moka", "pdk-ip-filter-lib", "regex", - "reqwest 0.13.2", + "reqwest 0.13.3", "revolt-config", "revolt-files", "revolt-models", @@ -7777,7 +7814,7 @@ dependencies = [ "serde", "serde_json", "tempfile", - "tokio 1.51.0", + "tokio 1.52.3", "tracing", "tracing-subscriber", "url", @@ -7789,7 +7826,7 @@ dependencies = [ name = "revolt-models" version = "0.13.7" dependencies = [ - "indexmap 2.13.1", + "indexmap 2.14.0", "iso8601-timestamp", "num_enum", "once_cell", @@ -7800,8 +7837,9 @@ dependencies = [ "rocket", "schemars", "serde", + "serde_json", "utoipa", - "validator 0.16.1", + "validator", ] [[package]] @@ -7833,7 +7871,7 @@ dependencies = [ "async-std", "log", "once_cell", - "rand 0.8.5", + "rand 0.8.6", "redis-kiss", "revolt-config", ] @@ -7844,7 +7882,6 @@ version = "0.13.7" dependencies = [ "anyhow", "async-trait", - "authifier", "base64 0.21.7", "fcm_v1", "isahc", @@ -7864,8 +7901,8 @@ dependencies = [ "revolt_optional_struct", "serde", "serde_json", - "tokio 1.51.0", - "ulid 1.2.1", + "tokio 1.52.3", + "ulid", "web-push", ] @@ -7874,7 +7911,6 @@ name = "revolt-ratelimits" version = "0.13.7" dependencies = [ "async-trait", - "authifier", "axum", "dashmap", "log", @@ -7926,7 +7962,7 @@ dependencies = [ "sentry", "serde", "serde_json", - "ulid 1.2.1", + "ulid", ] [[package]] @@ -7951,7 +7987,7 @@ dependencies = [ "serde", "serde_json", "thiserror 1.0.69", - "tokio 1.51.0", + "tokio 1.52.3", ] [[package]] @@ -8018,7 +8054,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ "crypto-bigint 0.4.9", - "hmac", + "hmac 0.12.1", "zeroize", ] @@ -8028,7 +8064,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "hmac", + "hmac 0.12.1", "subtle", ] @@ -8088,14 +8124,14 @@ dependencies = [ "either", "figment", "futures", - "indexmap 2.13.1", + "indexmap 2.14.0", "log", "memchr", "multer", "num_cpus", "parking_lot", "pin-project-lite 0.2.17", - "rand 0.8.5", + "rand 0.8.6", "ref-cast", "rocket_codegen", "rocket_http", @@ -8104,7 +8140,7 @@ dependencies = [ "state", "tempfile", "time", - "tokio 1.51.0", + "tokio 1.52.3", "tokio-stream", "tokio-util", "ubyte", @@ -8112,22 +8148,6 @@ dependencies = [ "yansi", ] -[[package]] -name = "rocket_authifier" -version = "1.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a4e9660d198ea0165dc2694e7620d8fe199e923b39bec4d12b7159da5a4a6cd" -dependencies = [ - "authifier", - "iso8601-timestamp", - "revolt_okapi", - "revolt_rocket_okapi", - "rocket", - "rocket_empty", - "schemars", - "serde", -] - [[package]] name = "rocket_codegen" version = "0.5.1" @@ -8136,7 +8156,7 @@ checksum = "575d32d7ec1a9770108c879fc7c47815a80073f96ca07ff9525a94fcede1dd46" dependencies = [ "devise", "glob", - "indexmap 2.13.1", + "indexmap 2.14.0", "proc-macro2", "quote 1.0.45", "rocket_http", @@ -8183,7 +8203,7 @@ dependencies = [ "futures", "http 0.2.12", "hyper 0.14.32", - "indexmap 2.13.1", + "indexmap 2.14.0", "log", "memchr", "pear", @@ -8195,7 +8215,7 @@ dependencies = [ "stable-pattern", "state", "time", - "tokio 1.51.0", + "tokio 1.52.3", "uncased", ] @@ -8233,7 +8253,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "094052d5470cbcef561cb848a7209968c9f12dfa6d668f4bca048ac5de51099c" dependencies = [ "byteorder", - "digest", + "digest 0.10.7", "num-bigint-dig", "num-integer", "num-iter", @@ -8254,7 +8274,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" dependencies = [ "const-oid 0.9.6", - "digest", + "digest 0.10.7", "num-bigint-dig", "num-integer", "num-traits", @@ -8335,7 +8355,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "errno", "libc", "linux-raw-sys 0.4.15", @@ -8348,7 +8368,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "errno", "libc", "linux-raw-sys 0.12.1", @@ -8383,33 +8403,33 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.37" +version = "0.23.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" +checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" dependencies = [ "aws-lc-rs", "log", "once_cell", "ring", "rustls-pki-types", - "rustls-webpki 0.103.10", + "rustls-webpki 0.103.13", "subtle", "zeroize", ] [[package]] name = "rustls-connector" -version = "0.23.1" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26bcb6901a3319d57589047c0da93a0f3228f13abf8dd949deef024749cb5e2" +checksum = "546c32c0a03187814b1e1239eec017778dc9b87d8241a2c5c1954c47ab8ac8fd" dependencies = [ "futures-io", "futures-rustls", "log", - "rustls 0.23.37", + "rustls 0.23.40", "rustls-pki-types", - "rustls-platform-verifier 0.7.0", - "rustls-webpki 0.103.10", + "rustls-platform-verifier", + "rustls-webpki 0.103.13", ] [[package]] @@ -8456,35 +8476,14 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.14.0" +version = "1.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" dependencies = [ "web-time", "zeroize", ] -[[package]] -name = "rustls-platform-verifier" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" -dependencies = [ - "core-foundation 0.10.1", - "core-foundation-sys", - "jni 0.21.1", - "log", - "once_cell", - "rustls 0.23.37", - "rustls-native-certs 0.8.3", - "rustls-platform-verifier-android", - "rustls-webpki 0.103.10", - "security-framework 3.7.0", - "security-framework-sys", - "webpki-root-certs", - "windows-sys 0.61.2", -] - [[package]] name = "rustls-platform-verifier" version = "0.7.0" @@ -8496,10 +8495,10 @@ dependencies = [ "jni 0.22.4", "log", "once_cell", - "rustls 0.23.37", + "rustls 0.23.40", "rustls-native-certs 0.8.3", "rustls-platform-verifier-android", - "rustls-webpki 0.103.10", + "rustls-webpki 0.103.13", "security-framework 3.7.0", "security-framework-sys", "webpki-root-certs", @@ -8535,9 +8534,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.10" +version = "0.103.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef" +checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" dependencies = [ "aws-lc-rs", "ring", @@ -8557,7 +8556,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c85d1ccd519e61834798eb52c4e886e8c2d7d698dd3d6ce0b1b47eb8557f1181" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "bytemuck", "core_maths", "log", @@ -8610,7 +8609,7 @@ checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" dependencies = [ "dyn-clone", "indexmap 1.9.3", - "indexmap 2.13.1", + "indexmap 2.14.0", "schemars_derive", "serde", "serde_json", @@ -8664,7 +8663,7 @@ checksum = "0516a385866c09368f0b5bcd1caff3366aace790fcd46e2bb032697bb172fd1f" dependencies = [ "pbkdf2", "salsa20", - "sha2", + "sha2 0.10.9", ] [[package]] @@ -8728,7 +8727,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "core-foundation 0.9.4", "core-foundation-sys", "libc", @@ -8741,7 +8740,7 @@ version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "core-foundation 0.10.1", "core-foundation-sys", "libc", @@ -8764,7 +8763,7 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4eb30575f3638fc8f6815f448d50cb1a2e255b0897985c8c59f4d37b72a07b06" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "cssparser", "derive_more 0.99.20", "fxhash", @@ -8798,7 +8797,7 @@ dependencies = [ "sentry-debug-images", "sentry-panic", "sentry-tracing", - "tokio 1.51.0", + "tokio 1.52.3", "ureq", ] @@ -8857,7 +8856,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "901f761681f97db3db836ef9e094acdd8756c40215326c194201941947164ef1" dependencies = [ "once_cell", - "rand 0.8.5", + "rand 0.8.6", "sentry-types 0.31.8", "serde", "serde_json", @@ -8915,7 +8914,7 @@ checksum = "da956cca56e0101998c8688bc65ce1a96f00673a0e58e663664023d4c7911e82" dependencies = [ "debugid", "hex", - "rand 0.8.5", + "rand 0.8.6", "serde", "serde_json", "thiserror 1.0.69", @@ -8932,7 +8931,7 @@ checksum = "04b6c9287202294685cb1f749b944dbbce8160b81a1061ecddc073025fed129f" dependencies = [ "debugid", "hex", - "rand 0.9.2", + "rand 0.9.4", "serde", "serde_json", "thiserror 2.0.18", @@ -8998,7 +8997,7 @@ version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ - "indexmap 2.13.1", + "indexmap 2.14.0", "itoa", "memchr", "serde", @@ -9040,9 +9039,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.18.0" +version = "3.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd5414fad8e6907dbdd5bc441a50ae8d6e26151a03b1de04d89a5576de61d01f" +checksum = "e72c1c2cb7b223fafb600a619537a871c2818583d619401b785e7c0b746ccde2" dependencies = [ "serde_core", "serde_with_macros", @@ -9050,9 +9049,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.18.0" +version = "3.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3db8978e608f1fe7357e211969fd9abdcae80bac1ba7a3369bb7eb6b404eb65" +checksum = "b90c488738ecb4fb0262f41f43bc40efc5868d9fb744319ddf5f5317f417bfac" dependencies = [ "darling 0.23.0", "proc-macro2", @@ -9077,7 +9076,7 @@ checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" dependencies = [ "cfg-if", "cpufeatures 0.2.17", - "digest", + "digest 0.10.7", ] [[package]] @@ -9088,7 +9087,18 @@ checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", "cpufeatures 0.2.17", - "digest", + "digest 0.10.7", +] + +[[package]] +name = "sha1" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aacc4cc499359472b4abe1bf11d0b12e688af9a805fa5e3016f9a386dc2d0214" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "digest 0.11.3", ] [[package]] @@ -9105,7 +9115,18 @@ checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures 0.2.17", - "digest", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "digest 0.11.3", ] [[package]] @@ -9139,7 +9160,7 @@ version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ - "digest", + "digest 0.10.7", "rand_core 0.6.4", ] @@ -9149,7 +9170,7 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "digest", + "digest 0.10.7", "rand_core 0.6.4", ] @@ -9201,9 +9222,9 @@ checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" [[package]] name = "siphasher" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" +checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" [[package]] name = "slab" @@ -9409,7 +9430,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68c7541fff44b35860c1a7a47a7cadf3e4a304c457b58f9870d9706ece028afc" dependencies = [ "kurbo", - "siphasher 1.0.2", + "siphasher 1.0.3", ] [[package]] @@ -9523,7 +9544,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "core-foundation 0.9.4", "system-configuration-sys 0.6.0", ] @@ -9568,9 +9589,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tcp-stream" -version = "0.34.6" +version = "0.34.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd7219422d3348cddeaf9073772997c452085c33e22d0b08cbd19652e1b16da5" +checksum = "e8da40490cac3733b85c67b831f64e2132fdaa0929f42a6d4cf458d339777473" dependencies = [ "async-rs", "cfg-if", @@ -9585,7 +9606,7 @@ version = "3.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ - "fastrand 2.4.0", + "fastrand 2.4.1", "getrandom 0.4.2", "once_cell", "rustix 1.1.4", @@ -9787,9 +9808,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.51.0" +version = "1.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bd1c4c0fc4a7ab90fc15ef6daaa3ec3b893f004f915f2392557ed23237820cd" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" dependencies = [ "bytes 1.11.1", "libc", @@ -9820,7 +9841,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ "native-tls", - "tokio 1.51.0", + "tokio 1.52.3", ] [[package]] @@ -9830,7 +9851,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ "rustls 0.21.12", - "tokio 1.51.0", + "tokio 1.52.3", ] [[package]] @@ -9841,7 +9862,7 @@ checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" dependencies = [ "rustls 0.22.4", "rustls-pki-types", - "tokio 1.51.0", + "tokio 1.52.3", ] [[package]] @@ -9850,8 +9871,8 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ - "rustls 0.23.37", - "tokio 1.51.0", + "rustls 0.23.40", + "tokio 1.52.3", ] [[package]] @@ -9862,22 +9883,23 @@ checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" dependencies = [ "futures-core", "pin-project-lite 0.2.17", - "tokio 1.51.0", + "tokio 1.52.3", ] [[package]] name = "tokio-tungstenite" -version = "0.20.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +checksum = "8f72a05e828585856dacd553fba484c242c46e391fb0e58917c942ee9202915c" dependencies = [ "futures-util", "log", - "rustls 0.21.12", - "rustls-native-certs 0.6.3", - "tokio 1.51.0", - "tokio-rustls 0.24.1", - "tungstenite 0.20.1", + "rustls 0.23.40", + "rustls-native-certs 0.8.3", + "rustls-pki-types", + "tokio 1.52.3", + "tokio-rustls 0.26.4", + "tungstenite 0.29.0", ] [[package]] @@ -9891,7 +9913,7 @@ dependencies = [ "futures-io", "futures-sink", "pin-project-lite 0.2.17", - "tokio 1.51.0", + "tokio 1.52.3", ] [[package]] @@ -9930,7 +9952,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.13.1", + "indexmap 2.14.0", "toml_datetime", "winnow 0.5.40", ] @@ -9941,7 +9963,7 @@ version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 2.13.1", + "indexmap 2.14.0", "serde", "serde_spanned", "toml_datetime", @@ -9961,10 +9983,10 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8e43134db17199f7f721803383ac5854edd0d3d523cc34dba321d6acfbe76c3" dependencies = [ - "digest", - "hmac", - "sha1", - "sha2", + "digest 0.10.7", + "hmac 0.12.1", + "sha1 0.10.6", + "sha2 0.10.9", ] [[package]] @@ -9977,7 +9999,7 @@ dependencies = [ "futures-util", "pin-project-lite 0.2.17", "sync_wrapper 1.0.2", - "tokio 1.51.0", + "tokio 1.52.3", "tower-layer", "tower-service", "tracing", @@ -9989,7 +10011,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "bytes 1.11.1", "http 1.4.0", "http-body 1.0.1", @@ -10001,20 +10023,20 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.8" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "bytes 1.11.1", "futures-util", "http 1.4.0", "http-body 1.0.1", - "iri-string", "pin-project-lite 0.2.17", "tower", "tower-layer", "tower-service", + "url", ] [[package]] @@ -10128,7 +10150,7 @@ dependencies = [ "http 0.2.12", "httparse", "log", - "rand 0.8.5", + "rand 0.8.6", "sha-1", "thiserror 1.0.69", "url", @@ -10137,22 +10159,21 @@ dependencies = [ [[package]] name = "tungstenite" -version = "0.20.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" +checksum = "6c01152af293afb9c7c2a57e4b559c5620b421f6d133261c60dd2d0cdb38e6b8" dependencies = [ - "byteorder", "bytes 1.11.1", "data-encoding", - "http 0.2.12", + "http 1.4.0", "httparse", "log", - "rand 0.8.5", - "rustls 0.21.12", - "sha1", - "thiserror 1.0.69", + "rand 0.9.4", + "rustls 0.23.40", + "rustls-pki-types", + "sha1 0.10.6", + "thiserror 2.0.18", "url", - "utf-8", ] [[package]] @@ -10177,9 +10198,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.19.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" [[package]] name = "ubyte" @@ -10196,24 +10217,13 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" -[[package]] -name = "ulid" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "220b18413e1fe5e85a5580b22f44241f82404a66c792c9f3c9eda74c52d9a22e" -dependencies = [ - "chrono", - "rand 0.8.5", - "serde", -] - [[package]] name = "ulid" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "470dbf6591da1b39d43c14523b2b469c86879a53e8b758c8e090a470fe7b1fbe" dependencies = [ - "rand 0.9.2", + "rand 0.9.4", "web-time", ] @@ -10333,7 +10343,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ - "crypto-common", + "crypto-common 0.1.7", "subtle", ] @@ -10401,7 +10411,7 @@ dependencies = [ "roxmltree", "rustybuzz", "simplecss", - "siphasher 1.0.2", + "siphasher 1.0.3", "strict-num", "svgtypes", "tiny-skia-path", @@ -10429,7 +10439,7 @@ version = "4.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5afb1a60e207dca502682537fefcfd9921e71d0b83e9576060f09abc6efab23" dependencies = [ - "indexmap 2.13.1", + "indexmap 2.14.0", "serde", "serde_json", "utoipa-gen", @@ -10446,7 +10456,7 @@ dependencies = [ "quote 1.0.45", "regex", "syn 2.0.117", - "ulid 1.2.1", + "ulid", ] [[package]] @@ -10463,9 +10473,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.23.0" +version = "1.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" +checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" dependencies = [ "getrandom 0.4.2", "js-sys", @@ -10484,21 +10494,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "validator" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f07b0a1390e01c0fc35ebb26b28ced33c9a3808f7f9fbe94d3cc01e233bfeed5" -dependencies = [ - "idna 0.2.3", - "lazy_static", - "regex", - "serde", - "serde_derive", - "serde_json", - "url", -] - [[package]] name = "validator" version = "0.16.1" @@ -10622,11 +10617,11 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.2+wasi-0.2.9" +version = "1.0.3+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" dependencies = [ - "wit-bindgen", + "wit-bindgen 0.57.1", ] [[package]] @@ -10635,7 +10630,7 @@ version = "0.4.0+wasi-0.3.0-rc-2026-01-06" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" dependencies = [ - "wit-bindgen", + "wit-bindgen 0.51.0", ] [[package]] @@ -10649,9 +10644,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.117" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0551fc1bb415591e3372d0bc4780db7e587d84e2a7e79da121051c5c4b89d0b0" +checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790" dependencies = [ "cfg-if", "once_cell", @@ -10662,9 +10657,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.67" +version = "0.4.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03623de6905b7206edd0a75f69f747f134b7f0a2323392d664448bf2d3c5d87e" +checksum = "96492d0d3ffba25305a7dc88720d250b1401d7edca02cc3bcd50633b424673b8" dependencies = [ "js-sys", "wasm-bindgen", @@ -10672,9 +10667,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.117" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fbdf9a35adf44786aecd5ff89b4563a90325f9da0923236f6104e603c7e86be" +checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578" dependencies = [ "quote 1.0.45", "wasm-bindgen-macro-support", @@ -10682,9 +10677,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.117" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dca9693ef2bab6d4e6707234500350d8dad079eb508dca05530c85dc3a529ff2" +checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2" dependencies = [ "bumpalo", "proc-macro2", @@ -10695,9 +10690,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.117" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39129a682a6d2d841b6c429d0c51e5cb0ed1a03829d8b3d1e69a011e62cb3d3b" +checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441" dependencies = [ "unicode-ident", ] @@ -10719,7 +10714,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" dependencies = [ "anyhow", - "indexmap 2.13.1", + "indexmap 2.14.0", "wasm-encoder", "wasmparser", ] @@ -10730,9 +10725,9 @@ version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "hashbrown 0.15.5", - "indexmap 2.13.1", + "indexmap 2.14.0", "semver", ] @@ -10760,9 +10755,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.94" +version = "0.3.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd70027e39b12f0849461e08ffc50b9cd7688d942c1c8e3c7b22273236b4dd0a" +checksum = "4b572dff8bcf38bad0fa19729c89bb5748b2b9b1d8be70cf90df697e3a8f32aa" dependencies = [ "js-sys", "wasm-bindgen", @@ -10790,9 +10785,9 @@ dependencies = [ [[package]] name = "webpki-root-certs" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804f18a4ac2676ffb4e8b5b5fa9ae38af06df08162314f96a68d2a363e21a8ca" +checksum = "f31141ce3fc3e300ae89b78c0dd67f9708061d1d2eda54b8209346fd6be9a92c" dependencies = [ "rustls-pki-types", ] @@ -10803,14 +10798,14 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "webpki-roots 1.0.6", + "webpki-roots 1.0.7", ] [[package]] name = "webpki-roots" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" +checksum = "52f5ee44c96cf55f1b349600768e3ece3a8f26010c05265ab73f945bb1a2eb9d" dependencies = [ "rustls-pki-types", ] @@ -11283,6 +11278,12 @@ dependencies = [ "wit-bindgen-rust-macro", ] +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + [[package]] name = "wit-bindgen-core" version = "0.51.0" @@ -11302,7 +11303,7 @@ checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" dependencies = [ "anyhow", "heck 0.5.0", - "indexmap 2.13.1", + "indexmap 2.14.0", "prettyplease", "syn 2.0.117", "wasm-metadata", @@ -11332,8 +11333,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", - "bitflags 2.11.0", - "indexmap 2.13.1", + "bitflags 2.11.1", + "indexmap 2.14.0", "log", "serde", "serde_derive", @@ -11352,7 +11353,7 @@ checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" dependencies = [ "anyhow", "id-arena", - "indexmap 2.13.1", + "indexmap 2.14.0", "log", "semver", "serde", @@ -11486,7 +11487,7 @@ dependencies = [ "serde", "serde_json", "time", - "tokio 1.51.0", + "tokio 1.52.3", "tower-service", "url", ] @@ -11513,9 +11514,9 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" dependencies = [ "zerofrom-derive", ] @@ -11537,6 +11538,20 @@ name = "zeroize" version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" +dependencies = [ + "proc-macro2", + "quote 1.0.45", + "syn 2.0.117", +] [[package]] name = "zerotrie" diff --git a/Cargo.toml b/Cargo.toml index 6d1335cc4..173740d4d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -65,6 +65,7 @@ encoding_rs = "0.8.34" # Mail lettre = "0.10.0-alpha.4" +handlebars = "4.3.0" # HTTP Requests reqwest = "0.13.2" @@ -155,9 +156,6 @@ opentelemetry_sdk = { version = "0.31.0", features = ["logs"] } opentelemetry-otlp = { version = "0.31.0", features = ["logs"] } opentelemetry-appender-tracing = "0.31.1" -# Authifier -authifier = "1.0.16" - # RabbitMQ lapin = "4.7.1" @@ -185,6 +183,10 @@ url = "2.2.2" impl_ops = "0.1.1" lazy_static = "1.5.0" mime = "0.3.17" +totp-lite = "2.0.0" +rust-argon2 = "1.0.0" +base32 = "0.4.0" +sha1 = "0.10.6" futures-lite = "2.6.1" # Build Dependencies diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index b2687266a..b2a8dffe1 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -34,7 +34,6 @@ async-tungstenite = { workspace = true, features = ["async-std-runtime"] } async-std = { workspace = true } # core -authifier = { workspace = true } revolt-result = { workspace = true } revolt-models = { workspace = true } revolt-config = { workspace = true } diff --git a/crates/bonfire/src/websocket.rs b/crates/bonfire/src/websocket.rs index ee5512896..718c5c525 100644 --- a/crates/bonfire/src/websocket.rs +++ b/crates/bonfire/src/websocket.rs @@ -1,7 +1,6 @@ use std::{collections::HashSet, net::SocketAddr, sync::Arc}; use async_tungstenite::WebSocketStream; -use authifier::AuthifierEvent; use fred::{ error::RedisErrorKind, interfaces::{ClientLike, EventInterface, PubsubInterface}, @@ -355,22 +354,20 @@ async fn listener( break 'out; }; - if let EventV1::Auth(auth) = &event { - if let AuthifierEvent::DeleteSession { session_id, .. } = auth { - if &state.session_id == session_id { - event = EventV1::Logout; - } - } else if let AuthifierEvent::DeleteAllSessions { - exclude_session_id, .. - } = auth - { - if let Some(excluded) = exclude_session_id { - if &state.session_id != excluded { - event = EventV1::Logout; - } - } else { + if let EventV1::DeleteSession { session_id, .. } = &event { + if &state.session_id == session_id { + event = EventV1::Logout; + } + } else if let EventV1::DeleteAllSessions { + exclude_session_id, .. + } = &event + { + if let Some(excluded) = exclude_session_id { + if &state.session_id != excluded { event = EventV1::Logout; } + } else { + event = EventV1::Logout; } } else { let should_send = state.handle_incoming_event_v1(db, &mut event).await; diff --git a/crates/core/config/Cargo.toml b/crates/core/config/Cargo.toml index e9e329c7a..7cda04472 100644 --- a/crates/core/config/Cargo.toml +++ b/crates/core/config/Cargo.toml @@ -14,13 +14,12 @@ anyhow = ["dep:sentry-anyhow"] report-macros = ["revolt-result"] sentry = ["dep:sentry"] test = ["async-std"] -default = ["test", "sentry"] +default = ["sentry"] [dependencies] # Utility config = { workspace = true } cached = { workspace = true } -once_cell = { workspace = true } # Serde serde = { workspace = true } diff --git a/crates/core/config/Revolt.test.toml b/crates/core/config/Revolt.test.toml index d7241d418..684f625fc 100644 --- a/crates/core/config/Revolt.test.toml +++ b/crates/core/config/Revolt.test.toml @@ -1,3 +1,5 @@ +environment = "test" + [database] mongodb = "mongodb://localhost" redis = "redis://localhost/" @@ -10,3 +12,12 @@ password = "rabbitpass" [features] webhooks_enabled = true + +[api.smtp] +host = "localhost" +username = "smtp" +password = "smtp" +from_address = "development@stoat.chat" +reply_to = "support@stoat.chat" +port = 14025 +use_tls = false \ No newline at end of file diff --git a/crates/core/config/Revolt.toml b/crates/core/config/Revolt.toml index e598a3dc8..5fe64cd04 100644 --- a/crates/core/config/Revolt.toml +++ b/crates/core/config/Revolt.toml @@ -1,5 +1,6 @@ production = false disable_events_dont_use = false +environment = "dev" [database] # MongoDB connection URL @@ -53,6 +54,10 @@ from_address = "noreply@example.com" # port = 587 # use_tls = true +[api.smtp.expiry] +expire_verification = 604800 # 3600 * 24 * 7 +expire_password_reset = 86400 # 3600 * 24 +expire_account_deletion = 86400 # 3600 * 24 [api.security] # Authifier Shield API key @@ -71,6 +76,10 @@ tenor_key = "" hcaptcha_key = "" hcaptcha_sitekey = "" +[api.security.shield] +host = "" +key = "" + [api.workers] # Maximum concurrent connections (to proxy server) max_concurrent_connections = 50 diff --git a/crates/core/config/src/lib.rs b/crates/core/config/src/lib.rs index 1ba041cac..257dfa509 100644 --- a/crates/core/config/src/lib.rs +++ b/crates/core/config/src/lib.rs @@ -1,9 +1,10 @@ -use std::{collections::HashMap, path::Path}; +#[cfg(feature = "test")] +use std::sync::OnceLock; +use std::{collections::HashMap, path::Path, sync::LazyLock}; use cached::proc_macro::cached; use config::{Config, Environment, File, FileFormat}; use futures_locks::RwLock; -use once_cell::sync::Lazy; use serde::Deserialize; #[cfg(feature = "sentry")] @@ -66,13 +67,28 @@ static CONFIG_SEARCH_PATHS: [&str; 3] = [ static TEST_OVERRIDE_PATH: &str = "Revolt.test-overrides.toml"; /// Configuration builder -static CONFIG_BUILDER: Lazy> = Lazy::new(|| { +static CONFIG_BUILDER: LazyLock> = LazyLock::new(|| { RwLock::new({ let mut builder = Config::builder().add_source(File::from_str( include_str!("../Revolt.toml"), FileFormat::Toml, )); + let cwd = std::env::current_dir().unwrap(); + let mut cwd: Option<&Path> = Some(&cwd); + + while let Some(path) = cwd { + for config_path in CONFIG_SEARCH_PATHS { + let config_path = path.join(config_path); + if config_path.exists() { + builder = builder + .add_source(File::new(config_path.to_str().unwrap(), FileFormat::Toml)); + } + } + + cwd = path.parent(); + } + if std::env::var("TEST_DB").is_ok() { builder = builder.add_source(File::from_str( include_str!("../Revolt.test.toml"), @@ -94,21 +110,6 @@ static CONFIG_BUILDER: Lazy> = Lazy::new(|| { } } - let cwd = std::env::current_dir().unwrap(); - let mut cwd: Option<&Path> = Some(&cwd); - - while let Some(path) = cwd { - for config_path in CONFIG_SEARCH_PATHS { - let config_path = path.join(config_path); - if config_path.exists() { - builder = builder - .add_source(File::new(config_path.to_str().unwrap(), FileFormat::Toml)); - } - } - - cwd = path.parent(); - } - builder = builder.add_source(Environment::with_prefix("REVOLT").separator("__")); builder.build().unwrap() @@ -162,6 +163,18 @@ pub struct ApiSmtp { pub port: Option, pub use_tls: Option, pub use_starttls: Option, + pub expiry: EmailExpiry, +} + +/// Email expiration config +#[derive(Deserialize, Debug, Clone)] +pub struct EmailExpiry { + /// How long email verification codes should last for (in seconds) + pub expire_verification: i64, + /// How long password reset codes should last for (in seconds) + pub expire_password_reset: i64, + /// How long account deletion codes should last for (in seconds) + pub expire_account_deletion: i64, } #[derive(Deserialize, Debug, Clone)] @@ -201,9 +214,15 @@ pub struct ApiSecurityCaptcha { pub hcaptcha_sitekey: String, } +#[derive(Deserialize, Debug, Clone)] +pub struct ApiSecurityShield { + pub host: String, + pub key: String, +} + #[derive(Deserialize, Debug, Clone)] pub struct ApiSecurity { - pub authifier_shield_key: String, + pub shield: ApiSecurityShield, pub voso_legacy_token: String, pub captcha: ApiSecurityCaptcha, pub trust_cloudflare: bool, @@ -449,6 +468,7 @@ pub struct Settings { pub features: Features, pub sentry: Sentry, pub production: bool, + pub environment: String, pub disable_events_dont_use: bool, } @@ -475,8 +495,7 @@ pub async fn read() -> Config { CONFIG_BUILDER.read().await.clone() } -#[cached(time = 30)] -pub async fn config() -> Settings { +pub async fn config_no_cache() -> Settings { let mut config = read().await.try_deserialize::().unwrap(); // inject REDIS_URI for redis-kiss library @@ -494,6 +513,34 @@ pub async fn config() -> Settings { config } +#[cached(time = 30)] +pub async fn config() -> Settings { + #[cfg(feature = "test")] + if let Some(overwrites) = CONFIG_OVERWRITES.get() { + return overwrites.clone(); + } + + config_no_cache().await +} + +#[cfg(feature = "test")] +static CONFIG_OVERWRITES: OnceLock = OnceLock::new(); + +/// Modify the config values for a test, this can only be called once +/// +/// This will also fail if two or more tests are running in the same process and both try to modify the config, +/// This could happen if tests where run under `cargo test` instead of `nextest`. +#[cfg(feature = "test")] +pub async fn overwrite_config(f: impl FnOnce(&mut Settings)) { + let mut config = config_no_cache().await; + + f(&mut config); + + CONFIG_OVERWRITES.set(config).expect( + "Cannot overwrite config multiple times, make sure you are running tests through nextest.", + ); +} + /// Configure logging and common Rust variables #[cfg(feature = "sentry")] pub async fn setup_logging(release: &'static str, dsn: String) -> Option { diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index f820c899a..a8f8b18ab 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -11,19 +11,18 @@ repository = "https://github.com/stoatchat/stoatchat" [features] # Databases -mongodb = ["dep:mongodb", "bson", "authifier/database-mongodb"] +mongodb = ["dep:mongodb", "bson"] # ... Other tasks = ["isahc", "linkify", "url-escape"] -async-std-runtime = ["async-std", "authifier/async-std-runtime"] +async-std-runtime = ["async-std"] rocket-impl = [ "rocket", "schemars", "revolt_okapi", "revolt_rocket_okapi", - "authifier/rocket_impl", ] -axum-impl = ["axum", "revolt-result/axum"] +axum-impl = ["axum", "revolt-result/axum", "utoipa"] redis-is-patched = ["revolt-presence/redis-is-patched"] voice = ["livekit-api", "livekit-protocol", "livekit-runtime"] @@ -55,6 +54,8 @@ linkify = { workspace = true, optional = true } url-escape = { workspace = true, optional = true } validator = { workspace = true, features = ["derive"] } isahc = { workspace = true, features = ["json"], optional = true } +base32 = { workspace = true } +sha1 = { workspace = true } # Serialisation serde_json = { workspace = true } @@ -84,6 +85,7 @@ async-std = { workspace = true, features = ["attributes"], optional = true } # Axum Impl axum = { workspace = true, optional = true } +utoipa = { workspace = true, features = ["axum_extras"], optional = true } # Rocket Impl schemars = { workspace = true, optional = true } @@ -91,9 +93,6 @@ rocket = { workspace = true, features = ["json"], optional = true } revolt_okapi = { workspace = true, optional = true } revolt_rocket_okapi = { workspace = true, optional = true } -# Authifier -authifier = { workspace = true } - # RabbitMQ lapin = { workspace = true, features = ["tokio"] } @@ -101,3 +100,14 @@ lapin = { workspace = true, features = ["tokio"] } livekit-api = { workspace = true, features = ["rustls-tls-native-roots"], optional = true } livekit-protocol = { workspace = true, optional = true } livekit-runtime = { workspace = true, features = ["tokio"], optional = true } + +# Security +totp-lite = { workspace = true } +rust-argon2 = { workspace = true } + +# Email +lettre = { workspace = true } +handlebars = { workspace = true } + +# Web Requests +reqwest = { workspace = true, features = ["json", "form"] } diff --git a/crates/core/database/assets/pwned100k.txt b/crates/core/database/assets/pwned100k.txt new file mode 100644 index 000000000..a57738388 --- /dev/null +++ b/crates/core/database/assets/pwned100k.txt @@ -0,0 +1,100005 @@ +this file contains the top 100,000 passwords from the have i been pwned (https://haveibeenpwned.com) data set (by troy hunt). +source: https://www.ncsc.gov.uk/static-assets/documents/pwnedpasswordstop100k.txt +all entries are lowercase +-- + +123456 +123456789 +qwerty +password +111111 +12345678 +abc123 +1234567 +password1 +12345 +1234567890 +123123 +000000 +iloveyou +1234 +1q2w3e4r5t +qwertyuiop +123 +monkey +dragon +123456a +654321 +123321 +666666 +1qaz2wsx +myspace1 +121212 +homelesspa +123qwe +a123456 +123abc +1q2w3e4r +qwe123 +7777777 +qwerty123 +target123 +tinkle +987654321 +qwerty1 +222222 +zxcvbnm +1g2w3e4r +gwerty +zag12wsx +gwerty123 +555555 +fuckyou +112233 +asdfghjkl +1q2w3e +123123123 +qazwsx +computer +princess +12345a +ashley +159753 +michael +football +sunshine +1234qwer +iloveyou1 +aaaaaa +fuckyou1 +789456123 +daniel +777777 +princess1 +123654 +11111 +asdfgh +999999 +11111111 +passer2009 +888888 +love +abcd1234 +shadow +football1 +love123 +superman +jordan23 +jessica +monkey1 +12qwaszx +a12345 +baseball +123456789a +killer +asdf +samsung +master +azerty +charlie +asd123 +soccer +fqrg7cs493 +88888888 +jordan +michael1 +jesus1 +linkedin +babygirl1 +789456 +blink182 +thomas +qwer1234 +333333 +liverpool +michelle +nicole +qwert +j38ifubn +131313 +asdasd +0 +987654 +lovely +q1w2e3r4 +0123456789 +gfhjkm +andrew +hello1 +joshua +status +justin +anthony +angel1 +iloveyou2 +1111111 +zxcvbn +hello +1111 +jennifer +hunter +naruto +bitch1 +welcome +159357 +101010 +tigger +147258369 +babygirl +jessica1 +parola +5201314 +robert +fuckyou2 +696969 +102030 +0987654321 +loveme +123456q +apple +pokemon +mother +money1 +secret +anthony1 +purple +q1w2e3r4t5y6 +baseball1 +qazwsxedc +1111111111 +abc +buster +matthew +andrea +soccer1 +basketball +hannah +freedom +golfer +chelsea +passw0rd +george +trustno1 +friends +william +iloveu +amanda +number1 +chocolate +qwerty12 +summer +flower +charlie1 +maggie +pakistan +samantha +asdf1234 +letmein +asshole1 +superman1 +marina +147258 +batman +fuk19600 +butterfly +010203 +qweqwe +29rsavoy +forever +1 +mustang +sunshine1 +ashley1 +internet +london +666 +harley +alexander +xbox360 +00000000 +12341234 +q1w2e3 +pepper +family +loveyou +50cent +joseph +whatever +! +jasmine +orange +user +junior +cookie +martin +qweasdzxc +212121 +1qazxsw2 +password12 +google +password2 +111222 +lol123 +hello123 +jordan1 +shadow1 +patrick +3rjs1la7qe +ginger +nicole1 +mylove +arsenal +12344321 +abcdef +love12 +232323 +vqsablpzla +taylor +myspace +brandon +angel +12345q +brandon1 +chris1 +diamond +snoopy +asshole +qweasd +starwars +matrix +mickey +school +jonathan +melissa +eminem +1234561 +cjmasterinf +lovers +1234567891 +nikita +richard +1342 +yellow +12345qwert +oliver +q1w2e3r4t5 +cheese +a123456789 +christian +290966 +wall.e +12345678910 +12413 +sophie +tudelft +diosesfiel +dpbk1234 +pe#5gz29ptzmse +bailey +u38fa39 +mercedes +victoria +147852 +asdasd5 +matthew1 +abcdefg +peanut +456789 +red123 +happy1 +sandra +benjamin +dragon1 +444444 +123654789 +$hex +elizabeth +prince +amanda1 +angels +angela +qqqqqq +samuel +banana +barcelona +ghbdtn +computer1 +michelle1 +william1 +hockey +monster +carlos +justin1 +antonio +qwertyu +nathan +55555 +123789 +0000 +killer1 +11223344 +chicken +lucky1 +gabriel +welcome1 +zaq12wsx +jasmine1 +silver +hunter1 +bubbles +hottie1 +purple1 +andrew1 +daniel1 +liverpool1 +1qaz2wsx3edc +rainbow +morgan +natasha +fuckoff +jackson +austin +vanessa +mommy1 +madison +adidas +xxxxxx +252525 +america +james1 +metallica +slipknot +chicken1 +87654321 +jesus +null +0000000000 +alexis +!ab#cd$ +spiderman +steven +ferrari +lauren +456123 +robert1 +147852369 +qwaszx +buddy1 +butterfly1 +!~!1 +tinkerbell +bandit +danielle +0123456 +nicholas +hannah1 +qwerty12345 +1234554321 +asdfasdf +pokemon1 +nirvana +destiny +scooter +cookie1 +123qweasd +loveme1 +chelsea1 +chocolate1 +1234567a +juventus +rachel +111222tianya +qazxsw +zzzzzz +monica +stella +america1 +999999999 +jennifer1 +freedom1 +taylor1 +741852963 +yamaha +victor +00000 +qwertyui +a1b2c3 +ronaldo +1password +smokey +david1 +money +daddy1 +cocacola +a838hfid +1234abcd +joshua1 +123asd +buster1 +myspace123 +booboo +madison1 +samantha1 +heather +7654321 +elizabeth1 +poop +tigger1 +family1 +mustang1 +142536 +november +jasper +lovely1 +diamond1 +success +edward +music1 +valentina +harley1 +sweety +tennis +zxc123 +friend +qaz123 +whatever1 +thomas1 +nothing +n0=acc3ss +super123 +casper +password +chester +exigent +password123 +cheese1 +spongebob1 +mynoob +hahaha +hellokitty +098765 +alexandra +canada +david +1q2w3e4r5t6y +dennis +december +olivia +a1b2c3d4 +playboy +sabrina +patricia +summer1 +friends1 +mexico1 +dakota +barbie +loulou +johnny +music +123456m +password1 +lover1 +maggie1 +pretty +123hfjdk147 +nicolas +qwert1 +charles +phoenix +rebecca +thunder +sexy123 +iloveu2 +123456789q +batman1 +beautiful +carolina +4815162342 +vincent +jeremy +spider +master1 +heather1 +weed420 +sojdlg123aljg +pepper1 +sebastian +yankees +dallas +pussy1 +cameron +caroline +peanut1 +guitar +startfinding +midnight +i +iw14fi9j +yankees1 +elephant +124578 +scorpion +sexy +tweety +bubbles1 +fuckoff1 +cowboys1 +fuckme +fucker +louise +dolphin +852456 +patrick1 +loser1 +mother1 +lalala +naruto1 +veronica +melissa1 +sparky +newyork +adrian +123456s +september +heaven +alexander1 +jessie +crystal +tigers +k.: +p +iloveyou! +chris +gemini +raiders1 +135790 +zxcvbnm1 +peaches +merlin +12121212 +spongebob +scooby +stephanie +shannon +james +246810 +1a2b3c +555666 +sergey +lovelove +202020 +159951 +precious +123456j +lakers +manchester +ginger1 +134679 +cristina +apples +a1234567 +qqww1122 +pussy +daniela +jackson1 +123456b +jackie +rocky1 +asdfghjkl1 +sakura +qazwsx123 +yellow1 +flower1 +apple1 +010101 +newyork1 +sammy1 +alex +muffin +cherry +poohbear +richard1 +nigger1 +test123 +destiny1 +flowers +slipknot1 +cooper +753951 +monster1 +password +baby123 +mexico +blessed1 +toyota +spiderman1 +beauty +fuck +emmanuel +genius +winston +tiffany +charlotte +741852 +iloveu1 +diablo +onelove +tiger1 +badboy +maverick +joseph1 +winner +mickey1 +creative +beautiful1 +softball +hotmail +421uiopy258 +brittany +1314520 +aa123456 +asdf123 +lastfm +manuel +sayang +kristina +austin1 +stupid1 +hottie +booboo1 +murphy +stalker +carmen +doudou +qazqaz +scorpio +m123456 +pimpin1 +pass +badoo +garfield +0000000 +fuckme1 +scooter1 +151515 +aaaaa +brandy +kitty1 +myspace2 +steelers +compaq +claudia +123456d +rabbit +bailey1 +crazy1 +august +isabella +orange1 +october +q123456 +green1 +black1 +samson +aaaa +angelo +1a2b3c4d +9876543210 +boomer +junior1 +12345678a +shorty1 +tyler1 +456456 +kimberly +guitar1 +cowboys +shorty +passion +soleil +christ +1v7upjw3nt +111 +albert +andrey +ranger +dexter +lucky7 +popcorn +babyboy1 +bitch +alyssa +brittany1 +123456abc +forever1 +fucker1 +barney +1122334455 +blessed +metallica1 +1029384756 +karina +krishna +cameron1 +california +christian1 +melanie +j123456 +password! +happy +963852741 +woaini +danielle1 +samsung1 +gangsta1 +icecream +letmein1 +qwerty123456 +eagles +love13 +qwert123 +uqa9ebw445 +fucku2 +smokey1 +leonardo +asdfgh1 +police +christine +windows +bismillah +miguel +iloveyou12 +: +snickers +arsenal1 +7758521 +bubba1 +cowboy +denise +pretty1 +george1 +q12345 +winter +dancer +coffee +player1 +fernando +maxwell +swordfish +rangers +horses +francis +951753 +martina +fylhtq +chivas1 +secret1 +s123456 +marlboro +qwerty1234 +kitten +lauren1 +twilight +florida +141414 +pass123 +yagjecc826 +jason1 +54321 +nathan1 +sydney +pumpkin +molly1 +dolphin1 +vfhbyf +natalie +hiphop +skater1 +fishing +bond007 +kobe24 +barbara +loveyou1 +tiffany1 +john316 +cassie +iloveme +hardcore +stupid +fatima +alexis1 +rockstar +abc1234 +123456z +playboy1 +321321 +123123a +greenday +baby +maria +angelina +starwars1 +google1 +b123456 +school1 +bonnie +123qwe123 +sz9kqcctwy +lucky +father +courtney +sexy12 +007007 +crystal1 +abc123456 +fluffy +kissme +marseille +trinity +sweet1 +candy1 +qwerty7 +password3 +alejandro +a +pookie +roberto +sarah1 +player +justinbieb +turtle +poohbear1 +simone +corvette +jackass1 +lolita +jonathan1 +steven1 +alicia +lollipop +jackass +123456c +786786 +biteme +honey +motorola +nicholas1 +friendster +angel123 +portugal +iloveme1 +simple +012345 +vfrcbv +brooklyn +morgan1 +darkness +rainbow1 +shelby +slayer +natalia +snowball +chicago +454545 +aaaaaa1 +1234512345 +people +lovers1 +sharon +golden +snoopy1 +shannon1 +raiders +123qweasdzxc +sweetie +789789 +teresa +blue123 +242424 +awesome +boston +victoria1 +pamela +wilson +ssssss +mike +kevin +test +klaster +123456k +kenneth +bonjour +tucker +catherine +hockey1 +pa55word +9379992 +password. +eminem1 +love11 +mnbvcxz +logitech +redsox +remember +popcorn1 +kevin1 +isabelle +p3rat54797 +seven7 +steelers1 +qwe +marcus +bulldog +yfnfif +cricket +lakers24 +edward1 +tweety1 +qazwsx1 +123456t +single +lizottes +nastya +amber1 +sarah +blessing +marley +rockstar1 +fender +aaa111 +willow +camille +aaaaaaaa +florida1 +peaches1 +bella1 +carlos1 +connor +d123456 +love4ever +cutie1 +indian +goodluck +marie1 +loveme2 +marine +hammer +chance +stephen +121314 +123456l +z123456 +santiago +strawberry +abcdefg1 +bigdaddy +daisy1 +thunder1 +asdfghjk +marvin +mmmmmm +vanessa1 +happy123 +abcd123 +fuckyou! +iverson3 +hotdog +svetlana +arthur +1212 +never +tintin +234567 +iceman +orlando +satan666 +superstar +babygurl1 +090909 +johnson +fyfcnfcbz +freddy +rachel1 +magic +qwert12345 +chester1 +loverboy +miller +cookies +parker +azertyuiop +porsche +teacher +5555555555 +angelica +yourmom1 +bullshit +sunday +christopher +love1234 +travis +5555555 +evildick +666999 +monika +nissan +qwer +asdfg +midnight1 +williams +please +55555555 +spencer +aaaaa1 +gateway +tiger +dallas1 +111111a +charles1 +321654 +gracie +raymond +ladybug +sweetpea +rush2112 +greenday1 +sunflower +1123581321 +baby12 +jason +precious1 +lakers1 +brooklyn1 +stephanie1 +undertaker +m +12345t +sweetheart +ihateyou +zachary +emily1 +fktrcfylh +123698745 +tamara +asdfjkl +21212121 +456852 +lebron23 +andrei +paradise +doctor +kawasaki +polniypizdec0211 +a12345678 +money123 +171717 +sophia +winnie +bianca +bigboy +22222222 +qqq111 +jacob1 +andrea1 +john +julian +pantera +lucky13 +poopoo +lollol +3d8cubaj2e +lorenzo +sasuke +babyboy +nascar +hahaha1 +vladimir +abc12345 +sierra +shopping +career121 +12345qwerty +genesis +christina +bandit1 +mylove1 +cool +nelson +abcd +january +sweet +qq123456 +scarface +159159 +montana +ricardo +dolphins +giovanni +frankie +soccer12 +johnny1 +facebook +changeme +zxcvbnm123 +jerome +sassy1 +password11 +123454321 +qw123321 +dakota1 +australia +southside1 +soccer10 +zoosk +maryjane +пїѕпїѕпїѕпїѕпїѕпїѕ +brenda +rebecca1 +baller1 +honey1 +jeffrey +xavier +eagles1 +ryan +getmoney1 +brianna1 +realmadrid +8675309 +k. +scooby1 +westside +minnie +bobby1 +vampire +linkinpark +asdasdasd +francesco +inuyasha +1478963 +asdfg1 +falcon +123456r +green +laura +1q1q1q +aaa +rosebud +katie1 +alex123 +111222333 +asdfghj +ig4abox4 +sergio +nigger +sterling +sophie1 +claire +100200 +italia +ronaldo7 +timothy +jaguar +mariana +maksim +abigail +isabel +sairam +520520 +jackie1 +savannah +bigdaddy1 +courtney1 +disney +bigboy1 +nigga1 +blue +zaqwsx +love22 +c123456 +dancer1 +1qwerty +musica +single1 +123456aa +valentin +brooke +oliver1 +chicago1 +cherry1 +london1 +cjkysirj +alberto +jesus123 +565656 +blabla +maria1 +warcraft +patches +cat123 +mahalkita +banana1 +p +monkey123 +hollister1 +alyssa1 +lover +butter +walter +black +alessandro +778899 +w5txn36alfw +tigers1 +password7 +danny1 +awesome1 +bestfriend +dominic +gabriel1 +michele +gateway1 +oscar1 +sex +cancer +helpme +volleyball +yuantuo2012 +marie +123456g +princess12 +love69 +justine +chouchou +bitch123 +champion +france +kitty +element1 +963852 +jasmin +fishing1 +4444 +darling +united +manutd +teddybear +regina +natalie1 +passwort +francesca +181818 +abcdef1 +maximus +rafael +buddy +victory +qwerasdf +animal +student +hawaii +apple123 +spirit +jamaica +carter +kayla1 +gabriela +mariposa +abcdefgh +love23 +super +yahoo1 +rental +eddie1 +dreams +sexy69 +cheyenne +babygirl12 +poop123 +1234321 +england +eduardo +valeria +zachary1 +1986 +bob123 +antonio1 +sniper +napoli +panther +willie +redsox1 +hallo +zaq123 +calvin +veronika +111111111 +lol +nintendo +copper +millie +georgia +ybccfy +dog123 +brianna +123zxc +happiness +diesel +monkey12 +mohamed +123321a +camaro +bigdog +7895123 +100000 +engineer +bitches1 +estrella +grandma1 +princesa +oksana +gloria +penguin +virginia +skater +scarface1 +suzuki +martin1 +blue22 +donald +123456e +password +1234560 +newlife +chris123 +++++++ +123qaz +leslie +jimmy1 +sweet16 +anderson +abcdefg123 +77777777 +blahblah +wwwwww +aleksandr +shelby1 +adriana +kisses +giuseppe +softball1 +skyline +audrey +fucku1 +trouble +badboy1 +rey619 +tristan +celtic +vkontakte +love101 +pimpin +simpsons +liberty +7777 +jeremy1 +godisgood +angels1 +262626 +cupcake +twilight1 +skate1 +potter +bradley +warrior +qw123 +miranda +pumpkin1 +barbie1 +sexsex +100 +147896325 +smile +hesoyam +debbie +ruslan +online +maddie +jessie1 +pink123 +speedy +taurus +loveyou2 +olivia1 +ladybug1 +wizard +allison +pierre +domino +benjamin1 +apples1 +silvia +kingkong +bobby +monday +polina +fuckyou123 +honda1 +mercury +nokia +rascal +pepsi1 +6969 +silver1 +angela1 +florence +adgjmptw +cookies1 +margarita +hallo123 +monique +258456 +fuck123 +9111961 +love14 +pass1234 +children +zzzzzzzz +tyler +123451 +cristian +star +justice +password5 +booger +knight +mamapapa +dreamer +siemens +esther +soccer11 +hollywood +qawsed +password01 +monkey2 +cassie1 +anna +inuyasha1 +amoremio +sister +gregory +191919 +serenity +natali +sabrina1 +n8zgt5p0shw= +prince1 +rangers1 +camila +123456qwerty +ncc1701 +1bitch +nirvana1 +ronald +business +texas1 +element +avatar +panasonic +gangster +serega +brandy1 +asasas +25802580 +missy1 +colorado +jenny1 +microsoft +cowboy1 +909090 +1989 +sammy +jupiter +stanley +madonna +123456p +serena +valerie +superstar1 +legolas +groupd2013 +31415926 +dbrnjhbz +rocket +megan1 +airforce1 +apollo +3odi15ngxb +internet1 +westside1 +qwer123 +brooke1 +kelsey +pebbles +system +catdog +christina1 +flowers1 +passw0rd +sultan +icecream1 +bulldog1 +redneck1 +123457 +123987 +gizmo1 +johncena1 +danger +chichi +donkey +nfnmzyf +asdzxc +india +titanic +compaq1 +thebest +kirill +javier +hamster +myspace! +223344 +gangsta +packers +asdasd123 +pookie1 +hitman +kathleen +qwqwqw +cupcake1 +skittles +sports +coucou +frankie1 +p@ssw0rd +aaron1 +christmas +molly +casper1 +qti7zxh18u +blondie +football12 +smiley +snickers1 +lasvegas +sam123 +445566 +september1 +2222 +jayjay +basket +elena +ireland +110110 +123456789m +k123456 +tommy1 +jesus7 +madrid +marshall +vegeta +people1 +minecraft +terminator +security +drowssap +sparky1 +123456789z +19871987 +poiuytrewq +j12345 +pauline +jackson5 +jetaime +p@ssw0rd +ronnie +skippy +kimberly1 +rammstein +alexandre +scotland +nikki1 +rocky +asdfjkl: +motdepasse +stefan +celine +harrypotter +aaaaaaa +babydoll +manman +violet +dddddd +192837465 +pizza1 +legend +321654987 +iloveyou. +bella +truelove +harvey +tanner +runescape1 +fantasy +peter +casanova +friday +robbie +katrina +philips +spencer1 +francisco +cool123 +viktor +exigent +fluffy1 +qwertz +chocolat +christophe +phoenix1 +poiuyt +z +bambam +jesus777 +99999999 +1qaz1qaz +323232 +pussy69 +killer123 +rhbcnbyf +alejandra +muffin1 +kelly1 +stonecold +aurora +chivas +loser +gordon +love21 +gandalf +lalala1 +jasper1 +a1s2d3f4 +spanky +love10 +mitchell +g9l2d1fzpy +jack +babygirl2 +19851985 +welcome123 +franklin +russia +carpediem +aaaaaaaaaa +linked +zaq1xsw2 +megaparol12345 +travis1 +admin123 +daisy +lorena +froggy +smiles +douglas +handsome +shithead +1blood +tatiana +santos +little1 +anastasia +unicorn +5555 +12369874 +savannah1 +tinker1 +sweetie1 +jenny +diwtgm8492 +1234567q +super1 +margaret +viking +muhammad +maxwell1 +pppppp +sexyboy +phantom +fatboy +m12345 +tomtom +080808 +monica1 +ballin1 +eclipse +andres +elijah +maurice +piglet +baxter +123456654321 +pikachu +india123 +platinum +gangster1 +garcia +passport +jesuschrist +kelly +sandra1 +hotmail1 +mahalko +charmed +loving +272727 +corazon +katherine +michel +myspace12 +access +bunny1 +123321123 +wisdom +mozart +snowball1 +147147 +asdfghjkl: +patches1 +abcde +chloe1 +horses1 +d1lakiss +98765 +church +everton +12345m +nicola +peace1 +marcus1 +trouble1 +13579 +dylan1 +tinker +161616 +candy +69696969 +valentine +grace +sandy1 +hercules +123456f +beatrice +puppy1 +cooper1 +wolverine +12345s +mama +jamesbond +jamie1 +theman +anton +19841984 +toshiba +cthutq +maradona +emily +gibson +787878 +bingo1 +green123 +marcel +lolipop +maganda +penis1 +turtle1 +amsterdam +joanna +fashion +mercedes1 +yahoo.com +123000 +19861986 +britney +boston1 +goldfish +power +james123 +kitkat +network +lawrence +pass1 +112358 +beatles +winston1 +saibaba +princess2 +trevor +promise +norman +14789632 +hotdog1 +idontknow +hollywood1 +damian +star123 +123456y +diamonds +trinity1 +ihateyou1 +kkkkkk +cutiepie +soccer13 +bulldogs +felipe +yoyoyo +heaven1 +enigma +marion +angel12 +brian1 +jayden +germany +mario +onelove1 +369369 +soccer7 +casey1 +sasha +brother +matteo +max123 +melody +jimmy +success1 +simona +julien +hjvfirf +loveu2 +digital +english +reggie +shalom +power1 +einstein +forever21 +karate +135792468 +hello12 +bubble +nathalie +benfica +billy +spartak +hahahaha +harrison +timothy1 +mom123 +123456123 +danny +kingdom +poopoo1 +admin +gunner +ranger1 +1234asdf +anhyeuem +helena +sasha1 +buttercup +argentina +water1 +cocacola1 +polska +soccer123 +omsairam +saturn +hg0209 +manager +georgia1 +stephen1 +baller +282828 +forest +12345r +johncena +sweets +elaine +maryjane1 +dragonball +milano +stargate +colombia +brian +19891989 +captain +infinity +pandora +amelia +trfnthbyf +dianne +eagle1 +redskins +digital1 +sexybitch1 +general +pogiako +dinosaur +zidane +7894561230 +colt45 +spring +sureno13 +arnold +catdog1 +jesse1 +eugene +teddy1 +penelope +19921992 +runescape +paintball1 +little +blood1 +test1234 +summer08 +billy1 +nadine +myname +therock +rusty1 +fatboy1 +ciaociao +football2 +swimming +wesley +travel +telechargement +zxczxc +orlando1 +nonmember +grandma +password4 +654123 +tennis1 +shithead1 +denise1 +thuglife +bbbbbb +vrbgqns997 +nothing1 +nigga +asd +subaru +chacha +tequiero +moomoo +charly +penis +chopper +comeon11 +lacrosse +12345j +scoobydoo +butter1 +gracie1 +sadie1 +zxcv1234 +iverson +bowwow1 +123789456 +bullshit1 +020202 +faith1 +kitten1 +monique1 +pink +victor1 +wordpass +bullet +r123456 +duncan +a11111 +1qa2ws3ed +adrian1 +laura1 +thx1138 +russell +love15 +cutiepie1 +flatron +sebastian1 +gordon24 +sexygirl1 +123321q +ilovegod +asdf12 +pickle +mememe +mar +kristen +143143 +kittycat +420420 +bamboo +mylife +e123456 +walker +oscar +boobies +cleopatra +pascal +alaska +testing +dragons +?????? +19821982 +qwerty321 +pippo +porsche1 +perfect +password13 +hummer +justme +303030 +megaparol12345 +sammie +smile1 +19801980 +david123 +teddybear1 +baseball12 +blue12 +joker1 +dustin +katerina +cynthia +11112222 +mario1 +harry1 +qazwsx12 +fabian +samuel1 +fuckyou69 +cecilia +roland +2 +golfcourse +070707 +daddy +magic1 +313131 +alfred +martinez +elephant1 +2004 +fktrctq +katie +ass123 +yahoo +ilovejesus +l123456 +123456123456 +houston1 +allison1 +smoke420 +godzilla +bernard +ganesh +peterpan +mybaby +brutus +pitbull +buddy123 +iloveme2 +skittles1 +spurs1 +logan1 +x4ivyga51f +9-11-1961 +ciccio +pineapple +panthers +napoleon +chopper1 +honda +drummer1 +louise1 +holiday +11235813 +federico +music123 +houston +startrek +vincent1 +qazxswedc +alabama +mohammed +qwe12345 +cambiami +iloveyou3 +christine1 +gggggg +friendship +911911 +pa55w0rd +pokemon123 +mountain +boomer1 +steve +galina +12301230 +vfvjxrf +college +biteme1 +raymond1 +bitches +looking +bhf +bradley1 +packers1 +berlin +lindsay +linkin +isabella1 +hassan +hacker +booger1 +987456 +my3kids +scotty +storm1 +19831983 +martha +5211314 +123456789s +bigdog1 +catch22 +mariah +marco +catalina +wildcats +solomon +caramel +michigan +oicu812 +44444 +butthead +myspace. +13131313 +vampires +philip +amber +cheer1 +753159 +sunny1 +peewee +bob +charmed1 +change +hiphop1 +yourmom +mybaby1 +theman1 +strength +panther1 +tommy +badass1 +jjjjjj +cdtnkfyf +charlotte1 +barcelona1 +hardcore1 +bubba +1loveyou +pussycat +spitfire +myself +tnk0mk16vx +babygurl +qweasd123 +chanel +fender1 +howard +andreas +megan +bluebird +a123123 +123456987 +carolina1 +asdqwe123 +sexygirl +sandy +popeye +matt +ybrbnf +pickles +2012comeer +medicine +autumn +something +evelyn +misty1 +cutie +naruto123 +peter1 +soccer2 +maxime +miriam +10101010 +grace1 +fordf150 +asd123456 +ilovehim1 +moonlight +caprice +lonely +123098 +t123456 +skipper +damien +llllll +angel2 +10203040 +yfdbufnjh10305070 +spider1 +johnson1 +deejay +giulia +africa +joel +saints +bananas +bonita +password10 +tucker1 +rodrigo +runner +joanne +000 +567890 +archie +birthday +77777 +baseball2 +trixie +mark +789123 +dearbook +spike1 +19951995 +null +password0 +q1q1q1 +pimp123 +blackberry +lilwayne1 +king +maddog +sugar1 +linda +elvis1 +66666666 +the +ffffff +firebird +kermit +jake +phoebe +aaliyah +7758258 +123456n +alison +s12345 +22222 +s +123465 +salvador +barney1 +sexy101 +drpepper +melanie1 +miracle +aaa123 +c +mypassword +caitlin +wxcvbn +fred +harry +ironman +thebest1 +natasha1 +ferrari1 +fuku00198 +d +usa123 +lololo +102938 +pebbles1 +898989 +abigail1 +a111111 +thumper +familia +rfrfirf +spartan117 +chance1 +goober +2222222 +qwerty11 +brenda1 +monkeys +cassandra +aaron +2cute4u +darren +135246 +tiger123 +always +smokie +steve1 +freddie +nick +poopy1 +genesis1 +panget +guinness +chiara +athena +personal +alabama1 +jaimatadi +gators +israel +darkangel +ellie +evony192 +19881988 +smoke1 +knopka +hershey +budlight1 +peace +lovebug +alicia1 +pencil +mikey1 +a1a1a1 +predator +ka_djkhjsy6 +alejandro1 +torres +hayden +newport1 +montana1 +111111q +marcos +lvbnhbq +qwerty +bigdick +20102010 +chevy1 +fuckme69 +sporting +indonesia +fernanda +aezakmi +olivier +devil666 +147369 +pizza +aquarius +dragon123 +bonnie1 +kelsey1 +mexican1 +12qw23we +1234567890q +future +franco +vikings +rahasia +222333 +jayden1 +44444444 +diana +sunset +lovelife +love01 +theone +sample123 +b +penguin1 +lizzie +bearshare +denver +my3sons +remember1 +drummer +lorraine +12345d +aaliyah1 +lindsey +davide +scott +nemesis +blondie1 +mike123 +hector +holly1 +tarzan +jeremiah +brasil +badass +pimp +magnum +temp +boogie +death1 +connie +capricorn +12131415 +wrestling1 +private +potato +special +пїѕпїѕпїѕпїѕпїѕпїѕпїѕ +good +manuela +cherokee +florian +asdfasdf1 +kenneth1 +blablabla +sexy13 +lincoln +friend1 +sheila +christ1 +yvonne +minnie1 +turkey +dipset1 +yamaha1 +veronica1 +punk +summer09 +a1s2d3 +love09 +passer2011 +sex123 +kennedy +2hot4u +marine1 +maddie1 +cricket1 +nikki +selena +goldie +cooldude +giants +broncos +123qwerty +juliana +myspace3 +buddha +skateboard +sk84life +chloe +buttons +westlife +norte14 +lizard +kissme1 +111qqq +defender +dumbass1 +favour +shaggy +vampire1 +456654 +darkness1 +tequila +daniel123 +azerty123 +1984 +bball1 +assassin +testtest +youbye123 +samurai +dragons1 +sk8ter +505050 +hello2 +14531453 +penny1 +11111a +federica +marian +killa1 +dance1 +explorer +simple1 +ibrahim +death +matilda +dickhead +qwer12 +pioneer +ducati +babylove +formula1 +crazy +angel13 +janice +789654 +micheal +password9 +jayjay1 +hailey +wangyut2 +363636 +1987 +l +dfvgbh +marissa +gilbert +cheyenne1 +canada1 +f +faith +12345z +monkeys1 +dominique +tokiohotel +xxx +j +delete +miller1 +deedee +alexandra1 +cantik +1985 +kenny1 +12345k +mama123 +connor1 +antoine +papillon +111555 +123455 +dolphins1 +haha123 +123456h +babyblue +pitbull1 +emerald +1313 +love16 +miranda1 +343434 +beauty1 +fondoom +sebastien +hhhhhh +simon +teacher1 +monalisa +ekaterina +19941994 +larisa +hearts +jeffrey1 +sapphire +disney1 +england1 +alex12 +wolves +jamie +warren +surfer +subzero +gustavo +arizona +bear +puppies +freeman +19931993 +april +julia +1234567899 +vision +k +telefon +1myspace +jacob +pink12 +sydney1 +dragon12 +killer12 +theresa +agent007 +123456789j +getmoney +33333333 +picasso +idontknow1 +linda1 +morris +spooky +julius +336699 +design +camilla +wrestling +jamaica1 +racing +lucky123 +9999 +salvatore +loverboy1 +shanna +19901990 +fuck69 +pinky1 +panthers1 +snowman +brownie +lollipop1 +murphy1 +kkkkkkkk +random +hughes +1princess +death666 +shirley +321456 +cjkywt +roberta +digger +miguel1 +stefano +zoey101 +19811981 +dude +benson +money2 +sierra1 +jayson +sputnik +9999999999 +watermelon +iloveyou7 +654321a +alpha1 +special1 +valera +bambam1 +8888 +bluefish +525252 +american +voodoo +malibu +123456w +rabbit1 +dodgers1 +slayer1 +amore +carmen1 +april1 +money12 +frank +blahblah1 +poopie1 +123123q +050505 +dustin1 +elijah1 +cuddles +fucking +winter1 +ily123 +liliana +fuckit +scott1 +frank1 +abcde1 +karolina +shelly +bonbon +90210 +6666 +tigger2 +justice1 +1234566 +adidas1 +shadow12 +harmony +fuckit1 +deborah +qazwsxedcrfv +1lover +babydoll1 +sam +king123 +paloma +golden1 +bethany +pimp12 +julie +celeste +sachin +906090 +123456qwe +marines +bulldogs1 +hotrod +forget +369258147 +bollocks +daniele +gerald +dalejr88 +abcde12345 +132435 +mustafa +password00 +6hbf28w791 +kisses1 +broncos1 +sweetpea1 +ficken +kitty123 +buttercup1 +987456321 +alessia +dominik +zk.: +lilmama1 +kissmyass +mommy +stellina +123456asd +d12345 +dragonfly +karen +bitch12 +matrix1 +980099 +loser123 +dominic1 +password8 +lindsey1 +stinky +sublime +ronaldinho +volcom1 +asdasd1 +shit +summer07 +jacobs +garrett +hotstuff +smiley1 +qweqweqwe +gundam +24680 +19911991 +beckham +maison +blood5 +candy123 +0.00000000 +thegame +nightmare +water +235689 +best +bunny +ghjcnj +doggy1 +password69 +thailand +password22 +simpson +sexymama1 +raven1 +february +lala123 +stella1 +lovebug1 +viktoria +oooooo +newlife1 +josh +doggie +soccer3 +201301 +redwings +aspirine +tobias +pirate +badger +energy +charlene +adam +emilie +5678 +пїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕ +dickhead1 +letter +123456789k +master123 +dennis1 +n +geronimo +gregor +redneck +riley1 +beaver +atlanta +atlanta1 +dadada +mariam +funny1 +garden +545454 +country +mommy123 +james23 +mookie +electra +buffalo +curtis +xavier1 +scorpio1 +yousuck1 +god +barbara1 +justdoit +massimo +marley1 +pakistan1 +olga +122333 +ytrewq +19781978 +tatyana +josephine +1980 +qawsedrf +ladygaga +f123456 +singer +carrie +soccer9 +lover123 +yankees2 +popopo +godislove +cuteako +valencia +insanity +sk8ordie +molly123 +twins2 +creative1 +fountain +harold +driver +redskins1 +suckit +rose +3333 +mollie +poop12 +queen1 +kristen1 +dexter1 +bella123 +bitch2 ++++++++ +liberty1 +rolltide +madmax +german +dylan +jazzy1 +valentino +christmas1 +vanilla +connect +clowns +burrito +october1 +sunny +schalke04 +preston +prettygirl +tornado +panda1 +stacey +cloud9 +willie1 +sammy123 +pavilion +vacation +love08 +tottenham +5hsu75kpot +callie +broken +love143 +hey123 +coffee1 +2222222222 +fish +hihihi +usdopaa +fireball +yankee +privet +bobbob +shakira +soccer14 +noway +akopa123 +illinois +pantera1 +rockon +newcastle +samsam +daniels +kkkkkkk +shadow123 +drpepper1 +sexy11 +scarlett +season +gabby1 +cedric +teddy +melvin +avalon +a1b2c3d4e5 +321123 +usdopaa +lucas +12345679 +ashton +froggy1 +shamrock +tomcat +shawn1 +marius +simba1 +mariah1 +frances +eternity +12345b +vagina +volcom +wallace +goodboy +rosemary +marlon +lollypop +paris1 +bubble1 +rooster +topgun +sasasa +g123456 +psycho +patricia1 +332211 +warcraft1 +123456789d +gerard +qwerqwer +donkey1 +dick +young1 +dodgers +milena +canyon +magnet +kristin +blackie +sanane +1jesus +989898 +1945 +manuel1 +redrose +bacchus +linkedin +19791979 +zombie +01020304 +flores +poopie +phillip +area51 +taco +fatass1 +12 +gabrielle +holland +magnolia +784512 +naruto12 +314159 +666777 +budlight +1951 +fresh1 +tanner1 +chandler +1982 +hello! +11111q +maxmax +jellybean +soccer5 +paramore +romeo1 +stratfor +istanbul +john123 +4200 +ragnarok +goddess +sunflower1 +andromeda +dollar +redbull +sweety1 +cinderella +michael2 +mamama +mason1 +bigred +laguna +9999999 +warrior1 +november1 +rocker +dinamo +258258 +passion1 +lala +delfin +1022 +sasuke1 +blacky +marines1 +030303 +1234567890a +sanchez +annie1 +fuckme2 +tattoo +cool12 +hamilton +batista +2000 +galaxy +000111 +dillon +police1 +education +whitney +rosario +henry1 +porsche911 +bogdan +antonella +gregory1 +michigan1 +alessandra +cookie123 +cxfcnmt +99999 +yoyoyo1 +sunrise +copper1 +casablanca +vikings1 +20092009 +wilson1 +1988 +starcraft +vivian +enterprise +famous1 +ocpoook325 +lionking +marissa1 +samira +temppass +100100 +19751975 +lucifer +my2girls +a1a2a3 +rooney +patriots +zxasqw12 +qazwsxedc1 +ghbdtnbr +123456789l +sabina +fuckyou12 +isaiah +judith +respect +cme2012 +yahoo123 +reddog +chargers1 +yasmin +sparkle +passat +wayne1 +iluvu2 +aaron431 +brother1 +stanley1 +samara +simon1 +country1 +bettyboop +blazer +swordfish1 +1010 +nigeria +3333333 +info +theone1 +marketing +december1 +newport +dog +dorothy +karen1 +p123456 +amores +boobies1 +alice +hola +chris12 +leonard +spam +catherine1 +98765432 +sobaka +julian1 +kent +ricky1 +kittycat1 +patriots1 +manson +hershey1 +outlaw +sidney +1qa2ws +dance +johanna +monkey7 +family5 +998877 +holly +stratus +moomoo1 +sara +holden +monkey11 +anything +bluesky +blueeyes +kurt +samson1 +perfect1 +carter1 +1979 +willow1 +andreea +000001 +twinkle +123456789p +carlitos +coconut +haha +scoobydoo1 +lester +skyline1 +roxanne +madeline +rosie1 +fucky0u +south13 +douglas1 +butterfly2 +pisces +bentley +blackjack +122001 +mamamia +newton +bigdick1 +19961996 +redhead +hotties +mahal +boubou +corona +baby13 +peewee1 +micheal1 +baseball7 +desiree +wow12345 +gogogo +caroline1 +dupont +shane1 +hongkong +b12345 +pickles1 +ticket +marilyn +space1 +bobmarley +classic +wonderful +qwe123qwe +ethan1 +1q2w3e4 +widget +zvezda +laptop +kevin123 +thuglife1 +youngmoney +underground +indiana +w123456 +acmilan +hailey1 +smile123 +224466 +1983 +7777777777 +4321 +tripper +yomama1 +red +fireman +renata +billabong +777888 +annette +bernie +++++++++ +blossom +chase1 +williams1 +football10 +lakshmi +joe123 +makaveli +456321 +almond +ninja1 +sugar +panda +sigma +love24 +burton +google123 +clifford +pepito +daddysgirl +morena +stormy +1357924680 +cartman +kristine +nikola +washington +freckles +bishop +trigger +1q2w3e4r5 +hendrix +password23 +tristan1 +cracker +detroit +beatriz +lilwayne +oblivion +giovanna +spike +gizmo +germany1 +fortuna +paul +kayla +callum +maverick1 +parker1 +soccer4 +bscirc +alfredo +lisa +bettyboop1 +divine +sister1 +coupons +megaman +353535 +poison +broken1 +myspace.co +juggalo1 +star12 +blah +blue13 +blowme +060606 +markus +jeter2 +coming +starfish +welcome1 +toronto +sandrine +amigos +ronnie1 +telephone +jordan12 +thankyou +renee1 +stardust +chubby +billybob +258369 +armando +skywalker +rebel1 +freddy1 +snowman1 +babies +lindsay1 +montreal +herman +jesse +777 +hotboy1 +jester +ncc1701d +football7 +alladin79 +mierda +k12345 +heyhey1 +random1 +1977 +peugeot +monkey3 +333666 +cassidy +mandy1 +therock1 +myspace7 +albert1 +arianna +casey +max +savage +just4fun +mate1 +20082008 +hernandez +spiderman3 +horse1 +marianne +apollo13 +paintball +katherine1 +789987 +azerty1 +fucklove1 +godbless +mobile +baseball3 +robinson +munchkin +hayley +000000a +eeyore +1asshole +ronaldo9 +punkrock +icehouse +skeeter +sharp +serenity1 +brownie1 +everton1 +chemistry +joejoe +292929 +gothic +paris +warcraft3 +ireland1 +sergei +missy +bubblegum1 +hotstuff1 +mykids +claudia1 +gators1 +1981 +hookem +jrcfyf +12345qwe +griffin +kaktus +dietcoke +asdfg123 +bitch69 +cashmoney +cashmoney1 +steaua +brazil +1236987 +jack123 +ilove1 +snuggles +snowflake +martini +entropy +bubblegum +1q2w3e4r5t6y7u8i9o0p +piazza +deftones +longhorns1 +123456789o +aobo2010 +redrum +kaylee +nicole12 +damilola +christy +aol123 +marlboro1 +loveme123 +callofduty +michaela +pegasus +bluemoon +tony +flipper +sheena +omg123 +spanky1 +marshall1 +michael +eric +192837 +catfish +bruno +superman12 +please1 +jerry1 +juliette +521521 +garfield1 +iloveyou +artist +something1 +birdie +mouse1 +carson +blueberry +warriors +tyson1 +1122 +polniypizdec110211 +12345abc +september2 +millie1 +speedy1 +cheater1 +sexxxy +wicked +claudio +cracker1 +mackenzie +19761976 +unknown +sanjay +michal +trevor1 +janine +lancer +great1 +brandi +5xfgs3ii9d +stefania +sommer +arizona1 +paddle +love18 +superman2 +1978 +y6p67ftrqj +timmy1 +hanuman +universal +monkey13 +hammer1 +jojo +lighthouse +password6 +rock +coco +marcelo +656565 +pop123 +rosebud1 +angelito +dalton +testpass +rocky123 +winner1 +kingston +bozo +esperanza +roscoe +cat +andre +singapore +scrappy1 +skyhawk +rjntyjr +rayray1 +doodle +rocknroll +magdalena +jordan123 +boxcar +rajesh +cougar +thumper1 +slayer666 +braves +yolanda +1234qwe +fake123 +enrique +n123456 +service +rrrrrr +cubs +allah1 +helpme1 +love07 +black123 +flamingo +tester1 +pinky +linkedin1 +rastaman +extreme +dkflbvbh +blizzard +baseball11 +1qwert +antonia +soulmate +112211 +sharon1 +qwertyqwerty +skate4life +1babygirl +incubus +office +point +marisa +gjkbyf +ramona +***** +alexia +butthead1 +kolobok +fellow +bastard +raquel +buffy1 +derrick +jeanne +nuttertools +blackcat +cynthia1 +iforgot +369258 +19731973 +momdad +yomama +mememe1 +my2kids +godfather +zxzxzx +elvis +mamita +1990 +sexy14 +banane +maximus1 +123456789123 +ironmaiden +1991 +geheim +lkjhgfdsa +mister +fatcat +semperfi +qwerty2 +coolio +mommy2 +angel7 +sassy +elodie +richie +mendoza +3 +pastor +tasha1 +lane +revolution +fisher +santana +whitney1 +as123456 +indigo +purple12 +ilovehim +account +angie1 +rascal1 +leslie1 +225588 +colombia1 +poppy1 +soccer15 +raptor +maria123 +wicked1 +jay123 +cccccc +hilary +fiesta +baseball10 +maxine +t +1a2s3d4f +felicia +toyota1 +ilove +111aaa +amour +motherlode +12qwas +1monkey +clover +debbie1 +shopping1 +nks230kjs82 +galatasaray +123456as +milan +just4me +dreamer1 +sexybitch +golf +kaitlyn +camero1 +priyanka +tyler123 +fashion1 +tootsie +powers +rfnthbyf +praise +target +ricardo1 +rayray +c12345 +babygirl13 +112233445566 +ashley12 +biscuit +princess10 +evolution +pwd1234 +romain +trooper +webhompass +blonde +23232323 +preston1 +lightning +bianca1 +rbhbkk +felix +skiffy +alejandra1 +ivanov +westham +sports1 +wildcats1 +princesse +lollol1 +olamide +585858 +alexandru +tttttt +champion1 +yugioh +research +12345c +88888 +cutie123 +pokemon12 +number2 +nichole1 +lilly1 +animal1 +ashley123 +animals +johnjohn +labrador +g-unit +nathaniel +paulina +dingdong +12345g +smallville +lavender +annie +boricua1 +jakarta +12345l +imissyou +19771977 +hitler +sonic1 +vagina1 +love12345 +susana +gladiator +january1 +rodney +russell1 +qqqqqqqq +sweetness +moose1 +handball +quentin +scruffy +jojo123 +1976 +playstation +mauricio +gemini1 +marijuana +justinbieber +lovelove1 +twister +anamaria +daniel12 +moloko +19971997 +zk. +classof09 +ibanez +techno +my2boys +redred +simpsons1 +ariana +chipper +sammie1 +ingrid +azsxdc +eastside1 +family4 +monkey22 +sherry +12345678q +windows1 +suckit1 +alessio +hobbit +bananas1 +dave +papamama +suzanne +987654321a +danilo +aragorn +warhammer +casino +hottie101 +kaitlyn1 +naughty +nick123 +derrick1 +trinidad +123love +joker +25252525 +baseball5 +daddy123 +unreal +henry +xxxxxx1 +oceane +laurent +carebear +anthony2 +dusty1 +12345671 +pinkfloyd +raphael +nicole123 +jason123 +reggie1 +pizza123 +zxcasdqwe +bigred1 +esmeralda +street +stewart +1975 +monday1 +pickle1 +immortal +000000000 +iceman1 +andy +truelove1 +allen1 +panzer +gabriella +hehehe +atlantis +beatles1 +gibson1 +larry1 +spartan +katana +123456v +shane +girls +power123 +zeppelin +vincenzo +julia1 +vaffanculo +metal666 +surfing +happy2 +369852 +mission +qwe123456 +hornet +jerry +football11 +darwin +virgin +asddsa +cadillac +corvette1 +mary +diana1 +garrett1 +123456789987654321 +loveless +scrappy +applepie +aurelie +radiohead +heyhey +zxcvbn1 +snowboard +123456qw +counter +brown1 +frederic +private1 +babycakes1 +insane +rodriguez +stinky1 +believe +19741974 +larissa +1234abc +godisgreat +inlove +youtube +1fr2rfq7xl +julie1 +puppies1 +sexy01 +hayden1 +diablo2 +111213 +scarlet +logan +aaaa1111 +soccer22 +6666666 +maprchem56458 +baller23 +424242 +wedding +cheryl +kittykat +michael123 +sophia1 +randy1 +teresa1 +nintendo1 +valerie1 +wonder +sublime1 +arturo +coolman +weed +bowling +gabriele +eleven11 +harris +monitor +watson +asshole2 +esteban +qqqqqq1 +robbie1 +lolo +logitech1 +flying +hallo1 +pepsi +sherlock +iloveyou13 +pineapple1 +1992 +fuck12 +skate +iloveyou22 +smith +roman +qweasdzxc123 +vfhecz +clement +pamela1 +marianna +fireman1 +autumn1 +jajaja +baby11 +money6 +man +hannah123 +caitlin1 +granny +zxcvbnm,./ +kenshin +qwertyuio +cindy +rough +w1985a +peter123 +australia1 +gorgeous +what +pasaway +dthjybrf +clayton +angelica1 +mathew +justin123 +fuckyou3 +787898 +nascar1 +pancho +anderson1 +denis +r +sandman +888999 +unknown +sampson +emma +poopy +blake1 +chrissy +verbatim +phantom1 +wildcat +tdutybq +nugget +w1980a +trisha +jakjak +breanna1 +myspace11 +frosty +asterix +2468 +cindy1 +alibaba +monkey5 +skorpion +maureen +motherfucker +jumpman23 +apache +chico1 +kickass +graham +wwe123 +vfrcbvrf +sprite +babyko +riccardo +asdf3423 +123456789123456789 +paige1 +homer1 +andre1 +gagged +rockon1 +drowssap1 +coyote +ernesto +colleen +jose123 +sunshine2 +808080 +pornstar +qwerty6 +purple123 +lasvegas1 +habibi +nana +fuckyou. +brendan +empire +marlene +enter +5532361cnjqrf +123456789b +fernando1 +sarah123 +w1979a +sooners1 +love17 +rusty +voyager +madman +iloveyou14 +258963 +romance +heart +smudge +college1 +cotton +1974 +password21 +horse +wolfgang +armani +detroit1 +irish1 +nevermind +secret666 +football9 +23456789 +collins +a801016 +miamor +ghetto1 +angelina1 +vfksirf +dixie1 +inferno +juliet +highheel +chrisbrown +z1x2c3 +w1990a +123567 +theking +bethany1 +a23456 +kelvin +bowwow +fire +abhishek +1a1a1a +norton +ultimate +jersey +retard1 +bryan1 +tester +fighter +backspace +osiris +987987 +zaqxsw +disturbed1 +francis1 +kaiser +f00tball +control +1a2b3c4d5e +carebear1 +gbpltw +spiderman2 +free +robin +mitchell1 +polaris +katrina1 +iloveyou4 +ericsson +gonzalez +bigman +134679852 +sexyboy1 +airforce +awful +campbell +chevrolet +babyface +jojojo +aleksandra +haley1 +1598753 +w1989a +jungle +cookie12 +soccer17 +car +deepak +hawaii50 +xyz123 +romashka +jillian +mermaid +cassidy1 +qwertyuiop[] +ninja +donald1 +whore1 +irina +jellybean1 +ghost1 +boobs +carole +24682468 +devils +200000 +francois +football3 +hakr +123456ab +halloween +axio +morrison +blaze1 +cactus +global +motocross +111000 +abraham +chevelle +sarita +fucklove +h123456 +skolko +iloveyou11 +princess13 +1020304050 +unicorn1 +vladik +hunting1 +kenny +blue1234 +buttons1 +lucas1 +415263 +162534 +princess11 +soccer8 +pyon +soldier +sandiego +halo123 +southpark +sentnece +1973 +erika +america10 +schatz +london12 +anjali +aditya +emilia +laurence +daisy123 +1million +moreno +ash123 +kissmyass1 +phone +austin316 +prayer +elvira +q123456789 +nature +bryan +universe +aztnm +hola123 +1969 +master12 +diego +doggie1 +h +pk3x7w9w +romeo +starlight +toulouse +richmond +86 +desire +cinnamon +holiday1 +allstar +mexico13 +punkin +puppy +hunting +isaiah1 +airborne +w1982a +charlie2 +w1984a +viper1 +steph1 +raven +patience +university +147741 +nokia1 +1993 +keyboard +mastermind +jonas1 +kucing +kramer +delpiero +lestat +unique +farmer +phillip1 +action +adriana1 +qwe321 +noodles +britney1 +abcdefghij +carina +xxxxx +crazy123 +boogie1 +window +2cool4u +renault +hawaii1 +passwort1 +hamster1 +rocker1 +merlin1 +jesusislord +33333 +sayangku +castle +football5 +d71lwz9zjs +virginia1 +rocket1 +ganteng +emanuel +thegame1 +flower123 +angel01 +lennon +house1 +purple2 +baxter1 +timber +cuddles1 +xxxxxxxx +letmein2 +ktyjxrf +yankee1 +joey +25251325 +w1986a +justin12 +14344 +sabine +my +jesus12 +cheese123 +whynot +1angel +jefferson +nnnnnn +iloveyou5 +meghan +aliali +stars +sexylady +12345678900 +eleonora +iloveyou123 +fucku +jeremiah1 +nichole +r2d2c3po +qazwsxedc123 +mamamama +malcolm +kiki +franklin1 +w1988a +xxxx +raider +sucker +kathryn +malina +backend +lover12 +angel11 +sexy15 +bobcat +uvgx8f8232 +1994 +a1a2a3a4 +emilio +7 +iamthebest +jessica123 +1314521 +makayla1 +slimshady +ghetto +nellie +reaper +stephane +tomato +bruno1 +faggot1 +794613 +amorcito +aspire +cheche +treasure +family6 +cannabis +house +babygirl10 +calvin1 +sirius +wordpass1 +titans +я +rockyou +assass +sandeep +maestro +metal1 +salman +walter1 +123ewq +vodafone +pirates +alisha +mushroom +love33 +jesucristo +rebelde + +stuart +deedee1 +w1983a +пїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕ +deniska +babyblue1 +mouse +taekwondo +amelie +kotenok +cheval +messi10 +naughty1 +billabong1 +peanuts +9 +hottie12 +kennedy1 +webster +lonely1 +giants1 +hannah12 +philippe +345678 +malika +goldfish1 +chantal +natalya +president +firefly +baseball13 +charity +1000000 +amazing +168168 +netlog +w1975a +southside +james007 +a123456 +scruffy1 +deathnote +skate123 +princess3 +catcat +maurice1 +chrissy1 +nokia6300 +princess7 +lucy +hottie123 +faithful +556677 +kingkong1 +theking1 +suckme +nicolas1 +helene +lawyer +agnieszka +history +12345678901 +lillian +w1987a +qqqqq1 +mississippi +1995 +love123456 +united1 +vietnam +marvin1 +dudley +kristin1 +opensesame +mexican +1andonly +rebelde1 +jake123 +19721972 +guadalupe +blackie1 +captain1 +1230 +rambler +father1 +pearljam +soledad +angel3 +mimi +newcastle1 +hermione +qweewq +babyboo1 +rochelle +hudson +simba +melinda +national +falcons1 +franky +spunky +summer06 +dating +pimp101 +taytay1 +landon +sailor +kamikaze +543210 +pingpong +corey1 +chevy +dracula +pussy123 +hunter12 +indiana1 +soccer21 +calimero +myspace13 +granny1 +brittney +saints1 +southpark1 +boomboom +rfhbyf +jessica2 +nelson1 +seattle +gandako +misty +oxford +adriano +1a2s3d +1234568 +dan +games +viewsonic +mike12 +download +marcela +big +abc123 +skippy1 +w1981a +angeles +qqq123 +yamahar1 +herbert +colorado1 +w1978a +diablo1 +forgot +jocelyn +1234569 +diesel1 +121212a +jackass2 +fenerbahce +pentium +svetik +castillo +1qaz +sylvia +159632 +littleman1 +renato +g +renegade +noodle +whiskey +international +juggalo +ironman1 +felix1 +amadeus +american1 +freaky1 +microlab +sally1 +676767 +bonjovi +erica1 +ivan +trumpet1 +dumbass +devin1 +teamo1 +victory1 +3rjs1la2qe +redman +sexy23 +mnbvcxz1 +shadow2 +daniela1 +summer12 +killbill +annabelle +penny +palermo +charlie123 +ihateyou2 +beverly +megane +hellfire +nursing +claude +yousuck +eclipse1 +ryan123 +hearts1 +jordan2 +friday13 +shelly1 +sharks +information +lover2 +12345678s +skipper1 +ashleigh +8 +love4u +teamo +horny +vfvekz +interests +qwertyu1 +justme1 +6543210 +betty1 +cosmos +bridget +beyonce +gunner1 +home +luckydog +man123 +freaky +w1976a +rosita +marie123 +ab123456 +tyrone +mohammad +onepiece +r12345 +friends2 +billie +bronco +princess01 +password1234 +789654123 +1972 +kasper +153624 +panama +manolo +natalia1 +moose +romania +foster +123456789c +babylon5 +kyle +sexylady1 +redhead1 +2323 +guest +caesar +wombat +d9zufqd92n +nicole2 +alpha +dallas214 +ilovemymom +jobsearch +discovery +abdullah +route66 +blowjob +nissan1 +jenna1 +darius +myspace5 +savage1 +chiquita +bitch! +135791 +qweqwe123 +blue11 +qwertyuio1 +qwert12 +ali123 +chipie +666888 +vitalik +batista1 +15426378 +kiss +vanille +wesley1 +tarheels +wolfpack +andrew12 +shadow13 +dolores +19981998 +dirtbike1 +august1 +goodman +felicidade +rhfcjnrf +classof08 +123456789r +football21 +anita +123456789t +t12345 +deadman +asdqwe +1zn6fpn01x +3girls +123456qq +arschloch +guillaume +leticia +hobbes +2005 +elisabeth +woody1 +belinda +payton +seven +golfer1 +shiloh +w1977a +jeff +doraemon +aleksey +western +squirrel +blood +sparta +mirage +werewolf +lampard +skeeter1 +madonna1 +mittens +soccer23 +momdad1 +lucas123 +123mudar +ricky +inside +dude123 +mikey +sampson1 +devil +lincoln1 +pass1word +dominique1 +emo123 +white1 +1family +sadie +eddie +junjun +terry1 +killer2 +thanks +batman123 +lacoste +pimp69 +babygirl3 +asd456 +pompier +memory +rommel +nascar24 +alenka +allstar1 +hot123 +alex1234 +andrew123 +cassandra1 +honeybee +lilman1 +inlove1 +enter1 +murray +darkside +winnie1 +kittens +ciao +million +trucker1 +texas +rooster1 +akax89wn +qwert6 +kinder +kaylee1 +oscar123 +gerrard8 +ashton1 +brandi1 +hotgirl1 +javier1 +luciano +2121 +karina1 +marathon +hello1234 +matias +hottie2 +libertad +shutup +louloute +zxcvbnm: +asdfgh123 +freak1 +password123 +3rjs5la8qe +g13916055158 +sweetness1 +manutd1 +zxcvb +vladislav +bleach +strong +cellphone1 +ssyu1314 +lovehurts1 +hi +blue42 +science +miami305 +coco123 +lovingyou +babycakes +princess! +rachael +lilian +etoile +leanne +dfkthbz +3children +monkey69 +soccer16 +audia4 +damian1 +karachi +elliott +memphis +120120 +football22 +falcon1 +v123456 +sherman +swimming1 +again1 +123qwe123 +alberto1 +krystal +chicken2 +258852 +eunice +chandra +chichi1 +mathilde +heart1 +sandro +jacqueline +tonton +vfvfgfgf +nutella +jehovah +2girls +josh123 +james12 +violeta +a000000 +fallen +goober1 +q1q2q3 +domenico +leelee +azsxdcfv +ji394su3 +kristina1 +fernandez +p4ssw0rd +michael12 +jobs +farfalla +odessa +chris2 +kamila +soccer6 +chocolate2 +132456 +michele1 +alfonso +maxima +manman1 +gloria1 +island +johndeere +my3girls +fussball +qarglr123 +963258 +4 +joyjoy +money5 +12qw34er +ronaldo1 +gerrard +green12 +boo123 +scotland1 +001122 +angie +loveme12 +newjob +sexy21 +lacrosse1 +turkey1 +peace123 +bigfoot +sunshine12 +catfish1 +foxpass +пїѕпїѕпїѕпїѕпїѕ +1230123 +5 +iloveu123 +474747 +jean +roberto1 +123qwer +6v21wbgad +2sexy4u +layouts1 +fuckyou7 +airplane +volume +thompson +verizon1 +nightmare1 +dalejr8 +pothead1 +attila +china1 +robin1 +danny123 +temppassword +sasha123 +cute +krystal1 +corona1 +porkchop +change1 +king12 +timmy +eileen +ganda +sayang1 +mathieu +angel5 +misiek +kokoko +melina +nopassword +regina1 +mama12 +milton +dawson +qwertyuiop1 +dancing +shooter +singer1 +qwerty +badgirl +mymother +designer +macmac +camaro1 +anubis +000007 +nikolas +nancy +papa +alexandr +cheater +elizabeth2 +hamlet +janjan +12345abcde +toshiba1 +potter1 +hooters +maiden +drjynfrnt +alex13 +adgjmp +motorola1 +peyton +01234567 +jonjon +monkey! +makayla +tacobell1 +ilovemyself +patata +marjorie +amandine +bullet1 +fktrcfylhf +harvey1 +elliot +sk8board +carlos123 +fallen1 +ashlee +behappy +emily123 +bobby123 +newpass +hunter123 +desiree1 +malaysia +tigger12 +erica +omni +ass +12345e +fuckthis1 +nancy1 +flames +goodgirl ++++++++++ +manunited +qqqq +123450 +eduardo1 +salome +12345p +chosen1 +1234567890- +112112 +kakashi +blonde1 +curtis1 +waheguru +q +123456x +xiang123456 +myspace01 +theresa1 +platinum1 +eagle +priscilla +poppop +pedro +kendall +love45 +chargers +babylove1 +loving1 +baby01 +rolltide1 +polniypizdec1102 +attitude +newman +flamengo +diamonds1 +project1 +nascar88 +nina +ramirez +losangeles +chronic +gladys +5150 +poisson +marina1 +jasmin1 +kendra +socrates +dwade3 +salvation +wachtwoord +cristiano +doggy +iubire +inter +spongebob2 +killme +464646 +hellohello +ilikepie +figaro +thomas123 +paula +admin1 +player69 +kayleigh +moimoi +brittney1 +qqqqqqq +rose123 +danila +syncmaster +viper +mnbvcx +leo123 +fuckfuck +lourdes +champ1 +mario123 +sweet123 +loveya +presario +freddie1 +breanna +facebook1 +amerika +john12 +steph +express +cartman1 +1qaz!qaz +dodge1 +password14 +qwedsa +linkedin123 +kingdom1 +loser12 +heckfy +pangit +amber123 +happy12 +polska1 +skyler +school123 +fatty1 +yasmine +honey123 +alina +nounours +brucelee +357159 +qwerty123 +cookie2 +larry +digimon +insane1 +tazmania +jacob123 +hell666 +fu7u4a#$$$ +professional +wanker +321321321 +fitness +963963 +8888888888 +wow123 +mookie1 +69camaro +opeyemi +eh1k9oh335 +cheetah +eeeeee +surfing1 +freestyle +nokia123 +m123456789 +pontiac +oracle +member +pacman +tuning +converse +jerome1 +qdujvyg5sxa +caleb1 +xxx123 +sally +poland +nguyen +11221122 +shotgun +hernandez1 +booty1 +girls1 +doberman +poppy +fuckoff! +keith1 +geraldine +placebo +http +dodger +beavis +futbol +sexy10 +lupita +search +castro +lovelife1 +eastside ++++++ +caramelo +kristi +z1x2c3v4 +24681012 +central +lilly +abcdef123 +whocares +l12345 +johannes +636363 +lexmark +microsoft1 +emerson +marika +sissy1 +757575 +tony123 +dante1 +playa1 +vvvvvv +walker1 +040404 +ziggy1 +bitch101 +voiture +candice +201314 +virginie +martine +chicco +hector1 +honesty +snake1 +cardinal +mylife1 +2112 +homer +bangladesh +pasword +church1 +sailing +milagros +122002 +babygirl11 +sexymama +anaconda +sniper1 +mexico123 +planet +topolino +110092 +12345f +rock123 +hariom +dragon2 +samsung123 +musique +lollypop1 +lionel +coupon +mamma +shasta +ashley2 +sexy16 +aa123456 +maryam +lobster +laurie +dragon13 +musicman +bintang +sesame +bomber +a654321 +jessica12 +baseball9 +abracadabra +555777 +general1 +scotty1 +xander +1357911 +20002000 +daniel +gotohell +benny1 +bill +porter +boots1 +nofear +gianni +stars1 +delphine +18atcskd2w +1996 +racecar +tacobell +love19 +yfdbufnjh63 +angel10 +summer123 +333 +1q2w3e4r5t6y7u +bigboss +omg199 +gonzales +oklahoma +student1 +taylor12 +anthony123 +smooth +bigtits +whiskers +testing123 +1970 +vfczyz +nounou +safety +walmart1 +ilovesex +123aaa +darkstar +sylvester +myfamily +alfaromeo +betty +wolf +excalibur +969696 +juanita +badgirl1 +myspace4 +0102030405 +laetitia +zxcasd +blue32 +velvet +trunks +19071907 +tabitha +555 +queen +harrison1 +trumpet +buster123 +morgane +celtic1 +tammy1 +coolio1 +password99 +bright +buckeyes +car123 +littleman +7ugd5hip2j +whatthezor +marta +donna1 +kitkat1 +summertime +star69 +abcabc +library +debora +ganesha +741258 +dream +messenger +snowflake1 +simone1 +katelyn +amanda123 +solnce +quincy +love4life +jesus2 +yoyo +wrangler +katie123 +carolyn +martinez1 +wanted +paradise1 +111112 +lovers2 +cintaku +c43qpul5rz +rctybz +love25 +leopard +qwe1122334 +selena1 +sexy22 +suresh +111333 +buffalo1 +kim123 +openup +armagedon +radio +london123 +lovehurts +party1 +manish +wendy1 +zxcvb1 +kirsten +baby14 +mersedes +megadeth +okokok +gerard1 +familyguy1 +lizzie1 +monamour +allen +trombone +prodigy +frogger +water123 +vanilla1 +cartoon +carrot +101112 +123456781 +gsxr1000 +1971 +beyonce1 +surfer1 +cm6e7aumn9 +martha1 +roadrunner +satellite +landon1 +123456a +piglet1 +hellboy +smile4me +gunners +angel101 +lee123 +stoner420 +happiness1 +harmony1 +brandon2 +abcd12 +eleanor +baseball8 +pupsik +love88 +komputer +joseluis +layout1 +1truelove +electric +rambo1 +carla +sundance +shaman +bigman1 +aussie +godisgood1 +marino +love20 +demon1 +freebird +beast1 +fuckoff2 +jazmin +pakistan123 +moocow +smackdown +monaco +ihateu +matt123 +shaggy1 +nickjonas1 +cutie12 +19691969 +12345654321 +blah123 +briana +marisol +firefox +business1 +ismail +dangerous +kisskiss +ben +mandy +snakes +marcin +register +p0o9i8u7 +nokian73 +rachelle +bhbirf +8ix6s1fceh +shadow11 +groovy +margot +isabel1 +wolverine1 +easy123 +anakin +tangkai +squirt +thankgod +insert +thomas12 +teiubesc +friday1 +jennie +fredfred +trabajo +conner +4runner +garcia1 +miley1 +james2 +ballet + +brigitte +baker3 +ethan +oakland1 +maroon5 +rootbeer +asshole123 +ashish +jeanette +2525 +tottenham1 +lakers8 +dfktynbyf +carmela +ford +packers4 +iw14fi9jxl +weezer +20012001 +jose +mackenzie1 +summer11 +ramses +glitter +angelika +goblue +heslo +theboss +mystery +career +voyager1 +sonia +bobbie +love77 +sahara +kathleen1 +deanna +stevie +sascha +hotrod1 +ilovegod1 +hummer1 +sofia +lowrider +mammamia +melisa +welcome2 +moscow +66666 +raider1 +lola +iloveher1 +momof3 +i +parola12 +pikachu1 +imagine +gianluca +369852147 +2002 +snake +akatsuki +ronald1 +stranger +a123456a +mattie +whatsup +white +bryant +ramesh +dogdog +giggles +aaa123123 +chucky +dima +omega1 +852963 +billybob1 +qazzaq +filippo +computer12 +sparkle1 +anastasiya +chandler1 +rebound1 +babybaby +qwerasdfzxcv +zxcv123 +senha123 +sunday1 +alex11 +wassup +qwertyuiop123 +bentley1 +robert123 +yellow12 +kicker +falcons +lorenzo1 +tina +alvaro +asd12345 +married +blasted1 +darren1 +daredevil +bingo +spanish +ernest +kikeunyw +vectra +madness +1234qw +happyday +beagle +rainbow6 +claire1 +jericho +butterfly7 +supernova +maman +ilovemom +morpheus +dandan +linkedin +miami1 +rfrnec +emmanuel1 +kangaroo +football23 +ntktajy +neptune +accord +carol +sexsexsex +tigger123 +sailormoon +metal +cooldude1 +philly1 +patrik +bangalore +hotboy +strike +brooks +nobody +famous +alice1 +878787 +guardian +soldier1 +mine +cecile +becky1 +freak +smart1 +m +desmond +simran +me1234 +gameboy +clarence +sonic +q1234567 +running +alexandria +amanda12 +2580 +buster12 +369963 +derek1 +joshua12 +blueberry1 +standard +arlene +marijuana1 +omarion1 +zzzzzzz +evangelion +fantasy1 +amazing1 +iloveyou8 +crazy8 +poop11 +hamburg +kathy1 +scania +dragonballz +trigger1 +capslock +yvette +ultima +adam12 +hitman1 +viphv5j736 +me +kakashka +giorgio +escape +456 +sean +chargers21 +cats +lalalala +dublin +qweasdzxc1 +thomas +purple7 +ghost +hannibal +gameover +fuck11 +clayton1 +pas +suckmydick +999666 +penguins +trixie1 +moneymaker +shelley +sharma +oleg +last.fm +stacey1 +jenny123 +million2 +camera +oranges +qwerty13 +ramones +courage +mateusz +junebug +9876543 +cristal +****** +pink11 +mongoose +pyramid +carrie1 +johndeere1 +myangel +1999 +000webhost +smith1 +shirley1 +mumbai +cooler +cfitymrf +wasser +mylove123 +172839 +estrella1 +wolves1 +clinton +8888888 +redhot +loveu1 +welcome12 +caterina +randy +philly +enrico +asdfg12345 +654654 +ace123 +juicy1 +mother123 +3333333333 +bubba123 +q2w3e4r5 +dannyboy +sergio1 +19701970 +salope +pa +zipper +1966 +michelle12 +anarchy +koshka +roger1 +1231234 +benny +nelly1 +westham1 +biggie +lesbian +pooper +charger +angel14 +security1 +movies +sameer +13243546 +kentucky +delta1 +queenie +matematica +sexy1234 +.adgjm +125125 +juanito +danger1 +coldplay +lokomotiv +michael7 +schalke +collin +alonso +namaste +ilovemom1 +iforgot1 +mommy3 +babyphat1 +159263 +monopoly +mazda626 +741963 +cherry123 +flash1 +funny +z12345 +stingray +200 +katarina +bonita1 +fuckyou13 +++ +1968 +univers2l +patriot +014789 +trinity3 +nintendo64 +tom +goblin +patrick +jeffhardy1 +1qazwsx +bernardo +valentine1 +qweasd1 +santosh +batman12 +medina +1z2x3c +retard +snowboard1 +blackdog +backspace1 +dorian +algerie +hendrix1 +bushido +asdfgh12 +bitchy1 +v +joe +leavemealone +marino13 +lonewolf +flyers +aubrey +swimmer +sakura1 +moneyman1 +mickeymouse +cristo +sooners +jesusis1 +myspace08 +momma1 +2fast4u +donnie +jimbob +baby1234 +01230123 +cucciolo +umbrella +louis +6666666666 +denver1 +diego1 +123456o +20202020 +tracey +goodbye +686868 +abc123abc +god123 +12qw12qw +killer7 +katelyn1 +110 +rodney1 +megaman1 +anthony12 +knight1 +575757 +fletcher +bitch13 +hellothere +soccer18 +yellow123 +lol12345 +love06 +angelo1 +kickass1 +trance +iloveu! +king23 +hello5 +margaret1 +christy1 +guigui +nonono +fuckyou666 +hello11 +122112 +summer69 +vfhufhbnf +741741 +joker123 +goldberg +kristian +angel22 +bball23 +love99 +ana123 +donovan +morales +magic123 +858585 +zxcvbnm, +22446688 +paladin +brutus1 +brown +vitoria +kendra1 +belle +515151 +buffy +2001 +rupert +barsik +wutang +jordan11 +software +madina +woodstock +dalton1 +my3boys +bigmac +dondon +mattia +punisher +rosie +sisters +000123 +11 +hayley1 +cheese12 +playboy69 +none +waters +987321 +trucker +football13 +poodle +dan123 +jimmy123 +gilbert1 +godzilla1 +baby08 +bubbles2 +angelique +antony +baseball4 +callie1 +147963 +machine +lilmama +adam123 +shawn +manisha +girl +mountain1 +1997 +tractor +fortune +houston713 +windows7 +primavera +madden +piggy1 +snuggles1 +reebok +kieran +eugene1 +sonny1 +godfather1 +babatunde +gorilla +lahore +together +buddy2 +gratis +goldie1 +myname1 +bastard1 +briana1 +holahola +jeffhardy +integra +mechanical +qwert1234 +postal +basket1 +hot +server +benito +redalert +bugsbunny +gretchen +dragonfly1 +...... +button +jesuschris +december12 +princess5 +polopolo +maldita +june12 +12345w +money$ +ferret +1a2a3a +wildcat1 +hanna +honeyko +daphne +money23 +bayern +wendy +hollister +smitty +romano +dookie +duke +hussain +tiger2 +michelle2 +busted +kendall1 +qwaszx12 +michael3 +maryann +baby23 +family123 +everest +roger +alucard +candy12 +bears1 +letmein123 +iloveyou10 +pudding +bearbear +sandiego1 +123456789n +babygirl01 +papito +benoit +blaster +sparrow +10203 +19711971 +mathias +dont4get +prakash +kamasutra +vegeta1 +estelle +nana123 +535353 +catarina +booboo2 +616161 +monty1 +tootsie1 +megaparol +beach1 +katrin +holden1 +trucks +help +2010 +legend1 +jared1 +852852 +bitchass1 +anna123 +404040 +anime1 +hondacivic +sponge +better +wizard1 +cardinals1 +sexybeast1 +guillermo +pokemon2 +cheesecake +television +love00 +spirit1 +blue23 +poker1 +summer10 +noodles1 +414141 +as790433 +devon1 +english1 +elaine1 +spartan1 +ben123 +123456789g +prelude +fabulous +andres1 +reading +nikolay +beckham7 +hurricane +peekaboo +tyrone1 +#1bitch +pussycat1 +studio +spooky1 +positive +20022002 +britt1 +memphis1 +manager1 +mon +estrela +alaska1 +skylar +baseball22 +contact +beethoven +maximilian +kristy +arthur1 +grizzly +lancelot +chanel1 +loved1 +loveya1 +popo +francisco1 +sunny123 +scorpion1 +taytay +coolcat +shadow01 +hihihi1 +cody +audrey1 +santiago1 +devil1 +dimitri +1football +turner +hunter01 +taylor123 +cheer +babyface1 +always1 +coolguy +alpine +lena +innocent +joyce +tkfkdgo +kosmos +muslim +goddess1 +infiniti +soccer09 +fatass +fytxrf +jewels +norman1 +lawrence1 +1q1q1q1q +allah786 +silence +74108520 +original +monkey01 +joaquin +ravens +aqwzsx +chickens +blades +pedro1 +mamour +pink13 +packard +nathaniel1 +balls +supergirl +meowmeow +alexander +jesussaves +hayabusa +chicken123 +connie1 +sandy123 +112233a +medion +gerardo +domino1 +yellow2 +woaini1314 +colton +ybrjkfq +babygirl14 +hotmama1 +anjing +carlo +chelsea123 +cleveland +love55 +eleven +pallmall +hawkeye +767676 +frances1 +werder +edison +cha +center +7753191 +q11111 +hotshot +flower12 +2008 +tattoo1 +tanya +dragon11 +marco1 +comfort +higgins +yfnfkmz +passpass +trooper1 +666666a +longhorn +beach +chloe123 +softball12 +dragoon +poonam +my4kids +giorgia +incorrect +leandro +kontol +trebor +morning21 +warlock +joanna1 +email +gunit1 +chipper1 +oakland +kosama +tarheels1 +matthew2 +team +demon666 +grapes +temp123 +128500 +mariano +dillon1 +dragon69 +shutup1 +arianna1 +myspace10 +goofy1 +lemons +orange123 +qqqqq +j123456789 +fabiola +striker +krista +terry +2007 +noname +dmitriy +director +unique1 +sanchez1 +puppy123 +faithful1 +destroy +youyou +money3 +crimson +eatshit +annette1 +jacques +mariposa1 +gamecube +jersey1 +ilove69 +moneyman +lesbian1 +mexico12 +gegcbr +cocoa1 +dirtbike +gatito +juancarlos +santana1 +marcia +network1 +braves1 +chuck1 +jundian2011xr +eureka +fucking1 +milana +dell123 +sylvie +stormy1 +chemical +minime +pencil1 +kawasaki1 +demon +fatcat1 +puertorico +jones +123456i +92k2cizcdp +daniil +dharma +mihail +2006 +paradox +mazdarx7 +weasel +1234zxcv +thirteen13 +mishka +french +fuckyou22 +fallout +howard1 +dad123 +meredith +abcd1234 +nyq28giz1z +grandpa1 +printer +cancer1 +redbull1 +angelbaby1 +ab1234 +anything1 +cavalier +hentai +paramore1 +123456789e +145236 +triumph +lulu +noelle +william2 +iloveme123 +starbucks +pimp13 +rdfhnbhf +monkey10 +sunshine7 +jesus01 +luciana +david12 +elefante +class09 +fatman +purple11 +taylor2 +lovergirl1 +love2010 +matthias +1967 +mama1234 +summer01 +smiles1 +brendan1 +159753456 +qqqq1111 +iamnumber1 +sassy123 +haters1 +222 +apple2 +jasmine2 +pepper12 +e12345 +mckenzie +lala12 +qaz +portland +mahesh +khalid +0987654 +kentucky1 +longhorns +vb +knights +boss +justin2 +321 +loveyou123 +susan +prasad +1998 +revenge +whiskey1 +soccer101 +showtime +holla1 +gatita +joshua123 +e +mankind +123456789abc +1fuckyou +456987 +stoner1 +hope +kimkim +sevilla +yfcntymrf +kjkszpj +cristina1 +babyboo +yamahar6 +boobs1 +pepsi123 +456456456 +lebron +impala +dream1 +doodle1 +hejsan +zouzou +onlyme +maymay +felicidad +333444 +jones1 +lol1234 +lovegod +auburn +riley +kipper +kittykat1 +srinivas +azamat +angel21 +zaqxswcde +marvel +purple13 +tom123 +cardinals +1hottie +manny1 +hunter2 +soccer! +741258963 +coconut1 +griffin1 +whatsup1 +asdfzxcv +rooney10 +notthat +abrakadabra +administrator +895623 +oluwaseun +irock1 +a123654 +monkey6 +baseball21 +dimples +janelle +zxcvbnm12 +chase +balaji +shasha +silly1 +robert12 +sheba1 +terror +batman2 +pippin +ivanova +pirates1 +vinnie +home0401 +baby22 +lady +stalker1 +ismael +finalfantasy +ilovemusic +camilo +stoner +jordan01 +evelyn1 +jenjen +broadway +addison +brayden1 +souljaboy1 +cutegirl +kaka22 +runner1 +rodriguez1 +violin +green2 +telefono +emanuele +rfn.if +shotgun1 +beer +hithere +dkflbckfd +hanson +333777 +cepetsugih +vancouver +ellie1 +spectrum +258000 +123459 +baby15 +daughter +ilaria +roxanne1 +nikita1 +outlaw1 +mason +dfcbkbq +jenifer +fuckface +salmon +nasty1 +sexyme +pavilion1 +braveheart +120 +mmmmmmmm +blink123 +cathy +fra +camille1 +balance +selina +monroe +starcraft1 +giggles1 +frogger1 +qazxsw123 +dfkthf +chris13 +children3 +babygirl7 +rachael1 +agustin +football4 +halloween1 +warriors1 +football8 +asdfghj1 +boy123 +cosmo1 +amarillo +113113 +797979 +stinger +12312312 +evgeniy +bruce1 +flash +747474 +bratz1 +chronic1 +coolgirl +bobo +diosesamor +boxing +adventure +bordeaux +roxana +pooppoop +007 +biscuit1 +kissme2 +angel23 +joker13 +qwertyuiop +meandyou +beetle +mykids3 +werner +purple3 +apple12 +kaykay1 +999888 +imcool1 +agosto +tracy1 +dimple +domingo +irish +chivas10 +andrew2 +393041123 +cantona +s123456789 +cinema +temp1234 +luna +penis123 +vfibyf +jonas123 +ashlee1 +artemka +12345n +coolcool +oakley +kansas +torres9 +bacardi +erika1 +beanie +maggie12 +thug4life +italia1 +1212121212 +reagan +fallout3 +missy123 +kitty2 +tyson +lionheart +budweiser +temitope +kenzie +tiesto +rocknroll1 +columbia +gillian +19681968 +junior123 +harry123 +dogs +topsecret +king1234 +number3 +brandon12 +loredana +skater123 +titans1 +burger +bumblebee +number +start123 +scream +simpleplan +waterloo +libero +1mother +angel15 +assass1 +bender +fossil +loves1 +amours +legion +373737 +iloveyou69 +irene +woody +leonie +bernadette +hannah01 +home1234 +vishal +996633 +jessica +iloveme! +jumper +kitty12 +ludmila +romina +secret123 +kayla123 +changeme1 +jenna +rivera +pelusa +1z2x3c4v +citroen +4444444 +blessings +kaykay +teddy123 +thirteen +beloved +buckeyes1 +jjcg16dj5k +dietcoke1 +hermes +hubert +charlie +keith +eduard +tupac1 +daniel2 +smackdown1 +myspace9 +khushi +1964 +passwords +jorge1 +carmelo +heroes +123qwe123qwe +qwerty77 +krasotka +gizmo123 +lovergirl +fuckface1 +archana +kleopatra +password15 +amelia1 +prissy +2020 +cobra1 +hollister2 +anime +pirate1 +online1 +busted1 +hoover +yomomma1 +monkey4 +wonderland +jorge +susan1 +orange12 +celtic1888 +bigmoney +legolas1 +gambit +chivas11 +dorothy1 +donna +monster123 +lukas +ballin +114477 +loser2 +alex01 +su123456 +stones +giraffe +yahooo +money7 +jesuss +svoboda +overlord +baby101 +blackjack1 +mommy12 +almighty +cute123 +commando +amalia +megan123 +lovesucks1 +salvador1 +johnny5 +jazmine +rustam +escort +nick12 +honest +goodness +wertyu +flower2 +friends123 +thierry +damien1 +loves +zigzag +mustangs +archer +xfiles +alinka +lamborghini +parrot +iloveyou23 +bloods +school12 +141516 +14141414 +12345h +1965 +star11 +kelly123 +maggie123 +hotty1 +nicole13 +princess21 +sssss +19051905 +belle1 +1qazzaq1 +pass12 +theodore +patrice +newpassword +ihateu1 +cutie101 +diamante +stefanie +cgfhnfr +health +dominican1 +qwerty777 +mallory +buckeye +brandon123 +fuck0ff +shibby +asd123asd +eragon +andy123 +jupiter1 +princess14 +d2xyw89sxj +fyutkbyf +ayesha +brothers +mittens1 +lifesucks +olayinka +honduras +qqwwee +qaz123456 +12345qw +leonardo1 +lillian1 +anne +hellsing +battle +killers +sucesso +vicente +justine1 +1234rewq +168asd168 +blanca +toto +birthday1 +maddog1 +nicky1 +ihateu2 +cherokee1 +jazmine1 +monkey23 +vicky +stargate1 +charley +hockey12 +123abc123 +23456 +willy +lizard1 +life +mustang2 +plastic +12345600 +georgie +rebeca +chelseafc +michael1 +richie1 +dragon +thesims2 +pot420 +ericka +melody1 +westwood +pothead420 +lucky2 +retired +rambo +starbucks1 +bitch3 +2sweet +sexy09 +renee +mother2 +1111qqqq +cinta +demons +lewis +dauphin +system1 +01010101 +shitface1 +123admin321 +harley01 +multiplelog +plymouth +josh12 +1money +mark123 +red1234 +lolipop1 +bowling1 +allah +henry14 +gsxr750 +konstantin +963258741 +luke +kate +hermosa +corinne +password09 +bernard1 +keeper +biology +sephiroth +derek +gabrielle1 +albina +don +951357 +kontakt +hannah2 +lowrider1 +mexico10 +duchess +cricri +silent +789789789 +romero +camaroz28 +myspace23 +poncho +pooper1 +market +maurizio +nicole11 +baby10 +www123 +123456789w +mondeo +piccolo +lineage2 +pandora1 +tiger12 +qqqwww +weed123 +myspace101 +welkom +nevaeh1 +helloo +momo +celtics +taishan2011 +manila +gandalf1 +venus +jennifer +animals1 +evergreen +iloveyou21 +eatshit1 +786786786 +artemis +tricia +estrellita +bloody +1234567z +hottie! +nikki123 +danica +love44 +matador +leelee1 +ferari +toffee +wallace1 +alexander2 +alexalex +123698741 +girlfriend +loveu +projectsadminx +marilyn1 +married1 +sponge1 +brayden +jack12 +money11 +someone +blowme1 +cowgirl1 +bobbob1 +toledo +highlander +jktymrf +1221 +torino +surside13 +titanic1 +volkswagen +2good4u +bartek +00112233 +pdtplf +bkl29m2bk +pavel +fabrizio +babyboy2 +mayday +sleepy +twins +444555 +assman +sullivan +isaac1 +484848 +annamaria +g12345 +herbie +ufkbyf +darlene +april12 +blabla1 +happydays +fgtkmcby +seattle1 +a1s2d3f4g5 +cheese2 +preciosa +temple +uhfybn8888 +rainbows +senegal +pollito +jordan3 +11111111111 +wenoob +pimpdaddy1 +masters +imperial +gay123 +yandex +kiki123 +coolman1 +iamcool +number9 +frederick +pacific +rossi46 +passport1 +hooters1 +prettyboy1 +journey +luis123 +quality +georgina +560076 +mylord +becky +chubby1 +lola123 +scooter2 +tamara1 +moneys +rootbeer1 +kenken +ou812 +diane +maribel +warning +cowgirl +buddy12 +love2009 +shanti +rereirf +0123 +minerva +asroma +lights +jordan13 +spring1 +alex10 +nadia +123458 +sweets1 +karine +gavin1 +elmo123 +lewis1 +jasmine123 +aiden1 +jose12 +halflife +jermaine +burton1 +myspace22 +baby09 +capricorn1 +shogun +dortmund +zxcv +ichliebedich +viviana +mariel +spitfire1 +fusion +utopia +free123 +zaqwsxcde +painter +catania +carlotta +baseball23 +stitch +omega +azertyui +jonas +computer2 +000999 +zxcasdqwe123 +sexyme1 +stealth +a123321 +jeffery +mehmet +sexylove1 +mathew1 +??????? +three3 +horny1 +mihaela +corazon1 +carmel +ginger12 +qwer4321 +bagira +turbo1 +swimmer1 +techn9ne +moon +jesusfreak +hercules1 +sandman1 +lemonade +mango1 +arnaud +lovely2 +2345678 +wellington +nurse1 +ilovechris +punkrock1 +millwall +p12345 +daniella +lassie +daniel01 +pazzword123 +mummy1 +massage +unknown1 +youandme +huhbbhzu78 +chico +bennett +635241 +loveislife +patate +87654321q +neveragain +kifj9n7bfu +gator1 +7007 +7777777a +gordon1 +ali +dominika +silverado +123456789qwe +number7 +lizzy1 +987123 +joejonas1 +myself1 +tasha +1sunshine +colleen1 +teamo123 +kodiak +1235789 +kill +tigger01 +adrien +zazaza +jamie123 +redwings1 +kathryn1 +sucker1 +wayne +karate1 +kayode +latino +dancing1 +whatever! +start1 +peterpan1 +bighead1 +mhine +nigga123 +confused +rtyuehe +sonyericsson +lalala123 +butterfly3 +myspace09 +6 +balls1 +bubbles123 +gfhjkm123 +abc321 +rihanna +cannon +123412 +anthony3 +73501505 +delta +magnus +asdfghjkl123 +addison1 +left4dead +brighton +francine +malaga +austin12 +shadow +jamesbond007 +maddy1 +charger1 +networking +poetry +zacefron1 +stunt101 +carol1 +fatman1 +jesus3 +clarinet +conrad +ohiostate1 +whisper +cavallo +michelle +hi1234 +celeron +smooth1 +yolanda1 +mission1 +sexy18 +cellphone +ramram +faster +walmart +princess22 +madison2 +babe +beaner1 +technics +resident +aerosmith +india1 +youtube1 +salomon +bitch11 +mike1234 +010 +cafemom +senior09 +choupette +sagitario +november11 +cobra +sunshine3 +shanghai +mazda6 +igor +19671967 +ashley11 +astonvilla +durango1 +snoopy2 ++ +angel16 +jeffery1 +latina1 +princesa1 +testing1 +a00000 +mykids2 +pompom +dance123 +7412369 +jg3h4hfn +yanyan +mollie1 +grizzly1 +434343 +benji +blazer1 +buddyboy +koolaid1 +benben +mafalda +1234567m +matheus +support +loulou1 +squall +demon123 +jade +june22 +margarita1 +qwe1234 +dddd +blacky1 +hohoho +trust +1qay2wsx +demo +115599 +dt123456 +soccer19 +roscoe1 +lisa123 +dreams1 +12211221 +sta +147896 +gertrude +linda123 +polo +madagascar +727272 +astrid +coleman +iphone +gabby +matilde +durango +tabitha1 +volley +bobmarley1 +bitch01 +nicole3 +working +iloveyou9 +splash +kingsley +jackjack +zombie1 +princess4 +carbon +pussy2 +carson1 +joshua01 +daddy2 +badminton +desert +20052005 +europa +warszawa +skater12 +reaper1 +hollie +fuckthis +dusty +toby +maksimka +dirty1 +1963 +felicia1 +linkedin2011 +n12345 +raiderz1 +candyman +cheetah1 +babygirl15 +a112233 +willy1 +faggot +madeleine +vfitymrf +summer2 +babygirl5 +storm +fuckyou5 +kathy +murder1 +1231231 +violetta +jerusalem +warren1 +w66yrybgra +viktoriya +sexsex1 +baby07 +yummy1 +loveme3 +blackrose +1234567s +blackbird +laura123 +159753a +alexa1 +fullaccess +ahmed +ms0083jxj +8522003 +peyton1 +respect1 +emiliano +kostya +popo123 +green7 +davids +june23 +sunita +roxy +pearl1 +hfytnrb +chaton +carlos12 +baker +panda123 +adelina +myboys +chevys10 +kathmandu +ariel +becca1 +1596321 +czz000 +miracle1 +notebook +megasecret +michael23 +america123 +nokia5800 +ryan12 +apollo1 +ananas +ihatethisgame +musica1 +shakira1 +werty +princess +ncc1701a +susanne +playstation3 +19651965 +archie1 +pothead +jokers +ariel1 +bertha +7896321 +meatball +131415 +bigmoney1 +imnumber1 +forzamilan +nacional +browns +caca123 +fre +sandhya +pimp11 +kingking +marcello +blake +hacker1 +yannick +racecar1 +15151515 +moonlight1 +shit123 +smelly +caca +smart +cantona7 +mercury1 +chris11 +diamond2 +benji1 +pulsar +spartans +boricua +555556 +yvonne1 +isabelle1 +lucky12 +josefina +tommy123 +babygirl09 +nodefinido +201010 +classic1 +bunny123 +babygurl12 +saskia +stewart1 +geoffrey +harrypotte +select +delacruz +1a2a3a4a +solution +10577 +butthole1 +ilove123 +allie1 +powder +gaston +nestor +triskelion +pinkie +condor +liverpool8 +chivas123 +oldman +start +1475369 +nanana +ale +606060 +remington +kakaka +jake12 +qqqqqqqqqq +alegria +lilman +david2 +iloveu12 +123456789h +gabriela1 +maximum +music101 +qwe1asd +skyler1 +girasole +didier +ginger123 +rakesh +money100 +honduras1 +london22 +disturbed +arsenal123 +madeline1 +poochie +poseidon +mulder +celica +davidson +revenge1 +bruce +sparkles +777999 +bossman +fabio +crjhgbjy +silvana +chacha1 +123456789f +monika1 +grumpy +fxzz75 +seagull +you +colts18 +yxcvbnm +front242 +muppet +login +chicca +momomo +p455w0rd +cody123 +superfly +tyler12 +blade +w12345 +mariya +132465 +57chevy +clifford1 +coco12 +aileen +1loveu +bear123 +leader +2009 +kim +gaurav +iamcool1 +sexy08 +dylan123 +198 +joejoe1 +1qazxsw23edc +portugal1 +paolo +tomtom1 +noodle1 +bigpimpin1 +senior08 +mileycyrus +survivor +robert +123654a +vanesa +tomate +senior +mike23 +sara123 +freckles1 +makemoney +willis +mississipp +pepper123 +godsmack +finger +celeste1 +bautista +vendetta +seventeen +ncc1701e +camelot +junebug1 +lovestory +pooh +pablo +briciola +helloworld +tresd5 +jermaine1 +fuck666 +skinny +semperfi1 +rabota +jess123 +pierre1 +121 +bubbles12 +mikemike +work +poipoi +pictures +pornstar1 +princess23 +sasha12 +adeline +superman7 +sprite1 +knicks +pillow +ltybcrf +daddy12 +charlie12 +bebe +pa55word +livelife +juan123 +oklahoma1 +cancel +kashmir +tdutybz +jess +hotmama +hospital +boo +4myspace +sweden +x3luym2mmj +2003 +45454545 +skiing +chrisb1 +hamish +tyler2 +cleveland1 +maniac +meghan1 +billy123 +trojan +june13 +handsome1 +blueeyes1 +spyder +roses +beaner +moises +steelers7 +blade1 +rhiannon +slipknot6 +nightwish +yankees13 +four20 +101101 +aaron123 +ilovehim2 +357951 +anthony7 +mystic +san +labtec +hammers +crip4life +lifeisgood +daewoo +dragon7 +indians +october10 +wolfman +stryker +tammy +sexyman1 +tekken +marie12 +yyyyyy +qwerty78 +orchid +coolkid1 +keisha +africa1 +iverson1 +navigator +gotmilk +584520 +ashley13 +myspac3 +334455 +bionicle +humtum +1loveme +simpson1 +waterfall +999 +noisette +mimi123 +jordan5 +huskers +scottie +luther +superman3 +psycho1 +yahoomail +20072007 +motocross1 +jared +armando1 +123456. +1iloveyou +nataly +rasmus +clarissa +shorty12 +fisherman +baby21 +hello9 +zxcvb123 +abcde123 +hardrock +annalisa +safari +159753123 +june21 +darkangel1 +hotgirl +chucky1 +babe123 +789632145 +celina +awsome +rockets1 +elisa +rjycnfynby +patito +1michael +cbr600 +milkshake +lightning1 +monkey21 +greg +simsim +myspace8 +montgom2409 +tesoro +bitch5 +solomon1 +- +s8ylpe9jdpvym +classof07 +google12 +love2008 +560037 +newstart +bigbang +classof201 +stallion +wonderful1 +firebird1 +olenka +sterling1 +daniel11 +playboy123 +forest1 +evony1 +1435254 +nicole01 +kaka +121121 +frog +hustler1 +razvan +blackman +poo +baseball6 +snoopdog +haha12 +female +franck +company +159159159 +bhebhe +adewale +whisky +mallorca +freeze112 +0192837465 +killer11 +green13 +myspace69 +adelaide +daytona +cimbom +emachines1 +paola +19031903 +baseball24 +reality +bball +april20 +m1234567 +monkey101 +tomorrow +mathis +peanut12 +legenda +shorty13 +shania +mobster1 +bunnies +868686 +ecuador +sunset1 +199 +bookmark +bangbang +rjynfrn +alison1 +sausage +lavoro +peanut2 +thomas2 +northside1 +class08 +naruto2 +198888 +johnpaul +subway +andrew11 +cuteme +justin01 +brian123 +amazon +leoleo +oliveira +pharmacy +fish123 +duncan1 +forget1 +maximo +nopass +kalina +lifesucks1 +vbkfirf +albatros +banshee +lil +foxtrot +new +giacomo +steffi +william3 +freedom2 +littlebit +sheldon +capone +keegan +central1 +glamour +beaver1 +april21 +thursday +indya123 +mollydog +reggae +gringo +bounty +greece +25011990 +rowena +princesita +adekunle +robinhood +lorraine1 +zaraza +cowboys22 +march17 +heineken +qw123456 +cheer123 +space +sexy17 +palmer +fuckyou11 +light +coolboy +professor +646464 +april22 +1q2w3e4r5t6y7u8i +mazafaka +homework +dbrnjh +koroleva +radio1 +principessa +gothic1 +baseball14 +angelus +z00000 +10 +godis1 +lampard8 +husband +persik +nugget1 +killer13 +corey +landrover +tequila1 +redred1 +a1a2a3a4a5 +heidi +kfhbcf +dwayne +rancid +medicina +candle +negrita +cotton1 +school2 +beckham23 +cooking +veronique +faisal +bookworm +answer +godhelpme +dragon01 +fghtkm +catwoman +smelly1 +friendly +phone1 +matahari +pleasure +ludacris +19991999 +july21 +will +saturday +mygirls +springer +shawty1 +fuzzy1 +zhjckfd +buster01 +babylon +aliens +chillin +peluche +triton +tsunami +maryland +cutie2 +jensen +black12 +1diamond +mickey123 +randall +marihuana +hello3 +love26 +frosty1 +football24 +nokian70 +candice1 +12321 +ilikepie1 +robert2 +coolcat1 +pink22 +adeola +baby16 +pandas +venera +webster1 +ankara +reddog1 +simon123 +cancun +12345qwer +control1 +flyboy1 +queens +venezuela +thomas22 +default +w +blueblue +asd1234 +ssss +roxy123 +incubus1 +angel88 +anuradha +ashleigh1 +pancho1 +reset123 +guatemala +ssssssss +applepie1 +12345v +garbage +manowar +mickey12 +food +project +alexis12 +kikiki +gremlin +ghostrider +m0nkey +1366613 +butler +gorgeous1 +kenwood +jillian1 +qwertyui1 +pok29q6666 +bonehead +22334455 +pimp23 +jaguar1 +rammstein1 +minette +forrest +mitch +leonard1 +amy123 +password08 +123asd123 +eeyore1 +1234567j +godofwar +amoure +create +junior12 +farida +dude12 +beaches +n1frdz +emerald1 +june16 +love777 +mighty +thomas01 +ordinateur +23jordan +zxcvbnm +george123 +krokodil +nastia +kittie +therese +giovanni1 +password88 +jessica3 +password24 +account1 +racing1 +angel07 +az123456 +383838 +pat +lucia +auburn1 +abcd123456 +sadie123 +qazzaq1 +lovebird +mommy11 +a1a1a1a1 +venice +meme +flipper1 +rogers +novo +bigbird +big123 +qwe789 +bengals1 +jasmine12 +versace +maggie01 +mary123 +heidi1 +satana +123456789v +malachi +greenday12 +family2 +veritas +porkchop1 +tatiana1 +eight8 +terrell1 +verona +puppylove1 +legacy +tootie +dipset +holland1 +mazda323 +homeboy +zander +baker1 +deutschland +manning18 +open +april13 +zxcvb12345 +1475963 +yuliya +margherita +tomas +my1love +janet +mango +family3 +12345677 +iguana +birdman +123456aaa +poptart1 +1234565 +123abcd +tweetybird +louis1 +south1 +lovely123 +ठ: +london +porn +1q2q3q +mom +blossom1 +shorty123 +thelma +chivas12 +chosen +qwerty69 +samantha12 +lucille +speed +aberdeen +martin123 +hockey11 +orange2 +candy2 +fabrice +love27 +ebony1 +l1nk3d1n +barbados +1357913579 +biteme2 +tkbpfdtnf +???????? +weezy1 +go2hell +tuesday +fanfan +guitarra +michela +killian +lucy123 +speaker +456789123 +munchkin1 +godislove1 +latina +220 +sprint +pancakes +grover +melvin1 +escorpion +liberte +626262 +ashley01 +twister1 +basketbal1 +payton1 +mynameis +k.lvbkf +guadalupe1 +babygirl21 +edward123 +ray123 +hottie3 +il0veyou +training +bassman +21122112 +progress +qwaszx1 +123123123123 +zelda1 +melinda1 +june11 +grandpa +myspace0 +angeline +violet1 +sexybaby1 +roberts +love34 +grace123 +motherfuck +ghjcnjnfr +q2w3e4 +scully +guilherme +john!20130605at1753 +333333333 +skyblue +123890 +cherries +buckeye1 +forzaroma +janette +taylor01 +music2 +newmoon +14881488 +wednesday +indira +andrew01 +clemson1 +kittens1 +april23 +whiteboy1 +peanuts1 +mummy +fighter1 +2children +789852 +dinesh +ilovepussy +deftones1 +619619 +tenerife +march +mariana1 +chris01 +dallas22 +alisha1 +jingjing +pankaj +icarus +eternal +707070 +parkour +jaden1 +history1 +c.ronaldo +justin11 +fuckers +luis +pietro +ignacio +babygirl! +bellissima +huskers1 +kungfu +goforit +babygirl16 +rosalie +zeppelin1 +redman1 +mancity +deanna1 +nokian95 +110085 +lovesucks +vertigo +destroyer +cadillac1 +good123 +amor +lesley +babygirl08 +princess15 +evanescence +roma +123321123321 +pepper2 +byusdg23 +smoking +56789 +ripper +winchester +holmes +йцукен +love4you +dilbert +sexy07 +1232323q +z123456789 +duckie +doctor1 ++ +number5 +rashmi +18n28n24a5 +great +rawr123 +fabregas +sexyman +operator +babygirl23 +possum +09876 +19641964 +kings1 +jordan10 +freeman1 +gotcha +phoebe1 +rjhjktdf +xxxxxxx +technology +angel69 +bessie +210 +panties +jesusc +billyboy +rafael1 +arnold1 +comcast1 +apsk54321 +tara +dixie +music4life +andrew +gotcha1 +time +suzuki1 +bridget1 +paige +principe +concrete +anita1 +porno +monsters +battlefield +mother12 +ayomide +nike +pirata +turbo +lolo123 +missyou +carolyn1 +fergie +pakistani +z0102030405 +april15 +greenbay +chivas13 +grandkids +789 +home123 +whatever2 +indian1 +roller +mylene +bruno123 +horizon +besiktas +yeah +1232123 +kiss123 +qwerty666 +dutchess +janet1 +ठ +monkey8 +owt243ygbj +ursula +nikolai +blingbling +angel4 +bigfoot1 +chevrolet1 +nigger123 +qwerty01 +maynard +101 +24242424 +emotional +qwerty789 +marcella +manu +redsox04 +qwegta13091990 +boris +armstrong +717171 +bandung +zainab +iluvu1 +maradona10 +pauline1 +football20 +cock +lord +as1234 +madalina +joey123 +badboy2 +748596 +april14 +2424 +sherman1 +paula1 +colts1 +biggie1 +1414 +budweiser1 +alexa +louie1 +confused1 +snoop1 +star13 +cherie +9293709b13 +theused1 +sweet12 +valeria1 +dalila +kochanie +adonis +214365 +bailey12 +zzzzzzzzzz +village +street1 +zenith +theboss1 +333222 +nursing1 +ppppp +prashant +love5683 +buster2 +travel1 +cazzo +shorty2 +yesyes +hunter11 +chuck +kirsty +ontario +wisdom1 +ariana1 +june24 +qwerty22 +clover1 +sunshine +slavik +leo +morris1 +emma123 +vicky1 +barkley +0147258369 +rastafari +samtron +!qaz2wsx +donnie1 +777666 +march12 +aaasss +spike123 +softball11 +abby +petunia +sharingan +shady1 +catalin +dick123 +lovely12 +aaaaaaa1 +leonid +.adgjmptw +abiodun +dogdog1 +111111111111 +donovan1 +qwerty5 +223322 +mash4077 +130 +dollar1 +momof2 +111999 +stevie1 +mystery1 +mimosa +paperino +chicken12 +lalaland +hyderabad +liverpoolfc +20112011 +пароль +nelly +soccer08 +nokia3310 +canela +redrum1 +money4 +iloveyou15 +princess8 +marriage +sextrime1 +bertie +explorer1 +aa123123 +100200300 +famille +breeze +losers +jesse123 +yumyum +numba1 +iloveyou09 +italian1 +daniel13 +marlin +p@ssword +sousou +amanda2 +argentina1 +patty1 +mar123 +dottie +charming +blizzard1 +pizzas +123456abcd +mostwanted +110011 +pobeda +antares +patrizia +medved +compton1 +bonheur +fantastic +123stella +110120 +santos1 +iloveher +rhonda +martina1 +sssssss +crazy12 +bradford +butthole +lopez +daisy12 +magali +bugger +234234 +lynn +chinnu +angelbaby +jocelyn1 +mandarin +hamilton1 +love89 +honda123 +football09 +sunderland +tropical +mallory1 +desperado +discover +puppylove +march1 +samiam +pimpin2 +drogba +159 +family12 +edwards +jamila +rebels +321678 +wishbone +qwerty! +losers1 +ludovic +looser +booty +malcolm1 +mafia1 +conner1 +medical +princess +5poppin +fuckyou6 +transam +supergirl1 +cookiemons +helen +pistons1 +livestrong +sidekick3 +babygirl4 +pokerface +lee +bestfriends +manson1 +test1 +carlton +jessica7 +matthew12 +iloveyou6 +sidney1 +tigrou +deadman1 +hannah11 +hater1 +sammy12 +1962 +kimbum +young +christian2 +pringles +lovehate +juventus1 +85208520 +smoke +bugsbunny1 +commander +gianna +password19 +gwapo +papapa +nipper +1234509876 +bharat +pie123 +loveis +punkin1 +friends4 +bobobo +enrique1 +fred123 +mat +nikitos +142857 +jesus4me +picture +black2 +cabbage +jesus! +asdffdsa +scarlett1 +green11 +shmily +vacation1 +gonzalo +linkin1 +qaz123wsx +glitter1 +rodolfo +pupuce +games1 +mellon +jackpot +harley123 +737373 +123456zxc +2bornot2b +bogart +lamont1 +italiano +valentina1 +lemon8 +peters +zasada +dalejr +lance +goodbye1 +123456789. +charlie3 +yugioh1 +212223 +rhjrjlbk +rolando +goodlife +extreme1 +abcdefgh1 +badboys +tulips +cool11 +sweetgirl +roman1 +management +14121412 +2128506 +delete1 +pluto +hejhej +offspring +never1 +slick1 +eric123 +gabriel123 +schatzi +nissan350z +michael11 +blink +felicity +momanddad +bones1 +amistad +pablito +star1234 +angel18 +dodgeram +sheila1 +softball2 +august12 +isabela +thedoors +monkeybutt +hyundai +trial +one +zacefron +candycane1 +12qw12 +china +jordan7 +113355 +ferdinand +spunky1 +chaos +summer99 +heritage +butt +20062006 +kobebryant +badman +lover69 +jamal1 +bruins +19631963 +cecilia1 +kumar +booboo12 +spanish1 +1anthony +gameboy1 +hidden +4children +babygirl69 +1butterfly +princess9 +splinter +naveen +cruzazul +fantasia +sexyback1 +2blessed +baseball15 +natural +leather +hello. +freeway +morgana +nathan12 +bridge +jaihanuman +aa1234 +april16 +september9 +joseph12 +lickme +пїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕ +hjccbz +harriet +lopez1 +sonali +leon +light1 +zorro +51505150 +stanislav +exodus +bailey123 +argentina +booboo123 +fxzz75yer +benedict +mmmmm +dodge +katkat +football! +doodoo +aptx4869 +qwertasdfg +malachi1 +peanut123 +cinnamon1 +fuckyou4 +dolly1 +242526 +stepan +gorilla1 +fktyrf +mitsubishi +angel6 +murder +blue10 +caramel1 +electro +gold +wifey1 +theend +soccer20 +doomsayer.2.7mords.v +soccer24 +myspace07 +pink101 +sneakers +nevaeh +nokia6233 +march23 +highland +bristol +dookie1 +scarlet1 +coolguy1 +imgay1 +natacha +pepette +assasin +121283 +mildred +joshua2 +micaela +kannan +azerty +maria12 +150 +omarion +tweety2 +revelation +psalm23 +halo +nathan123 +vjcrdf +monster2 +june14 +weather +summer05 +password07 +19661966 +corolla +il0vey0u +lespaul +martins +adrienne +janice1 +charlie1 +bologna +klapaucius +ariane +rasengan +arsenal14 +polarbear +austin123 +aprilia +skinhead +sha +cevthrb +bossman1 +jessica13 +777555 +ciara1 +h2vwdubjx4 +wookie +strong1 +june10 +709394 +snowwhite +228228 +deborah1 +logan123 +bball12 +soccer07 +bluebird1 +alexis123 +april10 +sexybabe +caballo +william123 +kimmie +poochie1 +lexmark1 +fireball1 +hedgehog +keyboard1 +password20 +1004 +lolita1 +michael01 +angel8 +adv24 +pearl +angel08 +gggg +scooby2 +chuckie +april11 +margie +momoney +110001 +barbie123 +maciek +june28 +shinigami +1cookie +ruby +everything +shooter1 +27653 +maddison +bailey01 +love02 +love4me +19411945 +fishes +christie +aaaaaa +00001111 +devildog +chuchu +chivas100 +scout1 +aardvark +blessing1 +poussin +badger1 +kellie +soprano +250 +john1234 +crackers +lenochka +beautiful2 +march11 +delfino +sherry1 +scvmofas79 +july23 +01011980 +kirsten1 +ilovejusti +twisted1 +caline +maggie2 +cookie3 +matthew123 +seniseviyorum +shitty1 +june17 +trenton1 +sleepy1 +pacman1 +bloods1 +skylar1 +picard +smarty +chronic420 +qazqazqaz +xboxlive +jelly1 +destiny2 +110688 +jazz +holly123 +hello7 +joseph123 +eagles5 +funky1 +chiefs +nicole7 +piramida +michael13 +colton1 +vanhalen +softball13 +green3 +rebel +246813579 +dr.pepper +number12 +135798642 +amormio +chewy1 +harley12 +lucky777 +victoire +marcopolo +titties +bluebell +110019 +thegreat1 +aries +ladies +vernon +sagitarius +ghblehjr +october31 +monkey9 +secure +885522 +1a2s3d4f5g +nevada +mikayla +123123qwe +writer +casey123 +nikhil +creation +piper1 +forzainter +diablo666 +letmein1 +angel9 +snapper +kenworth +marcos1 +eldorado +march22 +daniel19 +corrado +annika +blackops +seamus +liverp00l +x123456 +italien +asshole12 +dom +shark +kelley +darius1 +believe1 +jennifer12 +apples123 +magandaako +skinny1 +ravens1 +faith123 +trojans1 +232425 +finance +123456789asd +beast +andrej +bigben +christelle +imcool +softball7 +andre123 +kenzie1 +josiah +dragon88 +baby69 +softball10 +firefly1 +you123 +starlight1 +i23456 +snoopdogg +piggy +carmelo15 +recovery +bitch23 +alvin +maryjane42 +amethyst +bulls23 +mazda3 +vittoria +rainbow123 +janina +andreas1 +juan +laguna1 +paper1 +aikido +sherwood +bambino +123456qwer +abcd12345 +shamrock1 +twinkle1 +children2 +april17 +w5tn36alfw +princess16 +sacred +gilles +warlord +slamdunk +jane +babygirl22 +soccer01 +doreen +qweqwe1 +benjamin +hogwarts +supersonic +crazy4u +qwerqwer2 +orion +tony12 +010203040506 +killa +110075 +lipgloss1 +123kid +cazzone +angeleyes +denisa +america12 +qwerty99 +greeneyes +kagome +joanne1 +jordan +dragon5 +banana123 +starfish1 +columbus +holla +porcodio +hotpink1 +goldeneye +isaac +alissa +nevermore +josie1 +eqes606898 +sunshine! +pallina +champagne +mmmmmmmmmm +winmx1 +456123789 +madden1 +1213141516 +esther1 +bushido1 +morning +paper123 +mariajose +cougar1 +sky123 +badbitch1 +lily +fordf250 +forever2 +harold1 +theonly1 +ninja123 +davinci +gucci1 +bass +houses +rufus1 +qazxsw1 +trololo +monkeyman +bebe123 +cambridge +anfield +vlad +bollox +rovers +cornelia +blue21 +1960 +design1 +restart +cougars +byebye +all4one +090807 +nabila +cookies123 +crosby87 +derp12!@ +mustang69 +onedirection +kacper +gidget +sweet2 +golfing +?????????? +friends! +zarina +cheese! +borussia +killer666 +tracy +pop +mexico2 +123369 +purple22 +hurricane1 +knights1 +football14 +viking1 +europe +362436 +skater2 +chris23 +400053 +yfnfkb +matthew +lacey1 +wonder1 +palace +allahu +urmom1 +vishnu +babybear +123258 +bonsai +eatme +cristian1 +pussy12 +mike11 +fucku123 +august11 +xxxxxxxxxx +septiembre +starstar +johnlock +dimadima +billie1 +buddha1 +drake1 +littlebit1 +muskan +princess08 +nimrod +twilight12 +window1 +bajingan +digger1 +cherry12 +20032003 +fatima1 +march15 +brady12 +lipgloss +opelastra +riverside +santino +popeye1 +march13 +caravan +birdman1 +wilbur +april24 +iloveyou08 +serena1 +987789 +irinka +ilovehim! +nolimit +131421 +nicole21 +bailey +bleach1 +hooligan +560078 +bishop1 +theused +12345asd +mygirls2 +illusion +command +makaveli1 +russel +ready2go +achilles +computers +taylor11 +zxc123456 +aaaaaaaaa +pablo1 +acuario +venkat +granada +elliott1 +55555a +sexysexy +kevin12 +june15 +a123098 +123soleil +underworld +password17 +cinder +monkey14 +shadows +julieta +7elephants +inspiron +mamochka +aishiteru +123a123 +vermont +peaceout +oliver123 +lemon1 +heaven7 +google.com +fart +prissy1 +harper +southern +crusader +hillary +chinese +moritz +lamont +caitlyn +tweety12 +rocky2 +1player +jubjub +mclaren +230 +1001 +milkshake1 +samuel01 +florencia +panasonic1 +samanta +pinkfloyd1 +sangeeta +sweety12 +sasuke123 +ducky1 +satan +snooker +jojo12 +sarajevo +pasquale +fullmoon +lillie +dynasty +mermaid1 +brasil +u77789 +1zxcvbnm +darrell +anarchy1 +slipknot66 +sheeba +dana +13 +passwd +lenovo +june26 +naruto11 +darkstar1 +chaos1 +feder_1941 +classof200 +easter +potpot +drew +cucciola +kirby1 +12345qaz +999000 +brodie +solange +gymnastics +140 +hurley +sterva +music12 +eminem123 +walnut +ziggy +pradeep +sophie123 +sammy2 +bella12 +girl123 +japan +secrets +fearless +fuckme123 +praveen +montecarlo +baba +zanzibar +0147852369 +azazaz +monster12 +firefighter +myheart +caliente +chris10 +peacock +eminem12 +luckydog1 +frank123 +carola +goose1 +shitface +bretagne +roxane +stonecold1 +aurore +banana11 +oregon +elizaveta +rose12 +jesus77 +gsxr600 +cessna +zxccxz +princess09 +wildfire +messiah +rajkumar +buddie +matilda1 +snoopy123 +dagger +pudding1 +twisted +dell +pretty12 +654987 +murcielago +babygirl9 +penis69 +818181 +mypass +pasword1 +guerrero +vijaya +ijrjkfl +kolawole +rosemarie +chihuahua +money4me +crazy2 +bryant24 +butterfly8 +architect +sabbath +junior2 +kakashi1 +nicole22 +june +topcat +lorena1 +mocha1 +hooker +glasgow + +louie +wright +july22 +juanita1 +pancake +yummy +cesar +hilary1 +1superman +camera1 +clara +1qazxc +palmtree +mikejones1 +cristi +203040 +gordo1 +malik1 +070809 +tricolor +rockstar12 +polaris1 +loretta +kasia +theatre +пїѕпїѕпїѕпїѕ +alexis09 +sexygurl1 +monty +1515 +password01 +bigcock +maricel +july14 +sailboat +ste +kkk123 +millenium +nolove +1nigga +varvara +dollars +guess +darklord +history278 +gfhjkm1 +olawale +1961 +123a456 +floppy +xbox +printer1 +topper +naynay1 +tototo +2011 +liverpool +chobits +lupita1 +brazil1 +jesus33 +march21 +tango +nickjonas +baili123com +987654321q +koolaid +patriots12 +midget +pioneer1 +march18 +1234ab +angel17 +gunit +hottie13 +peterson +hustler +jimenez +narayana +nicky +alliance +rossella +1000 +denden +phillips +dynasty1 +texas123 +sonic123 +youssef +windsor +uganda +ibanez1 +michael5 +craig1 +softball3 +darling1 +yoyo123 +hilton +password77 +snapple +bitch22 +traktor +pooh12 +420weed +moneymoney +peachy +1chance +dark +feather +july12 +friends12 +jesus11 +emachines +usher1 +mirror +0000001 +fuckyou8 +wedding1 +1hotmama +kavita +laurita +butch1 +malibu1 +fireblade +pinky123 +pedro123 +seven77 +adebayo +familia1 +d123456789 +198000 +partizan +futurama +april18 +mygirl +dayday1 +jktxrf +polly +myspace200 +deerhunter +love1 +moremoney +chennai +lover13 +yellow11 +alondra +dkflbr +pr1ncess +tango1 +kool +mymusic +miamor1 +olesya +password16 +hamburger +jonny1 +matthew3 +1234567b +molson +amsterdam1 +solrac +1212123 +august13 +nssadmin +question +june18 +greens +mylinkedin +itachi +kimberley +666555 +sun +chippy +lottie +qwertzuiop +couponsc10 +buster11 +june25 +moonshine +jazmin1 +ludwig +110017 +666333 +nana12 +09876543 +kalpana +amor123 +boobear1 +mattie1 +mimimi +dontforget +audia3 +friendofemily +darlene1 +zebra1 +lance1 +baller12 +allan +bloody1 +helen1 +shaolin +nutmeg +marie2 +nike123 +jose13 +saturn1 +senior07 +wagner +diego123 +sf49ers +family7 +italian +cruise +philips1 +jack1234 +mikaela +skywalker1 +cupcakes +barselona +piolin +devilmaycry +santa1 +dolly +kronos +y123456 +sony +456258 +qwerty21 +mickey2 +holyshit +doodoo1 +19283746 +alexey +852258 +bumbum +photo1 +jamjam +sriram +tekiero +seven777 +matt12 +8phrowz624 +converse1 +savanna +joshua11 +future1 +startrek1 +pimping1 +sonia1 +clemson +francy +photos +guinness1 +dayana +sixteen +irishka +ad123456 +h12345 +1daddy +muhammed +athena1 +mac123 +thegreat123 +iluvme1 +onetwo3 +raiders13 +crossfire +lkjhgf +meagan +147896321 + +basketball1 +impossible +beverly1 +shadow7 +optimus +elefant +budapest +chris3 +zyjxrf +suzanne1 +pontiac1 +ralph +number11 +123qwert +blackhawk +johann +jobshop2002 +babygirl19 +heartbreak +bossy1 +12348765 +promise1 +kosova +amigas +june20 +ballin23 +ezekiel +lonestar +fisher1 +august23 +lov +boobear +patton +password33 +lobster1 +2gether +alfredo1 +++ +22 +chris14 +radhika +alvarez +loveless1 +green5 +familyguy +cerise +cthtuf +superman23 +robinson1 +sinner +israel1 +ichigo +children1 +pretty123 +tortuga +volvo +kaka123 +grenouille +kawaii +dragon22 +ashley7 +laptop1 +monkeyboy +pokemon11 +patty +tommaso +desmond1 +foobar +darina +loveme! +liverpool9 +kkkk +ralph1 +sam12345 +puppydog +espoir +brandon3 +??? +remote +cachorro +2babies +fabien +qazqaz1 +german1 +fabienne +meme123 +layla1 +4444444444 +lollollol +valley +poppy123 +555888 +hhhh +clouds +macarena +a7777777 +slimshady1 +speed1 +qwedsazxc +12345678m +kaitlin +ladybird +myspace21 +lucifer666 +root +zxc +112233q +cheers +atomic +angel09 +wolfie +420 +trojans +19191919 +2wsx3edc +oktober +shweta +bmx4life +canadian +tigger11 +khadija +dolapo +sdfsdf +3odi15ngxb +godlovesme +latino1 +333555 +trinidad1 +dante +idunno +lauren12 +1q2w3e4r5t6y7u8i9o +terrell +asshole! +love28 +open123 +edwin +class07 +1122334 +240 +francisca +mia123 +anthony5 +lipstick +hotpink +meow +teamomucho +not4you +jefferson1 +anthony13 +natalka +nebraska +110119 +today +lemon +2lovers +maimai +december25 +nomore +6543211 +jasmine3 +люблю +che +blaze +poohbear12 +kyle123 +sparks +1love1 +zxasqw +naruto13 +009988 +nastena +986532 +babes +france1 +tecktonik +hanna1 +passwort +august21 +159357456 +rainbow2 +filomena +ilovemysel +sasuke12 +tolkien +123123123a +iluvme +evil666 +clinton1 +lucero +river1 +xtreme +mylove2 +petrov +morgan12 +adrianna +redroses +person +simba123 +1mommy +george +25800852 +iamthe1 +magpie +football08 +player2 +zzzzz +1pussy +1231 +cool1234 +20122012 +ghbywtccf +trenton +april26 +transformers +smitty1 +s1234567 +bigsexy1 +master2 +nicole14 +coltrane +taylor13 +october13 +951159 +k123456789 +millions +pentium4 +marija +4everlove +angelita +musical +majestic +raffaele +ruben +surenos13 +looking1 +0000007 +longhorn1 +j1234567 +sexual +sveta +fucker2 +bonjour1 +hinata +dani +1secret +medusa +1melissa +minicooper +love100 +alfred19 +595959 +jansen +123456789i +idontcare +nextel1 +welcome123 +ukraine +red12345 +techno1 +april25 +supermario +joejonas +westcoast +horney +penelope1 +190 +harley2 +party +fkbyjxrf +kissme123 +megatron +money101 +qazwsxed +393939 +twiggy +steven123 +cheeky +dilligaf +goldstar +conejo +nicole10 +qazxcv +killer5 +bosco1 +nwo4life +hottie11 +78963214 +goliath +april19 +132132 +money22 +klaudia +123698 +baller3 +jackson2 +march24 +love92 +loco13 +170 +candygirl1 +musicman1 +matthieu +luigi +damnit +1111111a +philip1 +dee123 +strider +andrea123 +dwayne1 +powerful +althea +abc123 +cordoba +fuckoff123 +brandon7 +guatemala1 +richmond1 +mmmm +candycane +56565656 +melo15 +cheryl1 +margaux +james3 +diamant +florence1 +geneva +march10 +++++ +kingfisher +gfhjkmgfhjkm +tennessee1 +suicide +phillies +ohmygod +pathfinder +august22 +cucumber +jay +carter15 +1959 +1fucker +drakon +stinker +marseille13 +today1 +123456qaz +carrera +cococo +snow +asdfghjk1 +chase123 +ginger2 +capital1 +playgirl +abby123 +valerio +susanna +minouche +sonny +tanya1 +180 +bluesky1 +malena +karthik +daddygirl1 +flavia +football33 +123zaq +159852 +pepita +mushroom1 +jackal +mikayla1 +june19 +tmm +poop1234 +avalanche +princes +carpenter +yourmom2 +bermuda +deutsch +garnet +charlie01 +forgot1 +jethro +samurai1 +mckenzie1 +prince123 +zodiac +kimmy1 +cdtnbr +supernatural +ferguson +197777 +novembre +eliana +deskjet +mazdarx8 +123456798 +weare138 +zero +genius1 +tits +killer69 +blaze420 +pooh123 +money10 +yesterday +chris5 +++++++++++ +r1cd38d +mamacita +rosemary1 +jordyn +clancy +nicole23 +maxine1 +moimeme +freebird1 +753357 +charlie7 +radiohead1 +obiwan +april28 +topher +rock12 +really +thomas11 +myspace14 +indya123 +intruder +fabulous1 +bear12 +crimson1 +justin13 +ewanko +edgar1 +curious +fuckyou9 +fucklove13 +shilpa +chelle +959595 +enter123 +17171717 +turtles +rahman +running1 +1957 +fiorentina +topdog +reddevil +monkeyman1 +roswell +hahaha123 +gymnast1 +capoeira +condom +paul123 +narnia +20082009 +ferreira +julia123 +belinda1 +knowledge +money09 +powell +vasilisa +halima +tinkerbel1 +killers1 +july15 +bitchy +superman11 +kennwort +lukasz +333999 +e3r4t5y6 +anders +candace +blue99 +trains +daniel10 +bombay +sonnenschein +joelle +goaway +bonjovi1 +asshole69 +computador +sheena1 +user888 +alex22 +ddddd +любовь +chris22 +football6 +hopper +lespaul1 +1chicken +tralala +ihateyou! +260 +geminis +jan +marlene1 +archangel +criminal +131420 +qwerty23 +36mafia +artist1 +balla1 +chris21 +virgo +none +. +cash +bacon1 +7758520 +corleone +828282 +aa +oreo123 +100500 +romance1 +june27 +florin +seven11 +master +borabora +b123456789 +000777 +qwerty. +princeton +flight +123q123 +frisco +money13 +stephan +cesar1 +america2 +pink1234 +tennessee +madagaskar +cartoon1 +jonjon1 +rainbow7 +121234 +slut +margarida +darrell1 +qwerty0 +afrodita +nfytxrf +wazzup +a1111111 +hey +caleb +f12345 +tommyboy +march25 +nicole +222111 +crevette +maggie11 +daniel +loveable +hotshot1 +elwood +charmaine +saxophone +lover101 +oranges1 +9876543211 +160 +misfits +dynamite +a121212 +asdfjkl; +michael +password18 +expert12 +emerica1 +pimpin69 +moskva +100484 +boobie +telephone1 +norbert +annaanna +purple! +shankar +iloveyou16 +cathy1 +sinbad +hannah +milkyway +l6ho3tg7wb +love05 +ne1469 +manhattan +sanders +froggie +sugar123 +1234567d +underoath1 +hazel +karen123 +gmoney +nemesis1 +expert +555555555 +april29 +gamecube1 +angel666 +joshua +babygirl20 +aurelia +tartaruga +momanddad1 +craig +sample123 +libby1 +werwer +lingling +cutiepie12 +presley +bam123 +hihi +sharpie1 +hejsan123 +gribouille +171204jg +lol101 +multimedia +george12 +srilanka +austin01 +misty123 +computer123 +bitch7 +miami +patrick2 +erin +alex14 +mitch1 +krishna1 +edward12 +krissy +priscilla1 +boobie1 +louisa +malinka +211314 +121212q +pete +ohyeah +5482++ +steven12 +666666666 +zzzxxx +minnesota +emanuela +severine +kassandra +012345678 +serendipity +ashley3 +meatloaf +miguelito +cookie11 +souris +sweetlove +colocolo +havana +annie123 +boxing1 +princess19 +1234567k +physics +mamasita +infinity1 +asasasas +boyfriend +camper +cobain +karma1 +shiva +lolalola +harris1 +panic! +dontknow +1dragon +cunt +happy7 +sexybaby +scream1 +niklas +alexis2 +yellow5 +coolkid +poiuy +eloise +jehova +q111111 +eugenia +berenice +1213 +400101 +shiloh1 +undead +polpol +pepper01 +654321q +trigun +angels2 +sexybabe1 +august14 +love2love +dupa +bigboobs +kasia1 +olumide +147 +boomboom1 +victor123 +loser5 +wz362308 +summer2010 +henrique +aggies +12345678900987654321 +nokia5300 +empire1 +bighead +mahalkita1 +terminal +hello2u +diana123 +divorce +dinara +blanche +alcatel +premier +gideon +258741 +lisalisa +q1q1q1q1 +chino1 +march14 +ranetki +1958 +chelsey +hockey10 +checkers +m1chp00h +hopeful +mylove12 +maggot +sanjose +angus1 +pink10 +lovehate1 +fuckoff69 +qwerty3 +baptiste +67mustang +zebra +password12345 +crackhead1 +gbhfvblf +allmine +ocean +bdfyjd +moocow1 +yjdsqgfhjkm +ashanti +zimmer483 +nico +june30 +ale123 +zzzzzz1 +mexican13 +samsara +amanda11 +bigmac1 +gayathri +lion +diane1 +purple5 +kingpin +sneaky1 +sinaloa1 +rookie +1onelove +myspace6 +goodday +marc +steve123 +imesh +toronto1 +789123456 +pretty2 +champ +loveyou12 +cookies2 +haley +corina +mikael +starwars3 +pepsicola +numero1 +kylie1 +stalin +lunita +berry1 +babygurl2 +o123456 +johanna1 +coralie +jordan23 +gbcmrf +poppop1 +tajmahal +forward +12369 +godsmack1 +josephine1 +bassman1 +tripleh +woohoo +satish +9562876 +cv1230 +lotus +shitty +1357908642 +fabiana +jason12 +manzana +alpha123 +voodoo1 +hotchick +million1 +salazar +987412365 +benjie +nicole27 +momoney1 +jehovah1 +jeff24 +ulysse +oliver12 +zxcvzxcv +james11 +sander +1qaz!qaz +rockets +milka +whiskers1 +service1 +jesus10 +pharma +science1 +snatch +hello123 +kool123 +godson +bjk1903 +marty +linkedln +789456a +abcdefghi +gwapako +sexy24 +smoker +annabelle1 +iloveyou01 +elena1 +cute12 +libra +3456789 +devin +juice +death123 +74107410 +nigga12 +football32 +pink14 +tina123 +kayleigh1 +khalil +sofia1 +aubrey1 +dbnfkbr +20042004 +bakugan +malboro +claudine +april27 +seeker +orange11 +neopets12 +firenze +medion1 +summit +november19 +martin +tangerine +hello13 +lilbit1 +brennan +laurel +savior +truck +190986 +mmmmmm1 +avatar1 +1233210 +soccer99 +imthebest +azertyu +juice1 +blue14 +alex21 +syracuse +loser! +zerocool +wolfpack1 +mariela +regine +fuck1234 +blackcat1 +scorpions +blanco +detroit313 +iloveu3 +1231230 +fucked +denmark +c123456789 +woshiyazi +asdfqwer +henry123 +july10 +anthony +ghbrjk +giorgi +spikey +green22 +memories +shalini +zsazsa +mrf11277215 +sanandreas +lucky3 +koko +richard +black13 +silverado1 +journey1 +browns1 +quincy1 +passer2010 +zalupa +coleman1 +newyork2 +samantha2 +operation +one2three +kiara1 +quantum +vegas1 +homerun +0o9i8u7y +popcorn2 +1q2q3q4q +wanker1 +lambert +puddin +rob123 +302010 +sapphire1 +yeshua +military +magnolia1 +jimbo1 +iluvu +zzz123 +sunshine11 +moncoeur +spoiled1 +racoon +july13 +july16 +tree +mama11 +300 +killme1 +avril +iloveindia +luckyme +obama08 +for +honey2 +poupette +ramones1 +teodoro +virus +candace1 +etienne +198500 +nookie +bababa +afrika +rochelle1 +ocean1 +western1 +peaches2 +vince +guitar123 +lili +marek +xanadu +breezy +lamar1 +keystone +jonny +goodgod +t: +dfa72dfj +cbr600rr +birillo +neelam +pissoff +rasta +hellyeah +jordan22 +player12 +poptart +benson1 +a987654321 +goldwing +camel +justin +boots +mykids1 +the123 +calypso +???? +superman13 +bobcat1 +vampir +whoami +nitram +football55 +darthvader +superman5 +capital +memorex +o +roland1 +torres1 +avery1 +herman1 +samsam1 +trustnoone +poohbear2 +robert01 +270 +bonkers +notredame +fucker! +love666 +july17 +glenda +playboy2 +fuck13 +ffff +julio1 +198600 +karaoke +bombom +joyce1 +ann +chunky +carla1 +master11 +liverpool2 +maximka +020 +felix123 +corsica +12qwerty +dentist +savanna1 +nigga2 +ethan123 +nadejda +challenger +dialog +coolness +andrew13 +madison3 +biatch +villanueva +ademola +flamingo1 +spidey +selene +fuckyou23 +cougars1 +ellen +catcat1 +crack1 +chopin +agatha +carmine +resume +moses1 +plumber +faker1 +ventura +truck1 +222555 +848484 +ilovejosh1 +electric1 +artur +213213 +rasputin +donuts +romario +zoloto +yop7s55 +00000a +1qaz2w +nicole! +1123 +drama1 +fitness1 +carpet +pppp +purple4 +shivani +falcons7 +bluedog +pallavi +123456789a +romantic +martine1 +personal1 +doktor +waffles +atlantic +fantomas +olimpia +flipflop +marmar +tazman +scott123 +baby18 +livelife1 +driver1 +number10 +birmingham +aladin +oceans11 +limpbizkit +celtics1 +waterpolo +matisse +number8 +assassin1 +sashka +mister1 +brady1 +357357 +number4 +momof4 +lilly123 +moonbeam +october23 +12345y +machine1 +garage +v12345 +paulina1 +critter +159874 +picture1 +hummerh2 +yellow3 +oblivion1 +918273645 +werty123 +sprint1 +smokey12 +123xyz +indians1 +express1 +123123456 +momo123 +tatarin +alex23 +and +october12 +aurelien +leonidas +hip-hop +hotchick1 +funfun +2012 +jjjj +chocolate! +june29 +alphabet +hottie01 +declan +slipknot666 +tink123 +armageddon +chelsea2 +q12345678 +anonymous +diciembre +hotsex +1234567t +03082006 +ashley21 +y +fun +brando +bobafett +hooker1 +android +helena1 +polly1 +hello22 +dominick +winners +iloveyou0 +cosita +sylvain +doodles +loveable1 +cosmo +kenny123 +yfcntyf +qawsedrftg +tania +oxygen +196 +joseph2 +aabbcc +123qqq +march19 +salamander +liliana1 +integra1 +fuckers1 +d +deacon +nigger2 +anthony11 +sheryl +iloveyou +navarro +alfie1 +1955 +aaaaaaaaa1 +soraya +snoopy12 +football44 +h1xp2z2duk +poopy12 +easy +4wheeler +pompey +loveforever +09090909 +tigger13 +90909090 +myworld +bird +mickeymous +disneyland +gonzalez1 +rugby1 +blueboy +jagger +callum1 +marcel1 +monkey99 +yogibear +rhfcfdbwf +golfclub +ultras +saratoga +bigben1 +brittany12 +c +skate12 +ollie1 +goodtimes +breezy1 +smokeweed1 +sausages +aaabbb +karla1 +1357 +because +aurora1 +chelsey1 +yangyang +newport100 +pizdec +junior13 +rusty123 +a12345 +krolik +sexxy1 +duck +frisky +reddragon +rosie123 +armand +e23456 +july11 +asdasd666 +barracuda +kids +reynolds +godbless1 +alan +amizade +fingers +lauren123 +p0o9i8 +ronron +carlos13 +perrito +x +austin11 +palmeiras +tessa1 +dejavu +crawford +1jessica +roadking +3edc4rfv +excellent +maggie +blessed2 +chi +molina +wetpussy +loveit +audia6 +smirnoff +ruben1 +football25 +browneyes +280 +princess18 +gmoney1 +634142554 +esmeralda1 +football15 +daffodil +starwars2 +bruiser +carlito +bigboy2 +idk123 +flavio +astonmartin +georgie1 +william +dingdong1 +change1234 +resetme +i123456 +bla +78945612 +tigger22 +queenie1 +angel24 +gabby123 +aaabbb2 +shadow3 +cfvceyu +stone +gollum +march26 +october21 +gustavo1 +charmed3 +twinkie +preacher +buster +ilove2 +star22 +piotrek +baseball25 +jennifer2 +tupac +clemence +servus +cortez +hammer123 +tracey1 +fire123 +lilbit +anna12 +kavitha +abbey1 +asdf11 +bubba2 +bigboy12 +s +kamil +thethe +shasta1 +dogs123 +master01 +chelsea12 +prettyboy +asawako +bluestar +prosper +bullseye +001001 +pizza12 +gerald1 +farhan +lovegod1 +biteme69 +typhoon +13572468 +145632 +aleksei +camila1 +timber1 +randall1 +qwertyuiop12 +connect1 +hugoboss +tim +whocares1 +webmaster +march31 +sexyass1 +pimp01 +paranoid +brett1 +223456 +cameron2 +crazygirl1 +leopold +aqwzsxedc +1stunna +john11 +estefania +lucky11 +elvis123 +riverside1 +janelle1 +akira +target1 +blood123 +schule +cleopatra1 +another1 +q1q2q3q4 +chocolate7 +bobbie1 +zephyr +elsalvador +marisol1 +cruzazul1 +9876 +needforspeed +model1 +gypsy1 +brewster +gotmilk1 +thalia +duchess1 +arcangel +mic +chica1 +jfgvcqbuzug +wewewe +jazzy +desember +blood4life +film@123 +chris18 +maiyeuem +backstreet +jonathan12 +grumpy1 +austin2 +bella2 +santa +droopy +myszka +wilfried +apollo11 +gtnhjdbx +sekret +1hello +gagaga +august18 +fabian1 +morgan123 +smudge1 +dupa123 +lexor123 +197 +august19 +951951 +biologia +march16 +july24 +jesuscristo +maddy +new123 +sharky +sienna +valhalla +matty1 +varsha +mickael +ana +double +collin1 +asshole3 +bastian +ashley! +august16 +sarah12 +intrepid +secreto +rencontre +iloveyouba +westside13 +artem +werty1 +tahiti +carlitos1 +bollocks1 +271282 +march27 +badboy123 +1qaz2wsx3edc4rfv +michaela1 +clueless +dodger1 +bigmama +sexii1 +blues1 +hitler1 +blink123 +cosworth +hunter +963369 +shevchenko +lovely +shreya +ant123 +william12 +4jesus +boeing +zxcvbn123 +stimpy +slovensko +123admin32 +cody12 +lady123 +ctrhtn +4545 +1111aaaa +doobie +wireless +miles1 +carine +rhfcjnf +money08 +capucine +eddie123 +9874123 +topbutton +bitch21 +stefan1 +494949 +gucci +supreme +reunion +magical +piccola +agustina +nenita +trust1 +kfgjxrf +shadow22 +migrationschool +godwin +dddddddd +letsgo +tricky +78787878 +myriam +noemie +mistral +vinicius +aassdd +mischief +oreo +gary +calculator +kat123 +198400 +abc123! +highschool +mustangs1 +fishy1 +gwapoako +mudvayne +celtic67 +daisydog +niners +radical +philipp +orange3 +mongoose1 +jon123 +rivers +stewie1 +jaime1 +cookie13 +qw1234 +numberone +killer23 +hazel1 +weedman1 +lovely69 +tootie1 +asdfghjkl +357753 +miles +purple23 +kazantip +bears +gabriella1 +moussa +potato1 +paper +melissa123 +massage1 +matthew7 +hellboy1 +pepper11 +marron +loveme4 +stasik +blue15 +fyfnjkbq +bitchass +march20 +mikey123 +mars +667788 +olalekan +ksenia +zidane10 +cuteko +1956 +july27 +payton34 +nuvola +hockey7 +august15 +peanutbutter +hillbilly +citizen +gangsta2 +insomnia +surabaya +rocketman +abraham1 +12345687 +090790 +baby17 +genevieve +hunter3 +dominik1 +butterfly6 +jesus1 +loveu4ever +1moretime +maminka +baggio +formula +120679 +japanese +heka6w2 +boob +march28 +overdrive +919191 +fordfocus +14789 +wiggles +michael4 +crazy13 +harlem1 +wally1 +tipper +123wer +august25 +celtic123 +babygirl8 +money21 +poupee +1234567890-= +a666666 +espana +angelic +keepout +superman! +1234567u +fxzz75yer +boxer1 +1gangsta +my204856 +edwin1 +engine +sunrise1 +michelle3 +vfntvfnbrf +chocolate3 +119119 +d4 +shaun1 +sunsh1ne +amanda01 +deathnote1 +timtim +grapes1 +doomsayer.2.7mords.vv +profile +qwerty88 +nipples +013579 +ashley14 +ggggggg +love93 +zzzz +jessica11 +gorillaz +bolton +shashi +cuties +mother3 +smarties +peanut01 +dummy1 +bigbird1 +lexus1 +greeneyes1 +lolololo +thiago +play +elizabeth +lbvjxrf +ou8122 +armyof1 +david13 +august28 +qwaszx123 +emerson1 +aventura +bowser +aze +poodle1 +depeche +redfox +leigh1 +godblessme +kickflip +yahoo12 +southpole1 +caitlyn1 +capone1 +sancho +augusto +qwezxc +cheese3 +hithere1 +december19 +oldschool +blogs123 +nokia6600 +drag0n +contrasena +reglisse +babies1 +getajob +david01 +awsome1 +bigballs +justin10 +charity1 +my.space +casper123 +trustno1 +delilah +avenger +charlene1 +200200 +danny12 +lenlen +zelda +iiiiii +qaz12345 +misha +chiquita1 +danielle12 +1225 +juliana1 +metalica +noviembre +music! +burger1 +dani123 +jesus13 +qw3rty +quiksilver +bernie1 +july18 +justin3 +tiburon +christian +777777777 +chris15 +665544 +october22 +qwe123asd +dragon10 +joyful +rasta1 +babygirl18 +marion1 +melbourne +mommy4 +redhot1 +ashley16 +smokeweed +chipmunk +ddd +pokpok +rubber +hockey13 +ludacris1 +pereira +poncho1 +woaiwojia +asdfgh01 +gatorade +sepultura +sheba +123odidol +michael! +molly12 +gaetano +homie1 +redfish +sixers +mark12 +valery +love03 +jeff123 +pancake1 +hilaryduff +01234 +preeti +rosanna +maemae +princess07 +liquid +naruto10 +caracas +divina +riverplate +virgo1 +britt +iriska +nathan01 +july28 +usher +sunnyday +vika +1hunter +jackie123 +tanker +october7 +lester1 +canabis +magician +dada +chinita +heyheyhey +nicole16 +765432 +qwer12345 +makemoney1 +passme +lifetime +mmmmmmm +intermilan +sexygirl12 +ggggg +bigmama1 +ljxtymrf +zzz111 +sooner +keisha1 +tictac +ahmed123 +chick1 +subway1 +18436572 +whatthefuck +babygirl07 +anthony01 +obelix +samantha +crocodile +game +yourmom! +anastasia1 +luis12 +rebekah +1234567891011 +candyman1 +nice +papa123 +broncos7 +pillow1 +windowsxp +marty1 +chicken! +kristy1 +summer! +19621962 +thompson1 +alexan +love94 +dave123 +yahoo! +freestyle1 +mail.ru +mahalkoh +peace2 +purple01 +fake +shelley1 +200991 +lover3 +lucky5 +universal1 +madinina +jordan21 +manunited1 +karima +webcam +october2 +198700 +aaa123456 +dynamo +molly2 +toby123 +boyboy +social +tribal +bigboi1 +killbill1 +scoobydoo2 +hello12345 +pink23 +asdzxc123 +jjjjjj1 +01011990 +dawn +chinedu +fucker69 +him666 +888 +привет +tornado1 +dinosaur1 +julio +rodina +gatinha +orion1 +mike13 +777333 +050 +dogcat +dddddd1 +killer3 +qaz741 +xblhintb9w +hhhhhhhh +jelly +akshay +telecom +patrick123 +babyphat +olamilekan +lancaster +charley1 +rhonda1 +silent1 +r9lw4j8khx +bastardo +chihuahua1 +guitare +camaro69 +revolver +giselle +rocco1 +homero +matheo +qaywsx +ilovealex1 +freedom7 +smokey123 +nike23 +zxczxczxc +groovy1 +123546 +muriel +whitesox +merda123 +vortex +daniel7 +goodgirl1 +rfhnjirf +salut +reese1 +brett +barry1 +vittorio +cupcake123 +bigguy +caonima +swords +135135 +vadim +chantelle +marquis1 +yellow22 +greentea +ledzep +ilovenick1 +harley +huskies +darnell1 +starfire +hello0 +starcraft2 +nibbles +biohazard +fuckmylife +poison1 +dead +goodluck1 +henderson +sal +icu812 +friends3 +yvette1 +tatata +nadine1 +redwine +forgotten +hottie5 +emperor +meatball1 +1killer +macaco +sonata +natascha +sanjana +norway +jill +bullfrog +murzik +frozen +edgar +bingo123 +melissa2 +sexybeast +elisha +gansta1 +12131213 +dallas12 +rusty2 +constantin +skate2 +bettina +leanne1 +deluxe +holidays +mike22 +mustard +camping +pepe +chaser +penny123 +sport +kickflip1 +popcorn123 +arschloch1 +atticus +sandra123 +kisskiss1 +titi +rick +spotty +bdfyjdf +speaker1 +sherwin +snapple1 +naomi1 +gggggggg +rocco +cats123 +solaris +mv46vkmz10 +kingston1 +zxcasd123 +tantan +common +people123 +july29 +030201 +james01 +tmnet123 +studio1 +michael8 +tequiero1 +albania +square +thankyou1 +333666999 +wwwwwwww +petra +andrea12 +jimbo +napoleon1 +august17 +raquel1 +princess6 +du8484 +holyspirit +need4speed +cherry2 +pumas1 +friends4ev +redrose1 +alena +chunky1 +markiz +apples12 +abc456 +bumblebee1 +bradpitt +zzs000000 +cam +chris17 +xtseo2011tdx +patricio +nadia1 +chris7 +redline +peaceful +kayla12 +poi098 +july19 +luisito +cruiser +goodboy1 +princess69 +my1space +chicken3 +qqq +1223334444 +honeys +samuel123 +sta +ripley +bigbear +jester1 +ambition +mommie1 +kenshin1 +290892 +trucks1 +dayday +clever +bitch6 +bronco1 +freeze +qwert5 +lovelovelove +hola12 +narayan +art +caralho +jessica01 +access1 +mobile1 +gareth +charlton +lfitymrf +jarule +eugenie +grateful +jonathon +1020 +deepika +vova +snakes1 +120279 +newpass1 +superman10 +bball11 +sunlight +vanessa123 +august10 +triplets +malaka +track1 +dammit +sicilia +rhjkbr +colin1 +metalgear +blackman1 +tim123 +hansen +july25 +cherries1 +gutierrez +hellomoto +fucker123 +lovers123 +graffiti +??????@mail.ru +silver123 +magenta +bitch14 +elizabeth3 +konrad +bryant1 +saraswati +martin12 +patryk +asdfjkl1 +maya +baby06 +password55 +1babyboy +chavez +knuckles +bouncer +152535 +lizzy +amber12 +somebody +tabby1 +-deleted- +batman11 +nirmala +jungle1 +biloute +chandu +falloutboy +pancakes1 +rugby +letmein! +lilith +246800 +all4me +kkkkkk1 +bud420 +1qw23er4 +zaragoza +tamtam +3angels +alfred1 +doghouse +6358986 +angel777 +remington1 +ilovemybab +aussie1 +bitch09 +16051980 +aguila +marquis +iloveboys1 +magda +baseball17 +spongebob3 +zero00 +*123456 +jesus +river +twelve12 +gitara +marsha +222222a +blowjob1 +bisous +asdfg12 +meister +sukses +bball3 +ilovemike +admiral +scout +april2 +111122 +pimpin101 +awesome123 +2345 +google2 +kansas1 +198200 +kamala +costarica +darryl +apple3 +alohomora +destiny123 +199999 +titleist +fuckyoubit +reading1 +hastings +piano1 +18181818 +shearer9 +!qaz2wsx +fuckyou420 +fuckyou21 +sasa +adadad +georges +torrent +spartacus +number23 +august24 +brad +mad +pooppoop1 +michoacan1 +chivas9 +fantastic4 +truman +956208q +alone +bruiser1 +cristiano7 +iamgod +pixie1 +warning1 +gustav +qwerty00 +redhat +newzealand +hotwheels +6strings +amanda13 +lakeside +colette +welkom01 +brandon5 +french1 +mamma1 +brandon13 +fk3456abc +december10 +warhammer1 +niggas1 +shark1 +007bond +151617 +johnathan1 +12s3t4p55 +fantom +tyuiop +030 +lol123456 +atreyu1 +bennie +hitman47 +timoxa94 +king11 +cyclone +1ashley +greenbay1 +ashley22 +worship +190494 +yousuck2 +davis1 +showme +gregorio +stupid2 +walkman +iloveme12 +anthony4 +daniel22 +charli +penguins1 +miriam1 +colby1 +yfz450 +elisabetta +siemens1 +pppppppp +mommie +cerberus +123147 +kobe08 +fergie1 +nautilus +compton +1friend +lovable +jerry123 +dwight +123abc456 +marina +thesims +122334 +picasso1 +crazybitch +playtime +098098 +bluemoon1 +julius1 +1shadow +0o9i8u +midnight12 +ssssssssss +ximena +tessie +007007007 +rotterdam +mayhem +nosferatu +yellow7 +westlife1 +ramazan +purple10 +evelina +compaq123 +stupid123 +lulu123 +mandy123 +jesus101 +heather2 +butch +dad +space123 +angel1234 +gfcgjhn +dreaming +rapper1 +america13 +collins1 +dmoney1 +stone1 +wer123 +butters +gthcbr +sunshine01 +rob +tinker2 +lfybbk +040506 +angel06 +august31 +dragon3 +calibra +musiclover +husband1 +gu1tar +allahuakbar +camelia +bar +gunsnroses +feyenoord +99887766 +cheer12 +demon1q2w3e +zaq12345 +python +gatorade1 +howareyou +olanrewaju +james13 +123456789123456 +tresor +sassi123 +gofish +hannes +toutou +jessica! +lpl +president1 +gettherefast +a +killerman +roses1 +football07 +papichulo1 +heavymetal +minime1 +nina123 +garden1 +shivam +digimon1 +65mustang +julianna +april4 +solidsnake +tttt +pwtest +andrey +dasha +baller2 +112 +rugrats +floflo +png +dreamcast +u23456 +phoenix +partner +pepino +countryboy +farmer1 +ginger01 +honda250 +soloyo +sexy19 +cloud +hotmail123 +aishwarya +liverpool5 +southern1 +banana12 +guitar2 +milashka +aidan1 +345345 +bitches2 +football34 +ashanti1 +ashley10 +deusefiel +evolution1 +chestnut +heavenly +princess24 +devils1 +123123z +l +bubbles3 +secret2 +flores1 +florent +october11 +clementine +cousin +shauna +ilovematt1 +popstar +1223 +camara +anitha +dancer12 +dragon21 +liverpool1 +seahawks +kidrock +chevelle1 +sexy#1 +link123 +anakonda +scottie1 +puzzle +zero123 +maryland1 +campbell1 +dra +110018 +pimp4life +ksusha +maureen1 +butterfly9 +pommes +july31 +carrot1 +platon +geetha +geheim123 +andrew3 +jordan4 +vipers +hampton +no1knows +anusha +pink21 +shearer +find_pass +518518 +lover5 +sheridan +fiorella +homies1 +snoop +mommyof2 +3698741 +karolina1 +mcdonalds1 +christin +kitchen +mistress +kowalski +smokey2 +myspace4me +motherof3 +liverpool123 +diamond123 +chris16 +predator1 +happy3 +rfn.irf +april30 +tarheel +b +nicole5 +love2007 +123456789* +internazionale +bernice +000666 +daniel3 +852741 +tunafish +seahorse +sidekick1 +lovers12 +ramirez1 +jasper123 +fidelio +michael10 +smile2 +1234qwerty +sporty +asd666fds +hotty +salamandra +bubby1 +octavia +loveyou! +1235 +c00kie +pizzahut +goldfinger +bbbbbb1 +system32 +bball22 +bengals +hurley1 +love +jackson123 +walleye +dawson1 +carlton1 +01012011 +2twins +shahrukh +ananda +march29 +demon1q2w3e4r + +marie3 +baggies1 +method +october14 +bvp33w7epu +tracker +klopklop +gospel +pinkpink +monroe1 +morrowind +lordjesus +princess17 +dragoon1 +jackass123 +whitesox1 +clarisse +october15 +butters1 +princess20 +snowie +ruthie +ringo1 +chicks +masamune +alligator +kolbasa +vivian1 +balloon +nessa1 +love420 +rufus +sarasara +beloved1 +oioioi +mike69 +mygirl1 +1baseball +whatup1 +immortal1 +jordan45 +ankita +einstein1 +leonel +wert +mohamed1 +cutie13 +havefun +insurance +hottie4 +pink15 +krista1 +mandrake +taylor10 +zaqzaq +football. +carebears1 +football69 +denis1 +magick +magicman +apples2 +123454 +1flower +adrian123 +destiny7 +popo09 +789456123a +alianza +nicole15 +candela +beatrice1 +viper12 +shane123 +bigone +iloveme3 +snowy1 +maisie +players +watson1 +grant1 +1112 +stacy1 +3daysgrace +stuff +alex15 +bobby4 +rjhjdf +thisisme +octubre +kids123 +matrix123 +silver12 +eatme1 +19601960 +siobhan +azert +origin +68camaro +friendofjoan +mateusz1 +lululu +y23456 +paradis +gallardo +362514 +hellomoto1 +password45 +mindy1 +mel123 +1010101010 +bitch4 +doremi +victoria +dragon99 +poop69 +mark_963 +loser101 +tereza +&hearts: +green23 +jalisco1 +bounce +gayatri +deadhead +pistache +embrace +taylor3 +saretta +roberta1 +rbotmvz954 +tortue +gamer +titanium +lennon1 +harish +lara +5plk4l5uc7 +jim123 +nellie1 +magnum1 +raistlin +nfy.irf +alisa +dakota12 +leroy1 +jade123 +maria13 +aramis +wareagle +continue +grandad +090 +uzumaki +eistee +stewart20 +fraser +159357a +taylor +portable +tunisie +goofy +avinash +painter1 +23 +jamesbond1 +stuart1 +bearbear1 +a55555 +0007 +martini1 +myspace06 +eri +hey12345 +ballerina +yourgay1 +rashid +tata +kaitlin1 +verizon +aloha +pandabear +hansolo +cornwall +qwerpoiu +july20 +beretta +nanny1 +b-ball +bobdylan +quattro +weronika +21 +1qaz@wsx +poiuytre +omar123 +sixty9 +lovesex +alexia1 +147258369a +1nicole +starwars12 +jayson1 +samsung2 +reliance +juliana123 +eternal1 +chuckie1 +wisconsin +adrenalin +jimmie +belinea +squirt1 +notredame1 +jessie123 +blackout +myboys2 +killzone +bangkok +liz123 +animation +cocaine +bigfish +alyssa12 +mac +ola +o23456 +vasiliy +shakur +jaime +kkkkk +nokia5200 +booster +flo +twinkie1 +sisters1 +gunther +forrest1 +thebeatles +marie13 +catman +ruby123 +singing +12346789 +fatty +children4 +nickolas +bertrand +diva123 +102030405060 +hannah10 +kat +windsurf +rerere +vera +hockey123 +xiaoxiao +bandit12 +youknow1 +combat123654 +p4ssword +coccinella +angell +superman123 +love32 +salasana +babygirl6 +vjqgfhjkm +queens1 +marimar +princess123 +555555a +bookie +slinky +whatever4 +class2010 +mustang50 +member1 +marie05 +bmw325 +herbert1 +fuckfuck1 +rfntymrf +5845201314 +contrase +nick11 +sophie12 +monkeyboy1 +serseri +suslik +doodlebug +555444 +public +tzir25l5kn +12345678d +3.1415926 +star10 +harekrishna +chingy +5x1cjdsb9p +whatever12 +monkey15 +schneider +vienna +marita +4girls +thailand1 +maserati +meandyou1 +rooney1 +july26 +777888999 +vivien +electrical +khaled +bacon +august26 +vintage +capetown +fuckyou0 +aliyah +bible +peterbilt +shazam +november12 +jacob12 +consuelo +senator +michael21 +qwerty1 +mel +grant +inuyasha12 +ddddddd +sheffield +softball5 +reno911 +omni +love96 +pegasus1 +squirrel1 +jaybird +snoopdog1 +jammer +nurse +gina +chad +pipoca +love90 +brandon11 +getsome +infantry +london01 +thematrix +1chris +perros +ohiostate +hugo +qwerty10 +richard123 +dedewang +rapper +sandwich +ashley15 +natasha +pigeon +lacrimosa +password25 +hello4 +30media +ilovemykids +punisher1 +cookie! +kitties +cocksucker +downtown +tundra +peace12 +pooter +137900 +diamond12 +lemons1 +dedede +whatup +combat +cvzefh1gkc +stronger +queenbee +chloee +doggies +filipe +coca-cola +pol +qwer1234 +richard2 +pimpdaddy +makaka +roxie1 +jason2 +wrangler1 +playstation2 +japan1 +terrence +tigger +macdaddy +tigerlily +1fptjtl919 +uzumymw +freedom123 +1234123 +hockey99 +justin21 +1dollar +blues +187187 +india123 +jesusloves +twins1 +west +q123123 +generation +rich +loveme22 +johnnydepp +sauron +madman1 +corentin +jackson +sheetal +abby12 +bubbles! +scheisse +niggers1 +softball14 +bart +robert11 +airplane1 +rescue +auditt +world +can +player123 +egorka +101090 +arod13 +heyheyhey1 +baltimore +lopata +kurtcobain +rocky12 +armani1 +cutie11 +bambi1 +jazzy123 +tatjana +edward2 +meenakshi +w1aubvoq +danish +surprise +mariners +040 +rachel12 +ottootto +bismilah +gwapoko +flatblocker +chocho +mustang67 +gaelle +sokolov +122122 +michael22 +dreamgirl +hottie69 +sharks1 +ann123 +algebra +barbie12 +rudolf +babyboy123 +checkmate +welder +skyliner34 +himanshu +merlot +lollol123 +aerosmith1 +llama1 +blaster1 +joselito +hunter5 +october3 +stuttgart +david11 +sylvester1 +centrino +zach +sex101 +060 +barry +hockey2 +pink16 +nik +realestate +romans +dodong +honolulu +nascar8 +bob1234 +blue44 +stoney +santafe +sergey +beamer +& +27081989 +918273 +sinatra +vietnam1 +1mustang +juju +longbeach1 +football99 +turtle2 +analsex +boss123 +guess1 +princess. +daughter1 +kirby +romane +charlie5 +camel1 +keller +lolol +julie123 +scamper +keywest +purple8 +vickie +jasmine7 +couscous +myfriend +cheese11 +miley123 +sally123 +1sexybitch +wasabi +skaterboy1 +carlos2 +trisha1 +noelia +butterfly5 +tenten +lynlyn +funtime +bitch08 +maxim +camion +linker +naynay +mickey01 +kamran +matematika +native1 +zorro1 +400064 +softball22 +ang +weather1 +eastside13 +ricky123 +camden +500500 +peach +tony20 +softball8 +nokia5130 +sony123 +bailey2 +12345x +brebre1 +justin22 +halo12 +birdie1 +poophead1 +asasas1 +forever123 +foster1 +iloveyou18 +antonina +sch +popopopo +heartless1 +wassup1 +trapper +blacks +1qazxsw +tiamo +7894561 +bobby12 +love66 +love95 +bubba12 +boyfriend1 +sahabat +august27 +bryce1 +nenette +demon1q2w3e4r5t +trinitron +iluvyou +property +italy1 +beebee +vacances +290 +ninjas +johncena12 +may +divine1 +devine +171819 +dundee +browneyes1 +korova +saopaulo +dfytxrf +junkie1 +weston +1jordan +1a2a3a4a5a +0147852 +101088 +tiziana +pistol +forgetit +nipple +gangsta6 +rafaela +putter +19 +antoinette +jeannie +hunter13 +proview +myspace201 +9958123 +sephiroth1 +active +dirty +chintu +asdfgh +bootsie +coolgirl1 +hello99 +pegaso +october16 +rita +010989 +paris123 +noah +newyear +godslove +carter3 +allie +junpyo +kimber +taurus1 +cullen +olive +lovejesus +harley69 +hej123 +lynette +500072 +roshan +1234as +emokid1 +titan1 +fiona +zaqxsw12 +annmarie +hockey19 +transport +unlimited +allyson +harvest +trustme +fyutkjxtr +iloveyou143 +surf +curious1 +tigers12 +cutter +musical1 +cowboys9 +island1 +aries1 +jordan14 +tink12 +fun123 +bastien +1954 +fcbayern +hot97hot +cesare +berlin1 +mallard +jessica1 +satan1 +2cxdn8s271 +grayson +vaishali +anamika +number6 +r123456789 +nike12 +saviour +kevin11 +????? +steph123 +fernandes +tigger3 +plasma +cheerleader +and123 +salinas +celticfc +gunnar +dougie +frodo +diehard +987654a +jim +stephanie2 +!qaz1qaz +520530 +march3 +concorde +12345six +edinburgh +community +johnboy +mouse123 +++ +static +slipknot12 +wheels +annemarie +omar +badboy12 +bra +mutter +happy5 +hungry +rockie +topgun1 +01234567890 +pimp14 +becca +loveme69 +1224 +chris6 +bball10 +riley123 +subaru1 +1234aa +foxracing1 +gravity +cancan +opopop +jj1234 +monkey. +sensei +j1v1fp2bxm +everlast +tiger5 +swallow +13141314 +seminole +fanny +marias +last +romana +misfits1 +sunshine13 +tommie +dragon01 +111777 +hunter10 +sternchen +silly +berkeley +eleanor1 +rb26dett +globus +favre4 +felipe1 +ernesto1 +nickel +kermit1 +ilovejosh +mazda +1234567r +purple21 +leedsutd +ilovematt +papaya +fragola +123lol +nokia3100 +1234567qq +marta1 +hannah3 +elizabeth7 +azerty12 +hudson1 +serpent +metallica2 +bangbang1 +yu5l97wk8q +qazxsw12 +1qwertyuio +dieter +yahoo2 +renegade1 +blackwater +nevermind1 +marielle +killer99 +bismillah1 +coolbeans +squash +yassine +daisy2 +matthew1 +doglover +harvard +cnfybckfd +gcheckout +hothot +historia +superman69 +samsung12 +chinna +fudge1 +alexis01 +hikari +124578963 +vader1 +ryan11 +bubble01 +username +976431 +thunderbird +nikita +idontcare1 +hopeless +getmoney2 +maomao +letme1n +looney +meridian +divorce1 +poopy123 +airbus +bigpimp1 +october17 +normal +fluffy123 +ball +mcdonalds +sport1 +123467 +cindy123 +psychology +123a123a +gordito +gamer1 +emanuel1 +miamia +black5 +12345zxcvb +ingodwetrust +hfljcnm +123581321 +poker +coach1 +catalina1 +nicole18 +prudence +cornelius +justin7 +mommy5 +russia1 +buddyboy1 +flowers2 +acc123. +1818 +brendon +messi +1baller +ola123 +colin +arcobaleno +masha +jjjjj +junior01 +doggy123 +iloveu7 +nat +nicola1 +morrison1 +catdog123 +lolipop123 +eraser +humberto +1apple +junior10 +brayan +butcher +orange7 +12love +cake +trident +blue45 +gracia +celular +titeuf +michael9 +mamadou +10101 +duke123 +linkedin1 +football77 +booker +rockstar2 +happyfeet1 +ib6ub9 +david3 +augusta +spaceman +flames1 +coventry +sdf7asdf6asdg8df +19611961 +successful +sunshine5 +mason123 +kevin2 +mysterio +blanca1 +ashley23 +nicole08 +12345asdfg +harlem +manning +libra1 +badazz1 +prince12 +hillbilly1 +anthony23 +ffffffff +colors +1212121 +1life2live +iloveyou24 +thecure +hiphop2 +1brandon +universo +honeybear +earth +babybaby1 +tempest +applesauce +hannah7 +cancer69 +estate +dragon23 +rememberme +1919 +zoomzoom +superman +goose +1peanut +tardis +abc1234567 +oceans +amylee +football123 +primus +bennett1 +call911 +bad +qpalzm +station +olaola +3babies +alanis +vikram +shotokan1 +nono +121213 +star14 +ginger11 +cvzefh1gkc +peanut11 +atreyu +mariella +champs +01091989 +krissy1 +austria +green4 +horse123 +august8 +cheer101 +apple5 +987 +manchester1 +emily12 +qwertyasdfgh +sticky +banzai +bv123 +honeybun +159258357 +emogirl +salem1 +reuben +james22 +cooter +darkside1 +nymets +sheldon1 +girl12 +bailey11 +jessica5 +plastic1 +1computer +august20 +hippie +fuckme! +batman13 +hateyou +diamond7 +iloveyou19 +iloveboys +motherof2 +muffins +changes +12345678901234567890 +abc123456789 +charlie11 +manny +pierce +pyramid1 +iceberg +66mustang +hawaiian +chelsea11 +newnew1 +chewie +haslo1 +snuffy +420247 +naomi +davis +maxence +sawyer +3qdlqb49js +nic +nastenka +963741 +mahmoud +sprinter +warrior1 +alcatraz +shiela +marlon1 +morgan2 +foxylady +kimmy +sergej +october25 +matthews +inferno1 +talisman +cloud1 +jer2911 +poiuyt1 +brownsugar +neopets +xander1 +sunshine1 +glenn +living +justin5 +adidas123 +59trick +bizkit +tarheel1 +babyboy12 +kolokol +kareem +monmon +olivia123 +alicante +october5 +emma12 +larissa1 +johnathan +torpedo +hello23 +karukera +1123456 +tiffany2 +1z2x3c4v5b +hhhhh +hoe123 +superfly1 +roxy12 +daddys1 +castor +princessa +angie123 +george2 +shepherd +rjitxrf +honey12 +tonino +devon +nigeria1 +october18 +12345612 +nokia5230 +l123456789 +vandana +miguel123 +max1234 +cypress +hamburger1 +michelle7 +buddy01 +monkey77 +123456@ +stayout1 +weed12 +panama1 +qwerrewq +songoku +skater13 +piper +halflife2 +jen123 +ivan123 +taz123 +beth +meteor +malik +march30 +wtf123 +butterfly0 +bitch. +adrianna1 +david7 +lionking1 +icecream12 +bryan123 +purple14 +woaini123 +planeta +josie +bbbb +dramaqueen +compaq12 +killer01 +shit12 +carly1 +thekid +magic32 +songbird +vargas +octopus +seahawks1 +scooby123 +football01 +marisa1 +daniel23 +winter12 +flyboy +ramon1 +iloveyou20 +milton1 +ballet1 +family1st +alondra1 +santacruz +macintosh +reynaldo +samsung +samuele +drizzt +hell +fredrick +@!@ +love91 +sunshine4 +htubcnhfwbz +pink01 +011194 +arielle +stardust1 +aragorn1 +bieber +looser1 +myjesus +coke +rachel123 +sophie +abcdef12 +silvio +waffles1 +kris +babyg1 +15 +punker +commerce +dupadupa +iloveyou17 +didididi +aminata +iloveyou07 +bff123 +doogie +14725836 +dannyboy1 +october8 +r4e3w2q1 +jello1 +jesus07 +24862486 +obinna +paulette +123qwe456 +philippine +123456zz +1qazse4 +chris69 +ilovemike1 +romans828 +sausage1 +43214321 +tester01 +aze123 +viviane +constance +tweety123 +james5 +mireille +sexyred1 +ladybug2 +travail +12345aa +killa123 +atlars10 +com +angel25 +159357258 +chuckles +juan12 +athlon +bobo123 +1111qq +carmel1 +mackie +whitey +tractor1 +godspeed +november20 +hope123 +king13 +needajob +brandon01 +nfy.if +star23 +triangle +shruti +elmo +121288 +ecuador1 +tycoon +bbbbbbbb +hammed +tree123 +shawna +whisper1 +timberland +patrick12 +horses123 +peach1 +test12 +jarvis +3344520 +shinobi +1717 +ashley18 +pussys +love29 +dudley1 +franky1 +cookie7 +polo123 +kishore +nevim +bigbrother +liliya +zildjian +papichulo +id6c3wr6un +psicologia +madzia +1harley +pistons +19591959 +ser +patriot1 +a1234567890 +bynthytn +ipod123 +kitty5 +ultimate1 +800620 +chanel5 +love4eva +november18 +hellfire1 +westcoast1 +nicoleta +mercado +chicken7 +groove +aguilar +mail +peppino +accounting +woaini520 +angel19 +secret12 +babygurl13 +chicken5 +karla +iamtheone +michal1 +hockey14 +aku123 +crazydog +jimbob1 +bones +goodnews +bookie1 +qwertz123 +limegreen1 +lalakers +dangerous1 +777777a +mango123 +piano +passions +football +terrance1 +blink182 +sixteen16 +den +killyou +babe12 +hassan1 +cookie01 +football88 +sugarbear +jessica +girly1 +vagina69 +anabel +567567 +london11 +erick +spinner +wednesday1 +casper12 +format +antonia1 +qwerty12 +cassie123 +people12 +shadow10 +tigger69 +katharina +integrity +lucifer1 +barber +kamilla +morgan01 +classof06 +123456789x +nefertiti +jessica21 +091296 +superior +money01 +character +070 +cottage +augustus +playstatio +yoshi1 +1472583690 +cheyanne +chipper10 +100986 +fhntvrf +bbbbbbb +buckshot +fujitsu +michaeljac +sassy2 +bacardi1 +ilovehim12 +message +starburst1 +mcdonald +rachid +cheerleade +jennie1 +cacaca +sansan +voetbal +windows98 +jjjjjjjj +tianya +ilovemymum +yasmin1 +andrea +panchito +bandit01 +131061 +megadeth1 +zavilov +400067 +gjkbujy +popova +kittylove +123123aa +winxclub +www +sara12 +tommy2 +schumacher +jenkins +poi123 +phil413 +mighty1 +jazzman +butterfly4 +scooby12 +soccer. +fickdich +gordita +flyfly +sylvia1 +753753 +123red +1bigdick +jordan08 +everyday +casino1 +yes +academia +852369 +ballin2 +8eight +totti10 +sasasasa +cheech +justin23 +shayla +flame +nathan2 +salami +baseball20 +charles2 +mam +modern +killer22 +killer +eminem2 +myangel1 +120197 +mortal +word +dale88 +lakers08 +rfhfylfi +kambing +kamil1 +babygirl17 +24crow +lola12 +robert13 +jellyfish +specialk +deadpool +pelican +132465798 +alberta +gwapa +pauline +leah +simmons +aldrin +quadro +sexylove +1heart +gundam1 +jacky +yosemite +bibiche +hottie7 +brandon +world1 +fox123 +yesenia +hgfdsa +psalms23 +my2sons +mary12 +portland1 +goat +giancarlo +hgrfqg4577 +nash13 +hahaha! +cupcake2 +bugatti +aragon +luke123 +1235813 +greyhound +softball4 +gogo +fy.nrf +rahul +bottle +romeo123 +blue55 +flowerpower +hellos +house123 +mexico11 +terence +cherish +icecream2 +impreza +emerica +strange +oliver +nuggets +runescape2 +muffins1 +12monkeys +danielle2 +lauren2 +passord +wiggles1 +qwerty111 +happy11 +antoine1 +gavin +newday +asdfghjkl:': +tauchen +blue24 +????????? +haters +lover4 +starr1 +nbvjatq +102102 +minicalibra +chinchin +gateway2 +portia +ghost123 +monkey24 +delicious1 +major1 +saffron +galileo +sheriff +ghbdtn123 +mashka +lavinia +gilberto +ghhh47hj7649 +bangsat +1234567y +1234567890z +patch1 +555222 +hansol +kerstin +b1234567 +mustang66 +alien +saurabh +838383 +terserah +football18 +anton1 +oriflame +bosco +shayne +pinocchio +matthew11 +misiaczek +manfred +graham1 +jesus5 +dutchess1 +madden08 +angeleyes1 +grandma2 +anime123 +kitten12 +t123456789 +apocalypse +diamond3 +amparo +rehbwf +jake11 +1012 +mingming +gigi +rocky5 +myspace15 +calle13 +dictionary +1234567l +153426 +uranus +kramer1 +pulamea +rodrigo1 +lololol +jake1234 +cba321 +boys +only4me +mendoza1 +dimples1 +quality1 +august29 +zimbabwe +zhou1980 +phillies1 +jingle +1v7upjw3nt +09051945 +guitar12 +360flip +jaylen +patatina +bronson +jordan! +begemot +cupcake12 +poopoo2 +windmill +daniel14 +october27 +bobesponja +monitor1 +jimjim +barosan +59mile +bigsexy +summer7 +ant +1121 +engineer1 +19weed +number13 +marcin1 +bravo +1asdfghjkl +jackie12 +thomas13 +lucky21 +kartal +vision1 +sassy12 +chickens1 +imagine1 +grammy +tyson123 +pinklady +hawkeye1 +taylor7 +kokakola +dallas123 +qwerty9 +monica123 +1aaaaa +maxell +asturias +weezer1 +royal1 +jkl123 +mephisto +october24 +graciela +coregmedia +moses +qazwsx +j +mimi12 +possible +teresita +zxcvasdf +southside3 +melissa12 +josiah1 +buck +bball21 +dancer2 +thegreat +120702 +madhuri +ssssss1 +simple123 +redsox34 +milkman +sunshine22 +hockey17 +braxton +olatunji +01011985 +gemma +123456789aa +kthjxrf +bab +prettyme +love04 +soleil13 +lawson +lipton +qazwsx1234 +janvier +chico123 +economics +parents +121106 +cookie5 +reload +george01 +gagarin +horses2 +anissa +kiki12 +hallo12 +shawn123 +homer123 +fener1907 +blowme69 +cocoa +katie12 +shibby1 +orange22 +reginald +chris08 +newman1 +redbone1 +rosalinda +lexie1 +poophead +dodo +friendofgerly +lauretta +buckwheat +someone1 +talent +lucky8 +quebec +daisymae +monster3 +stronzo +matty +tonyhawk +cosmic +water12 +loveya2 +dragon666 +boom +jasper12 +fred1234 +winter08 +jameson +jelszo +dick69 +underdog +pat123 +alfie +ilovemydad +sister2 +baby24 +firewall +god777 +soccer25 +nate +blue33 +soccer33 +380015 +123321z +sissy +dino +skidoo +woofwoof +poo123 +terrance +tamahome +killkill +tomboy +chilli +jordyn1 +champions +89898989 +zacatecas1 +shasha1 +z1x2c3v4b5 +kjrjvjnbd +echizen18 +girls2 +piramide +iamgay1 +evony123 +ramiro +prosperity +james21 +gromit +pixies +hannah13 +marco123 +1210 +dfhdfhf +mayowa +chelsea +beyond +335577 +tolulope +yesenia1 +baseball! +sushi1 +080 +kamote +inactive1996aug +tarakan +carnival +russian +marble +dick12 +198900 +pawpaw +angel05 +1233211 +boogers +ilovemyfam +sparky123 +poupoune +4ever +biggles +televizor +nicole4 +buddy11 +blue01 +crazygirl +iw14fi9jwqa +221122 +golfball +liverpool0 +googoo +shad0w +bigboss1 +66bob +fightclub +greedisgood +1summer +stanford +oilers +dbm +girlie +sr20det +happygirl +chris1234 +1230456 +gogeta +worship1 +connection +hurensohn +caballero +october20 +christopher1 +scratch +0123654789 +ellen1 +puppy2 +asa123 +zipper1 +prelude1 +12step +chinni +barcelone +clark +froggie1 +hockey9 +bigboy123 +smokin +roadkill +ministry +virgin1 +sinclair +francesca1 +winter11 +452001 +jenny12 +cena54 +employment +national1 +mommyof3 +raindrop +kitty3 +12qw! +april7 +ifeanyi +irock123 +ellobo +1234567890qwertyuiop +&hearts +patterson +xt97794xt +mike01 +hackers +ilovegirls +warlock1 +r +gfhjkm +prosto +judith1 +tata123 +vfhujif +october6 +delaney +schnecke +wowwow +policia +forzajuve +prasanna +silvia1 +matthew5 +s0ccer +140473 +reader +frodo1 +tobias1 +jeanette1 +brooks1 +ashley5 +spaghetti +junior11 +00110011 +lily123 +321456987 +audi80 +54321a +alliswell +airborne1 +maurice4 +maldini +mickey7 +monkey16 +marinka +barkley1 +bahamas +banana2 +cachou +28081976 +markie +flamenco +avemaria +mat123 +tacoma +147147147 +25257758 +01478520 +colombo +sowhat +razor1 +yahweh +vfndtq +puppy12 +lithium +joshua3 +couponmom +andrew22 +privacy +paprika +love2011 +1newlife +popular +baseba11 +f: +fynjirf +chat +november17 +zlatan +twenty20 +bahamut +vjkjrj +eastwood +maryann1 +people2 +lioness +rebels1 +1pimpin +74123698 +metall +safety1 +asdf12345 +christa +1234556 +pro100 +look +1michelle +sk8erboi +comeon +delilah1 +steelers43 +joshua13 +malone +vfhbirf +viewsonic1 +nick1234 +karamba +jordan6 +james7 +meggie +albion +mortimer +tripleh1 +jello +superduper +sexy25 +lemonade1 +08520852 +copenhagen +advocate +guevara +fffff +jaylen1 +hotdog123 +ebenezer +amatory +1111122222 +baseball09 +567tyu +iloveu4 +irene1 +ginger +741236985 +mozart1 +love56 +beyblade +motorcycle +almost1 +madison123 +bratz +69cougar +samsung +kitty7 +november23 +kamikadze +560034 +caveman +braxton1 +bramble +voyager1 +derparol +qwerfdsa +rfgecnf +10201020 +porter1 +imthebest1 +198300 +mario64 +anthony6 +foolish +brittany2 +mustapha +gayboy1 +ou29q6666 +14 +office1 +freefree +encore +midnight2 +jarhead +mimine +16161616 +independent +dancer123 +superman21 +bobby2 +16 +october4 +chula1 +just4you +bitch07 +jack11 +november10 +status +leeann +winwin +rfvfcenhf +playa +greenwood +852654 +tiger7 +undercover +pheonix +volley1 +159875321 +dean +67camaro +szczurek +raven123 +girlpower +vergessen +sherri +12345o +november21 +brent1 +purple69 +outkast +waterfall1 +bmw123 +natural1 +marguerite +counter1 +jasmine +sunshine10 +zapata +deeznuts +december20 +dima123 +12345678j +qwertyasd +chris07 +chaselo +barrett +keenan +1badass +tiger23 +holein1 +jericho1 +komputer1 +michael6 +400093 +kiara +sexyblack1 +cavalo +leilani +baller21 +daniel15 +ortega +benten +lineage +speedway +chapman +malish +eskimo +zeynep +slipknot2 +friends7 +123qwe +greatest +demilovato +astalavista +nonono1 +yes123 +haslo +dogfood +amanda +pimp10 +fergus +maplestory +jessie12 +stacy +churchill +stress +joker12 +0okm9ijn +wolfgang1 +qweasd12 +bribri1 +tigerwoods +jeronimo +quartz +as12345 +brokenhear +violette +night +destiny3 +beefcake +jancok +baracuda +890890 +dragon +juanjose +ronaldo123 +wanrltw +loser4 +heyyou +justin! +asswipe1 +nigger12 +nicole09 +shahid +yasmina +onlyme1 +first1 +hello10 +sixsix6 +vulcan +chief1 +12344321a +humble +qh6xl1p9xj +unlock +moo123 +myspace99 +money69 +brilliant +grisha +1211 +spinner +voyage +titan +marymary +fisherman1 +hippo1 +26262626 +arsenalfc +kidrock1 +m1chael +amdturion64 +twenty +sweetiepie +ilovemykid +kratos +cnthdf +puddles +jacob2 +n +baltimore1 +sean123 +18273645 +100001 +idiot +allen123 +clyde1 +december21 +madison12 +madmax1 +stolen1 +random123 +hindustan +lotus123 +demon1234 +mack +p00p00 +asdf123456 +daniel21 +vodka1 +niceguy +thunder2 +michael123 +kolkata +doomsday +crystal2 +979797 +skate8 +wojtek +super12 +golfgti +!@#$%^ +cingular1 +johnny123 +bombers +1asdfgh +shadow5 +kochamcie +dell12 +astros +qwertz1 +october28 +maria2 +emily2 +wally +********** +pinkie1 +angus +hockey22 +angel +noway1 +november22 +marketing1 +999111 +zx123456 +123asdf +123four +makeup +slonik +petrova +slave1 +delpiero10 +9638527410 +gretchen1 +chainsaw +justyna +melodie +chewbacca +goalie +mas +i< +vehpbr +kerry +zxcv12 +786110 +lions1 +stayout +nestle +energy1 +pa$$word +telecaster +andrew7 +luca +sacramento +zamora +itsmylife +hondas +1abcdefg +hardware +asian1 +ilikesex +pastor1 +mikimiki +198611 +ewq321 +hunter7 +icecube +fff +maxpower +slapshot +walrus +stereo +october26 +earnhardt3 +10293847 +lansing +trombone1 +hellow +kostik +juliet1 +puppys +dragon77 +bigballs1 +maynard1 +hamada +biker1 +whiteboy +blackdog1 +powerof3 +alonzo +2000comeer +mailman +ashley +saints25 +aleksandr +shampoo +elway7 +jordan15 +xxxxx1 +good2go +carlota +hi12345 +loveme11 +banshee1 +12340987 +nick13 +kay123 +aleksander +tascha +lkjhgfdsa1 +vanessa06 +mukesh +skating1 +reshma +tekila +babies2 +redstar +xoxoxo +doudoune +titine +hootie +alexis13 +anthony15 +baby2008 +mmo110110 +wersdf +janek1 +korn +orange13 +opernhaus1 +arturo1 +delldell +lolek123 +campeon +7415963 +fuckit2 +woodland +harman +pandabear1 +trouble2 +69mustang +flower11 +crepusculo +cabron +merda +praline +everett +coolbeans1 +thomas +7779311 +jonathan2 +carol123 +humphrey +hello6 +astra +dfcbkbcf +7ugd5hip2j +joey12 +nokia5530 +monkey88 +robert3 +november13 +shadow21 +luisa +waterboy +inter10 +johan +01012010 +beaches1 +daniel5 +password44 +green420 +paulo +demon12345 +gogogo1 +joshua +coolboy1 +eric12 +jessika +charlie4 +swagger +easton +cassie12 +stars123 +c2h5oh +123456789+ +01011991 +monkey1234 +#1pimp +kameron1 +van +justin16 +311311 +alice123 +lancer1 +august30 +apelsin +joy123 +nomore1 +armada +soldat +221188 +tiger11 +hhhhhhh +persona +delgado +delicious +fat +taylor5 +presto +joshua10 +++ +beachbum +cocoloco +manson666 +funmilola +ken123 +graduate +scuba1 +summer22 +lalaland1 +jordan24 +sarah2 +ruth +priya +july30 +nicole +codered +d1234567 +lazarus +jingles +faraon +steven2 +gymnast +wsbe279qsg +night1 +anchor +jordan07 +francia +jonathan +parola123 +shawna1 +turner1 +presario1 +wutang1 +wdtnjxtr +johnjohn1 +china123 +baseball16 +taylor21 +colonel +frog123 +freaks +22071972 +powder1 +tarzan1 +fresh123 +alfonso1 +rollin60 +prestige +spurs +perfection +virtual +anthony +portal +cool123456 +midget1 +denali +lisa12 +clipper +smile! +life123 +frederik +jorge123 +mario12 +april5 +othello +valencia1 +sexbomb +vfvf +ilovemylife +darnell +leland +myfamily1 +family01 +cjytxrf +honesty1 +arkansas +jessy +jen +igorek +love4ever1 +socks1 +packard1 +justina +123password +brianna2 +free12 +m1am1b3ach +chick +jasmine5 +tristan01 +marina123 +loverman +zack +pa55w0rd +coldplay1 +dantheman +reyes +just4u +brendon1 +mechanic +1charlie +westwood1 +mike21 +december22 +hopeful1 +pippen33 +realnigga1 +myhoney +robin123 +reefer +batata +joshua7 +aaaaaaaa1 +andy12 +winter99 +marmite +chicharito +martyn +loser11 +plumber1 +short1 +100261 +10pace +martian +shoes +raziel +password89 +noreen +fivestar +avrillavigne +3000gt +tinker12 +hollywood2 +starburst +taffy1 +400076 +roberts1 +minhasenha +shopper +catdog12 +dogman +09061976 +xxx666 +clarence1 +maryrose +afghanistan +themaster +jazz123 +stunna1 +500000 +12345123 +graphics +anthony21 +plokij +samuel12 +rainbow12 +mafia +superstar2 +131 +ilovemyfamily +soccer06 +crash1 +ezequiel +ganja +nolove1 +lavigne +murray1 +lebanon +homework1 +cookies12 +amoramor +cyprus +bigtits1 +academy +admin1234 +mellow +kings +ilikeyou +confidence +october19 +elliot1 +ppoo0099 +lovehim1 +ghghgh +cronaldo +suckit69 +120389 +lakota +sarina +thomas3 +filip +ashley69 +12345i +manon +slider +32167 +mozilla +chrysler +angele +stewie +usarmy +tiger13 +dennis123 +baller22 +parlament +montgomery +sweet13 +brasil1 +global1 +mirela +31x7t5xbke +mishijos +iloveryan +pendejo +boris1 +gold123 +wyatt1 +happyfeet +strange1 +slick +kill123 +traveler +jack01 +diabolo +november15 +laurah +tryagain +vauxhall +angle1 +alexis11 +aleksa +hammers1 +bball24 +niunia +thisisit +erik +govols +popcorn12 +paloma1 +merde +butterfly! +treasure1 +jewel1 +20092010 +nata +pittsburgh +drake +bmx123 +32323232 +gisela +tyler11 +dewayne1 +candle1 +praise1 +giraffe1 +sparrow1 +fish12 +etnies +timepass +luv123 +kkk +mckenna +homers +asdfghjkl; +dragon6 ++ +lonnie +socrate +ashlyn +mylover +herrera +alanna +rosa +weed69 +baddog +lavezzi +meowmeow1 +giulio +positivo +13579- +horses12 +baybay1 +harley11 +online123 +brisbane +hotsauce +gigolo +fxzz75$yer +domenica +nicole07 +123456u +firefox1 +joseph +ordenador +milo +aloha1 +son +harry24 +amanda3 +poulette +tennis123 +fcporto +summer3 +spongebob9 +1master +transforme +braden +berserk +feuerwehr +designer1 +ilovesam1 +brooke12 +cosmin +oasis1 +moumoune +simba11 +jarrett +venom1 +kamehameha +redcar +gangsta123 +153153 +swatch +sexy20 +mustang7 +purple6 +cutie3 +showtime1 +123456788 +baboso +capricornio +yeahyeah +bmwbmw +maxmax1 +lavanya +button1 +1236 +alyssa123 +shakespeare +rosario1 +12345689 +dragonfire +lisboa +poop00 +hottie14 +prayer1 +minimum +1justin +limegreen +loveme23 +mate +crystal123 +justin14 +fffffff +cnfkrth +meredith1 +pimp22 +neworleans +qwerty55 +pennstate +bandit123 +lavender1 +anno1602 +linked1 +123456zx +kittys +121290 +benjamin15 +mulligan +zakaria +patrice1 +aug +baseball18 +dolores1 +woodstock1 +m0nk3y +carpediem1 +all +arcadia +cooler1 +dddddddddd +pussy101 +queen123 +wanda1 +cbr900rr +poptropica +angelok +bigtime +nowehaslo +fghjkl +nicholas2 +mack10 +jessica10 +vfhbyjxrf +muffin12 +939393 +matt1988 +fuc +element2 +prophet +foryou +kyle12 +fishbone +music4me +laughter +kitty13 +seaman +110024 +fred12 +black666 +tiger3 +hm9958123 +1soccer +dolphins13 +erick1 +jamess +qwertyytrewq +wanted1 +juniper +sophie01 +1234qaz +ninanina +andrew21 +december13 +vitaliy +dogcat1 +liverpool7 +kaycee +swathi +fcbarcelona +missouri +chris09 +lauren01 +builder +pinguino +eternity1 +bronx1 +yamaha125 +calcio +dfg5fhg5vgfh1 +austin13 +748159263 +ghjcnjq +timberlake +viriato +protect +cool13 +funny123 +destiny12 +sweet666 +bucket +misskitty +12qw34 +presley1 +richards +circle +mini +computadora +krasota +jessy1 +thegreat123 +bologna1 +metroid +lovely7 +hustle1 +screen +sirena +erika22 +wertzu +suicide1 +iloveryan1 +nokia6230 +lapochka +drums1 +alina1 +mollydog1 +pumpkins +10011001 +kelvin1 +whatwhat +cardinal1 +century +shayshay1 +ram +911 +fat123 +bravo1 +lilwayne12 +zoe123 +totoro +counterstrike +blue16 + +tippy1 +phuong +fullmetal +salsa +4money +esperanza1 +allahis1 +dkxjizc282 +euteamo +markiza +challenge +cas +elmejor +ilovelucy +k1234567 +morena1 +softball9 +1597530 +newnew +buddy3 +1024 +marie11 +jonathon1 +baller24 +13241324 +daddy01 +sun123 +121289 +m@d!z +nathan01 +kanchan +sugarbear1 +boobies2 +rjhjkm +gbenga +febrero +ballin12 +sooner1 +sss +sathya +amor12 +202122 +qugrqfo825 +bagpuss +superman22 +batman3 +beckham1 +michelle11 +mathematics +bonbon1 +kumar123 +football17 +shadow69 +danilka +ilovealex +ilovedogs +kameron +ryan962052 +profit +dragon76 +helpme2 +federal +andrew10 +dance4life +heartless +iverson03 +waffle +jesuslovesme +naruto +nicholas +cardiff +amanda! +cars123 +tamere +pizza2 +mmm123 +madden07 +mari +milacek +green10 +baggins +augustine +a12121212 +871982 +rashad1 +september3 +bbbbb +ilovecats +tessa +massive +hoover1 +ghjdthrf +redline1 +555333 +143 +abcxyz +mommy01 +ken +marker +ketchup +trojan1 +izabella +bling1 +love111 +jordan +redwood +maddison1 +henrik +salamanca +1234567c +music7 +lukasz12 +eagles12 +melissa +nkechi1 +daddy3 +1robert +sunshine69 +1245 +marbella +jobhunt +gjhjkm +ramsey +daisey +perkins +wordlife +awesome! +lover11 +angelito1 +1qaz2wsx3e +germania +newyork123 +cocaine1 +krishnan +apache1 +pimpin12 +ipswich +education1 +bunnies1 +pearls +walalang +lover21 +stacie +hunter08 +lennox +rochester +punk123 +wwww +beagle1 +123qazwsx +426hemi +babygirl24 +fuckshit +ashley17 +1destiny +130130 +michelle13 +1907 +rjyatnrf +frogs1 +muscle +kristine1 +tigger7 +suckme1 +october29 +dododo +gopher +gunners1 +tujhrf +tomcat1 +pavlik +heythere +beardog +matthew01 +40028922 +fishtank +dabears +elmo12 +131313a +dimension +dookenr1 +pearljam1 +harsha +powers1 +1011 +chioma +chris4 +bambou +hammond +music3 +november5 +ddzj39cb3 +41034103 +fucklife +babykoh +renren +kaikai +wildman +snapper1 +llll +michael69 +angeli +francoise +starwar5 +woshishui +3syqo15hil +januari +sassie +zeus +newpasswor +400706 +noiembrie +felicita +scorpione +1william +jessica14 +nataha +159753159753 +hannover +paulie +kobe +lorenz +password27 +denzel +amoureux +fresh +ichliebedi +198111 +sailing1 +blue69 +feline +forzanapoli +giuliana +1a1a1a1a +amanda21 +615243 +phil +bambi +nideknil +saveme +cowboys81 +anurag +jelena +shortie1 +football +coolness1 +jam123 +sanjeev +1453 +food123 +gucio +girls123 +modena +jasmine13 +star15 +a123456789 +gator +loserface1 +foxy +mydear +baltazar +william1 +150801 +robocop +natasa +jaiden +killua +victoria12 +stinky01 +millennium +13791379 +abbie1 +putangina +shayne123 +5050 +loveme7 +peppe +austin10 +holler +1953 +sushi +123852 +mangos +concord +black3 +venus1 +lickme1 +michael. +hamburg1 +lovelygirl +dadadada +pimp21 +kasey1 +playboy12 +negro1 +lunatic +mykids4 +selenagome +nascar3 +brennan1 +cannon1 +chris24 +chicago23 +12345as +josette1 +ineedyou +aq1sw2de3 +kitty11 +parola1 +dropdead +1950 +pookie2 +123456789y +pollo +leeloo +timmy123 +aaron12 +love +funky +googletester +macaroni +fake12 +311070 +super8 +blackrose1 +canelle +newjersey +fletcher1 +gizzmo +kingpin1 +mybabies +01012000 +amanda22 +books +raptor1 +forever12 +poop22 +papapapa +brucelee1 +laracroft +habiba +mancity1 +daddys +198800 +lololo1 +magical1 +411014 +olivia12 +raj123 +ilovesex1 +bryson +guiness +2angels +love321 +imissu +bluedog1 +hawaii808 +meme12 +teodora +qwqwqwqw +william7 +virgil +tyler13 +suerte +marusya +nikki12 +summer13 +shayla1 +justdoit1 +marinara +118118 +serious +kagome1 +kampala +jordan8 +rfhfvtkmrf +franci +longbeach +326159487 +redfish1 +angedemon +777111 +vh5150 +hacker123 +tay123 +barbie2 +3232 +daytona1 +10987654321 +pascale +brooklyn2 +mickey11 +134679258 +doglover1 +november16 +whynot1 +ryjgrf +automobil +mustard1 +movies1 +sincere +cinzia +200669 +smoking1 +goodgood +dim +teste123 +december23 +justin15 +xdqwerty +grease +mybaby2 +star21 +197800 +batman01 +edward17 +103196 +stigmata +lakers32 +val +marseille1 +starbuck +333888 +misterio +karma +boulette +warner +junk123 +inter1908 +asas +yankees7 +meadow +jaigurudev +dolphin2 +beanie1 +dkssud12 +888666 +scotch +2hot4you +trent1 +shoes1 +0101 +getout +airport +meathead +felipe123 +llamas +bri +chivas#1 +shadow99 +blessed7 +andreia +3s43pth5aea +because1 +ilovejoe +nat123 +polarbear1 +felice +newuser +women +romaroma +222222222 +surena13 +daemon +alexander3 +langga +brothers1 +bazooka +pjkjnj +tingting +dog1234 +agathe +villevalo +475869 +anthony22 +vince1 +301197 +ww111111 +fishfish +skating +poker123 +bummer +soleluna +rasheed +hal9000 +messi19 +olusegun +lucy12 +troy +stinger1 +blue77 +stinker1 +1237895 +loser13 +nigger69 +no +cvbhyjdf +batman7 +opelcorsa +forgiven +absolute +gerardo1 +olechka +football54 +premium +angel20 +valley1 +stratocaster +freedom1 +candy11 +001100 +madness1 +slut69 +bigbooty1 +batman23 +assholes +bolaji +happydays1 +tanginamo +primrose +198511 +temppassword +angels3 +aligator +allahakbar +flounder +nessa1234 +ford150 +loser3 +12101961 +pokemon10 +111666 +bottom +leika1 +november2 +scrabble +amber2 +goodies +sweet69 +snoopdogg1 +bumble +dottie1 +lolotte +19821108 +mahalq +252627 +angel99 +staples +pocket +tombrady12 +wwwwwww +electronics +tuesday1 +jessica22 +racer1 +bbbbb1 +solitario +mcgrady1 +hawkesbury93 +cuttie1 +sk8erboy +mommom +bicycle +choochoo +paola1 +misha1 +quentin1 +adonai +weaver +goodtime +angel77 +happy22 +bonito +espagne +shandy +yomomma +barca +terrys + +198411 +shell +sanjuan +154322358 +g00gle +mickey13 +love!! +daisymay +art123 +1234567891234567 +dj1234 +251314 +h +cvthnm +unicorns +buffy123 +steffen +glamorous1 +miroslav +leicester +lydcc20091314 +october9 +elements +yfcnz +perico +second +titties1 +madison5 +munchie +weedman +paddy1 +bribri +aparna +sam1234 +moonstar +bunny12 +12345abcd +feather1 +k.,jdm +money07 +wolfman1 +alex07 +peyton18 +shadows1 +cristo1 +hf +painting +tichuots +pampam +december11 +jessica4 +caramba +55667788 +meagan1 +estela +original1 +waters1 +mirella +leralera +cooper12 +senior06 +aphrodite +ilovesam +198612 +bunny2 +saphire +yourmom123 +nolimit1 +minnesota1 +5551212 +x99qomx561 +w8woord +nha7ebf6kp +chevy350 +dude11 +negrito +april6 +pleasure1 +onetwo12 +abundance +lozinka +avalon08 +shelby12 +123123123q +loveme13 +black7 +dumdum +apple22 +zebulon +3sisters +forgotten1 +bhaby +lonewolf1 +deshawn1 +fernanda1 +steele +ilov3you +hello8 +hx28o9e646 +flower4 +sup +adam1234 +iamhappy +boosie1 +phyllis +assman1 +2short +rainman +123q123q +gemma1 +dayton +marietta +johnny12 +taekwondo1 +baller123 +kelly12 +keepout8 +manuel123 +fearless1 +joseph11 +jake01 +pro +jewel +852123 +annabell +itsme +canada123 +cfiekz +dozer1 +rabbits +27272727 +mivida ++ +uuuuuu +angelface +rampage +loveyou3 +ntktdbpjh +123456780 +lunaluna +1200nerds +vinnie1 +123456asdf +400072 +yellow13 +q1w2e3r4 +willem +92dk2cidp +marta7 +elizabet +slacker +mouette +kayden +u +callaway +roserose +my-space +green14 +alemania +shanice +hawaiian1 +austin3 +1q2w3e4r5t6 +monopoly1 +star01 +david23 +loretta1 +tulipe +zhang123 +jayden08 +damilare +achille +gearsofwar +adeyemi +onetime +david5 +fuzzy +amoreterno +160403 +winter09 +bebita +pedarsag +traffic +italy +ram1500 +badman1 +121001 +1chocolate +bitch15 +marilou +lenny1 +corbin +missie +powerpuff +soccer01 +satanas +scooter123 +bad123 +lokita +klinger1 +record +headshot +johnny2 +nextel +chiqui +shadow23 +ashwini +yaroslav +michael14 +birdie123 +marishka +loco123 +198585 +tyler01 +ernie1 +dakota01 +senha +habbo123 +198989 +123456789qwerty +calico +smirnova +sphinx +lina90 +ownage +edxk20qmfs +jaycee +damon1 +salima +brent +cascade +temporary +tytyty +rajendra +oatmeal +ficken1 +bracken +schumi +fucker12 +desire1 +missy2 +holyshit1 +treefrog +robot +joy +fduecn +native +jan123 +159753852 +naruto101 +yahoo100 +ulises +itsme1 +tweety13 +newthree51 +123qq123 +adrian12 +jesus#1 +perry1 +lzhan16889 +pink69 +triple +language +jayhawks +dashka +pfqxbr +tbone1 +lovemom +adolfo +swinger +moemoe +maricar +ilove? +total90 +deandre1 +december17 +maranatha +july +gadget +engineering +north1 +clemente +tkfkdgo7 +e93c50 +bebe12 +keepout1 +gandhi +pqntmt1247 +wdtnjr +lauren +123654987 +real +hunter99 +zoosk1 +2010comer +dominick1 +sunshine8 +rowdy1 +0r968ji9ufj6 +leinad +perach +candy13 +canon +haylee +mag +678910 +1faith +invisible +evan +nobody1 +password32 +gardenia +kate123 +lighting +plus44 +monalisa1 +peaceout1 +lalitha +parole +tyler5 +ilovenick +transam1 +zaxscd +robotech +000786 +breakdance +wyoming +kristal +sword +27352735 +charlie! +montero +smile12 +ludivine +musician +sexy06 +@@@@@@ +nasty +fer +powerman +koko123 +kayla2 +panic1 +mirantte +yaallah +important +bankai +fourteen +gotohell1 +salvation1 +vitamin +raduga +123admin321a +guitarhero +greenday2 +mustang5 +dynamic +spider123 +amoureuse +shorty3 +chelle1234 +cubbies +luv4ever +rktjgfnhf +klaudia01 +woofer +yankees23 +playgirl1 +pictures1 +login123 +pocahontas +spikes +fuckthewor +lady12 +pedrito +alexander1 +alone1 +cream +hallohallo +lukas1 +cutie5 +fuckyou09 +puppet +arsenal +rudeboy +yomismo +rudy +kurama +tigres +carajo +enigma1 +inna +onetwo +spiderman7 +amy +frankfurt +girlsrule +rachelle1 +alfa147 +kakakaka +rai-131 +liza +juanito1 +k +cornell +reilly +w1991a +nanook +december2 +under18 +positive1 +catlover +1qaz@wsx +f4u*123 +tonya1 +onkelz +lfybkf +juventini +ollie +boogers1 +25 +sardegna +password06 +bigblue +moneys1 +stretch +kseniya +198787 +myhome +charlie +rain +merida +iluvme2 +anthony1 +cristh +ella +thomas10 +28282828 +sidekick +borboleta +samsun +shubham +chocolate5 +1andrew +satyam +chingy1 +peepee +joseph01 +4391634m +pa$$w0rd +pass9876 +michel1 +trabalho +stealth1 +chevy2 +ahov +polska123 +vermont1 +kaiser1 +constantine +cristy +vbifyz +allen3 +schatz1 +ophelia +quicksilver +rockandroll +sailor1 +fuckyou10 +malice +solnishko +naruto +hillary1 +lilpimp1 +chinchilla +smokey01 +miracles +310 +win +buddy7 +thedog +blackstar +04022000 +tilly1 +jules +peppermint +nadege +isabel972 +12345678r +another +gentle +danielle +3526535265 +armenia +wert1234 +boy +essence +waswas +football28 +devildog1 +lynn123 +spongebob7 +messenger1 +popopo1 +koala +zhd741220 +memphis10 +401107 +jjjjjjjjjj +deadmau5 +escalade +carl +porno1 +ncc74656 +rupert1 +shaun +oscar12 +werter +haribo +oldschool1 +september8 +lloyd +cowboys2 +wildwood +13587930210 +teddy2 +change1234 +jumper1 +galaxy1 +smile0_0 +library1 +ab12345 +paramedic +maritza +reborn +qwertqwert +katie2 +elizabeth9 +emo666 +doughboy +pass_2011 +l1nked1n +naresh +juanpablo +astrid29 +april8 +qazwsxedcrfvtgb +bball13 +poopmaster +korean +twenty1 +speedo +13571357 +lover23 +antivirus +bunghole +critter1 +helicopter +000006 +itachi1 +619rey +har +gfgfvfvf +esteban1 +110016 +damnit1 +12344321q +raiders2 +houdini +hbhc8290826 +only1me +nescafe +427468 +bahia1979 +forever7 +baseball08 +1234love +pingpong1 +lovers +grande +maria666 +asakapa +babybear1 +games123 +marquez +01011981 +mentos +qwerty8 +auriane +neverland +laddie +morgan11 +mynameis1 +1purple +junior88 +masters1 +solitude +cameron123 +antonio123 +mongol +nicole. +victor12 +rivera1 +ahmed1 +villa1 +jon +spartans1 +mewtwo +11110000 +198686 +liberta +557799 +hitachi +p@$$w0rd +minemine +17 +sweetie2 +beowulf +joel123 +spoiled +castillo1 +nicky123 +hal +198512 +flowers123 +fischer +atlantis1 +173928 +soccer69 +katya +paladin1 +143143143 +imyaimyaimya +mamma123 +jose1234 +jubilee +kool12 +benny123 +zwickau +heythere1 +whore +sunshine +spears +12345zxc +alyssa2 +123456! +cuttie +sabine12 +arvind +twingo +zxc841219 +dalejr88 +14629227 +29422277 +mustang65 +gaara1 +notorious +anthony10 +spionin8688 +edwards1 +929292 +aqswde +madison7 +123987456 +112020 +101089 +313313 +thizz2 +fowler +mmmmm1 +juggalo420 +gianna1 +high420 +andrews +31313131 +ghjuhfvvf +florian1 +pilipinas +carissa +ramona1 +larry123 +confirm +december18 +bball123 +chachi +llllllll +chris101 +december15 +kirill1990 +germaine +0420 +jakejake +ww651118 +nicole17 +myspace24 +green21 +husker +201001 +12365478 +omshanti +elizabeth8 +bea +sammy01 +fucklife1 +gtavicecity +macdre1 +skinner +krazy1 +iloveyou<3 +byteme +0987 +gangster12 +24 +123456+ +prince2 +hollie1 +raspberry +lucky4 +jordan09 +jimmy2 +myspacepas +baba123 +barnes +heyyou1 +82214989 +bubbles13 +soccer77 +luckies +football95 +shaina +1234567898 +10241024 +trunks1 +browning +circus +sodapop +lhfrjy +chriss +password1! +synergy +salam +broadband1 +happy13 +fylhtq12 +madison4 +anthony9 +hotdog2 +asdf:lkj +marigold +blbyf +hellraiser +yogesh +112345 +will123 +shorty7 +hshshs +freestuff +babyboy3 +seminoles +money1234 +asdasd12 +mari123 +baseball19 +mobsters1 +louise123 +finley +prova +blake123 +latoya +baylee +d0r1nc0urt +gusgus +canard +kittie1 +wasdwasd +bubbles7 +buckley +jazzie +derick +mudvayne1 +cronaldo7 +mullet +silkroad +******** +davidic1 +1211109032 +baseball33 +harvick29 +striker1 +rtw150809 +22152182 +stoned +midnite +jessica69 +t36473647 +sebastian + +sincere1 +chadwick +prodigy1 +wildchild +venezia +bird33 +nibbles1 +killer6 +fuckyouall +92298899 +elisabeth1 +david +san123 +435453 +780813 +amrita +godgod +lonsdale +djkjlz +#1stunna +edberg +petey1 +ariadna +flame1 +pl +pennstate1 +ettore +hotmail.com +absolut +nikki6 +brandon4 +fucku69 +anthony14 +mamamia1 +1treehill +cedric1 +den221991 +198100 +orange5 +myrtle +production +fuckmehard +ram123 +beans1 +cool10 +pasadena +arabella +blaine +texas12 +fletch +honda125 +madison01 +handyman +kims89 +198711 +may123 +cheeky1 +carlos10 +nedved +november14 +andrew23 +mariusz +transit +1bigdaddy +kellie1 +53472235 +magda1 +victoria2 +pushpa +ilds4edad +lou +pixie +luis13 +cocotte +aquarius1 +todd +angela123 +teamo12 +washburn +jiefang007 +staredobre +mosquito +200888 +121286 +addicted +586016 +quality123 +h8llp9f +flower5 +qpwoeiruty +hate +124124 +psp123 +kisses2 +xsw21qaz +sparkles1 +red456 +bitch10 +resing1965 +chevyz71 +khan +stevens +007700 +karakartal +jojojo1 +cupcakes1 +lala11 +ash +duckie1 +caramella +monster13 +153759 +platypus +05200520 +rebekah1 +november7 +boeing747 +sandra +rhiannon1 +w123456789 +7410 +a4tech +vfcnth +eatme69 +012012 +football16 +lucian +1,00001e+14 +198412 +lananh +hellas +perfect10 +peggy1 +mohammed1 +23skidoo +golfing1 +money9 +rihanna1 +tetris +bayern94 +oooooooo +tl281188t +nautica +littleone +charisma +giogio +xige5516726 +kismet +520025 +gggggg1 +sundance1 +serrano +florida2 +pushkin +valkyrie +chiefs1 +jjjjjjj +tasha123 +vanille1 +uhfaabnb +hockey16 +madryt +9632147 +hikaru +ploppy10 +alucard1 +reveur +welcome +110091 +1qwertyu +lakers123 +muhammad1 +greene +wrestle1 +darkman +beethoven9 +hannah! +yayaya +pajero +charly1 +vanessa12 +jeep +toilet +roseann +20 +tinman +newcall +ducky +alivioo +vuc7neyu0 +185800 +player13 +police123 +alexandra +123ert +diva +eugenio +niki +mbahurip +battery +jkljkl +uchiha +ovr220278 +blackcat123 +sexy1 +turtles1 +madrid1 +564335 +magdalena1 +andrea +mm123456 +edoardo +degrassi1 +sales +summer5 +weasel1 +annabel +killer4 +pussy7 +serkan +april123 +19561956 +pimp1234 +dogshit +charlie13 +dimebag1 +7418529630 +zzzzz1 +darkknight +december16 +buzhidao +adeline +fordf350 +bitch1234 +paisley +flower3 +gwarmonster +bartman +hunter22 +yemi19900911 +leigh +belmont +alesha +80 +johncena54 +654789 +muffin123 +meteora +popstar1 +ilovedavid +mibebe +nuggets1 +brandon10 +skank1 +shadow! +ekmzyf +prototype +cat1234 +peanut3 +pink07 +piffish +colibri +raluca +gfs2z6wb +kookie +smokin1 +homies +qazxswedcvfr +nicole6 +spolana +juninho +halifax +kindness +gossipgirl +kapej111 +mmm +book +qiciqdp162 +phx602 +hellen +elizabeth0 +loveis1 +sunfire +buddie1 +tortoise +jasmine11 +athens +michelle! +buddah +melania +ryan1234 +shitshit +supervisor +leticia1 +the +tigger21 +alex16 +anthony8 +angel! +butter12 +morales1 +dtxyjcnm +bhbyrf +roro1024 +zaq1zaq1 +electron +2wsxzaq1 +citron +dragoste +lucille1 +monkey09 +kangaroo1 +tennis12 +31081981rs +reason +password66 +050965 +amanda69 +123456789qw +comedy +poepen19 +jkjkjk +ilovejohn +locura +povlmly727 +nigger! +159753258 +swampfire +123qweasd +dontknow1 +shorty11 +arslan +pppppp1 +foolish1 +bible1 +radeon +realtor +lovemykids +p5415420 +jordan2345 +godisable +monkey33 +12345678z +valeriya +139381512 +anthony! +25393275 +volume1 +tyler3 +poser2 +happy1234 +1234567g +bball2 +behappy1 +jeremy12 +kassie +babymama1 +zander1 +roderick +dou +didine +weiwei +hambone +znt: +bon +monkey07 +jesuslives +groupd2013 +maggie3 +firestorm +firefire +uphill45 +68582988 +puppydog1 +69charger +frogs +11111111a +supa1906 +mamita1 +dede +monkey08 +eggplant +blunts +moreno1 +mustang01 +01011987 +bartek1 +mywife +fathead1 +lil123 +1abcdef +1q2q3q4q5q +choice +gummybear +anechka +jimmy12 +minecraft +19571957 +mierda1 +secret +dieguito +eli +vegas +cortez1 +xaxaxa +spyder1 +queenbee1 +paluso00 +whatever7 +shrimp +mjdsf11 +j4n4jel4 +shanice1 +rodrigues +18 +1amanda +123123321 +cumshot +brodie10 +acapulco +1952 +trapdoor60 +kristel +nascar20 +snorre98 +7seven +maggie13 +olitec00 +superman1 +248001 +sonoio +petram +ballon +mumdad +acts238 +linkedin11 +vascorossi +sharpie +bigpimpin +crazy101 +qwarty +jkiuztdftl57 +lovely! +paraiso +alex18 +justus +jenni +bob101 +connard +5children +swapna +wang123 +iloveyoux3 +trina1 +pokemon3 +thissucks1 +kitty6 +kiss12 +xantria10315 +batman69 +aabb1122 +gangsta12 +idiot1 +kuana230345 +ophelie +starwarsfan10 +taylor! +fluffy12 +civic1 +lindinha +familiyafamiliya +patience1 +lexus +viper123 +bluejay +pommes123 +5a8b9c2d +maxpayne +cksdnd12 +aksrms8010 +fiona1 +111888 +awei1616 +buffett +teddybear2 +pumpkin2 +policeman +futyn007 +gigabyte +lilili +bhjxrf +infamous1 +fruity +candygirl +uchenna +sable1 +bouboule +star101 +shayshay +rambo123 +niggers +lebronjame +frosch +alesana +0987654321q +gutschein +attack +blkdrag0ns +1598741 +supernova1 +finger1 +dragon9 +13245768 +justin08 +marilyn59 +blablabla1 +lightning2 +astig +topbull +astros1 +dakota123 +wrasloco11 +skaterdude +catdog2 +blah12 +luc +poilut +aa224466 +500016 +randyorton +singing1 +myspace00 +placebo1 +ulisse +jewels1 +lilica +brandon! +killer21 +ornella +usa12345 +jadakiss +fubar09 +nacho1 +angels12 +foofoo +myblocker +jesus +19941028 +mustafa1 +pissoff1 +jessica8 +rhinos111 +0147896325 +almighty1 +kokokoko +clapton +4826159 +26665806 +sverige +kar +teonamaria1 +fuckthat1 +candies +advance +volcano +asdf1234 +sn00py +mal +salem +124356 +marmotte +haloreach +hockey5 +juancho +water2 +courage9 +ronaldo17 +good4u +jiang8kevin +allmine1 +shaheen +destin +kokomo +ficken76 +avenged +jewish +bonanza +chocolate9 +dakota2 +dangerous12 +isabella +1272446 +loyola +seigneur +tiger10 +tiger22 +nineteen +jasmine4 +nerone +mercurio +mark1234 +bluerose +mis +looby123 +ice +sexychick1 +railroad +november25 +wildthing +anetka11 +recovery1 +rancid1 +chambers +fritz +zbychlas +allrecipes +punjab +axelle +cds04121989 +masterkey +1324 +princes1 +fucku12 +ray +fx-one +latifa +12345678k +pipeline +motorhead +happyhappy +icxkyb7972 +1daniel +yfhenj +londres +vitor1268123 +369369369 +rosales +september7 +asdasdasd1 +mamapapa1 +monkey17 +123456789qaz +sithlord +monica12 +1jasmine +skater11 +lena123 +1023 +araceli +wendell +kurwamac +healthy +povray14 +nfvfhf +don123 +glasses +1q2w3e4r +bloodz1 +lloyd1 +password123456 +music11 +vicecity +painkiller +159357r +aviation +849vak17 +kurdistan +peppers +ringo +lillie1 +q1w2e3r4t5y6u7i8o9p0 +mysecret +rockers +smokie1 +cutie01 +texas100 +www111 +saitou +4567 +killemall +altair +11121314 +focus +mutant +tony1234 +action1 +berry +mamikawada +aa261599 +bucky1 +jul +stitch1 +epsilon +alchemist +christmas2 +bigbear1 +killer10 +jessica15 +diamond +element123 +weronika1992 +a5201314 +2211 +tintin1 +62543234 +rodeo1 +sweetangel +ghosts +honda450 +antonio2 +scarface2 +icegirl +upperd7 +clovis +oreo12 +nena123 +128128 +thomson +@bigmir.net +jdd04257 +anfisa +maiden666 +catholic +j5644574 +doggystyle +trueblue +camilla1 +freiheit +twinkle15 +leopoldo +jetsmets +serdar +hornets +tenshin +chilly +19581958 +ashraf +b2spirit +emirates +jordon +valeri +1002 +konfetka +zaq1 +ehdgnl12 +abcd1234 +sipfhair +cheguevara +baller5 +doodlebug1 +aquila +nathan11 +football1 +пїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕ +m01759766727 +sandie +1867sb +summer00 +barakuda +neo123 +19451945 +baby2009 +vergeten +juju1987 +584521 +ernest1 +class +campos +april9 +neworleans12345 +marygrace +po918dg +tyrael04 +liam +kjifhf +william2631 +calgary +december31 +learning +clifton +400050 +pass1478 +jordan9 +norton1 +me1212 +superwoman +singh +rogelio +leika86 +keystone1 +luna123 +1905 +kara2711 +sonics +aug!272010 +noelle1 +062593 +jessi1 +green6 +choclate +green15 +2fresh +october30 +kissing +avalon1 +brenden +gogirl +homerun1 +vampiro +blabla123 +frontier +rosalia +corbin1 +katana1 +sexy4life +frisco415 +purdue +letmeinnow +party123 +wasted +naruto7 +1234567h +u83xu3u83 +kirkland +sushma +crack +vfkbyf +master69 +danielito +eli123 +101080 +candy5 +alain +honeybun1 +passward +spitsy16 +yggdrasil4 +pallino +n123456789 +dianna +stupid! +ss563563ss +carpet1 +voldemort +bamidele +lynette1 +angels123 +mazda1 +macdaddy1 +letizia +robert7 +attitude1 +poiu07 +iminlove +dinero +charly2004 +hannah5 +computer +dilbert1 +94246843 +shelby123 +ferret1 +crystal12 +superhero +jackmore1 +ohshit +susie +fathead +32342711 +james10 +toonarmy +wiktoria +stargazer +infinito +floyd1 +shriram +rockey +single2 +superman8 +coco11 +aliceadsl +madison +irving +kalyani +maryjoy +nomeacuerdo +52hoova +happy01 +idefix +gfynthf +sabrina123 +perro +cxfcnkbdfz +seminoles1 +cannibal +mnbvcxz123 +renuka +richardson +wealth +45678 +ashley6 +nation +qq1234 +myspace77 +pink09 +tigers2 +sandra12 +piepie +222444 +komputer12 +1olmetec1 +145145 +soccer88 +yfcn.if +robert +fb1907 +c6h12o6 +leningrad +musik +lalita +u8t6e4 +heavenly1 +mamika10 +david21 +deadly +satsuki +impact +fire12 +alleycat +yolo +ashley09 +football19 +poland1 +pollux +mousse +cookie4 +523456 +kevnwo128 +trackstar1 +ytreza +spongebob0 +crybaby1 +pauko97 +kaleb1 +abayomi +teenaa111 +staples1 +pessac +gogators +akademiks11 +denis123 +fourkids +cabbage1 +shadow14 +battle1 +ewelina +youandme1 +carpenter1 +fairy +seahorse1 +pie +natiichen999 +maiden1 +lover22 +dallas2 +vaughn +21052003 +jessica23 +fhctybq +tanzania +1cutie +goblue1 +james1234 +roger123 +125678 +27254931 +1loves +pass11 +abcdef +goodtimes1 +pepsi2 +halo219 +courtney12 +llama +dallas01 +swetha +marmalade +l1verpool +hockey21 +ldgend +iforget +moon123 +django +budman +newstart1 +concrete1 +cleo +ganja420 +andrea2 +charlie10 +threekids +david22 +hamburg15 +basketbal9 +werewolf1 +qq18ww899 +complete +hermione1 +ilovejoe1 +london01 +5656 +maximiliano +lost +hunter07 +nokia5310 +326598 +tarzan00 +alfa156 +truth1 +pentagon +85218812 +killer9 +killjoy +ipad +chocolate8 +nwolf72 +orient +buster13 +vicky123 +meow123 +pioupiou +h4t3cr3w +dfktynby +lauren11 +incredible +velvet1 +smb0512bz +luckyboy +tricky1 +steflio3123 +hello69 +198311 +001579238 +bharathi +michelle01 +94327579 +bettina23 +hunter4 +bucuresti +zerozero +cordell123 +411001 +29694419 +minimal +110034 +stani06 +werock1 +monarch +courage1 +hannover96 +heather +batman22 +bond +thibault +andre1986 +matthew4 +sentinel +nummero1 +black11 +summer2008 +fleurs +love30 +123456789101112 +yvonne90 +jarox1301! +seinfeld +love87 +kittykitty +sexybitch2 +farley +jordan99 +vfhnsirf +ashwin +john13 +cloclo +43922572 +mlb229 +money8 +notebook1 +bin +alvin1 +cacca +sex666 +shurik +santhosh +football27 +franca +heather12 +bl8lygb0 +alex2000 +homeboy1 +ayodeji +qazplm +starwars111 +ziggy123 +semangat +dizzy1 +breaker +kambal +biscuit22 +slipknot9 +together1 +ibanezjs +rainbow3 +banaan +green17 +haha1234 +hydrogen +kinomoto89 +pt120439 +fragolina +evgeniya +passw0rd1 +123321aa +mahendra +ludi1234 +video +maburro +mercedes +yomisma +ebony +skeleton +lara1308 +lokoloko +1zn6fpn01n +missy12 +ch0c0late +tigger! +121282 +cowboys12 +soccer05 +boobies2 +abhinav +felix1952 +medical1 +ilove12 +pa +110059 +whistler +maciek06 +jarrod +pokemon7 +markus1 +godlike +stumpy +gs1905 +superman4 +pakistan12 +nikolas1 +candy3 +farmacia +123321qwe +charlotte +mikemike1 +0range +hehehe1 +madona +boomerang +princess1 +succes +someday +kartoffelpuffer +ijrjkflrf +nickiminaj +passcode +ashley08 +barcelona +52253823 +m12345678 +spider-man +27412678 +sabbath1 +1nigger +agustus +matt1234 +raiders12 +mayquinn2 +1987123 +55665566 +wiseman +loco +sweet18 +q1q2q3q4q5 +david10 +devil123 +wwe619 +shalom1 +april3 +iloveyouso +198712 +gonzo1 +pugsley +dario +abc@123 +alejandro2 +zack123 +milan1 +agnes +redhorse +cherry13 +garbage1 +520love101182 +halo22 +mojojojo +515253 +doodles1 +chelsea7 +loyalty +smoker1 +1asdfg +illini +starry +linked123 +matyas2001 +leopard1 +barley +melrose +elise +stupid12 +spice1 +buttface1 +qaqaqa +1233 +hannahmontana +nothings123 +j0rdan +yumyum1 +12346 +love456 +pa$$w0rd +montreal1 +34343434 +tuputamadre +135792 +10200718 +ciccia +96101z +yasemin +jesusis +huskies1 +montagne +boxers +malvina +bowwow2 +leolong1985 +vodka +kelley1 +mental +braves10 +cutie10 +chris! +888777- +march5 +cannelle +qwertzu +love1314 +jesus1234 +21152117 +sandberg5 +ska02ska +d41d8cd +march6 +44332211 +malishka +6817zd57 +listen +ffffffffff +twiztid1 +lightpower12345 +nikita123 +bmw320 +300300 +misfit +000000000000 +chantel +somerset +1234567890123 +dell500 +duster +rfhfgep +superman +bella01 +jaiden1 +kissmyass2 +mandingo +lolly +nanou4552 +jammin +raprap +lenalena +blackpool +majesty +mommy7 +aladdin +vbienrf +hans4queck +vaibhav +l5l5l5 +qq123123 +henderson1 +saigon +openup1 +smirnov +hillside +gangbang +vale46 +caca12 +sunshine21 +tuangbi +123456az +girlygirl1 +zaq12wsx +kakashi21 +link +newjersey1 +maella1311 +2w3e4r +101086 +bertha1 +thebeast +102030a +197900 +1grandma +football56 +31337a +fysihz5g +messiah1 +hello01 +fenchel55 +thissucks +gaudens +saddam +l3tm31n +nashville +qazedc +killer +barbiegirl +1204 +junkmail +berger +custom +surethang +boroda +jcdenis1 +pennywise +ilovelife +madmad +morango +123666 +bunker +98989898 +evelin +098poi +robotics +brody1 +hockey3 +123234 +grayson1 +jewish1 +moose123 +watever +beast556 +riddick +dar +1america +creeper +finland +qwerty123456789 +a6543210 +paopao +orange! +mckenna1 +crowbird +gaylord +312312 +mu080295 +coyote1 +1234qq +techno13 +honeybunny +laska +nikki2 +shorty14 +nandini +yfnfirf +1freedom +hollister3 +622906268 +sad123 +pinguin +1234asd +legend22 +hampton1 +nicholas12 +220389 +emoboy +qq123456789 +2sisters +booboo11 +rose1234 +horror +ghbdtnrfrltkf +123456mm +cocococo +crackers1 +twelve +thecat +fktyeirf +110025 +1214 +manu123 +sedona +cars +231 +karo13 +rotten +jesse12 +123edc +1314 +pilgrim +ohyeah1 +britt12 +thriller +alana1 +treguier +sim +addl0223 +madden09 +sangeetha +mkal2707 +br00klyn +ilo +brown13 +shayna +monday123 +smokey13 +angelseye22 +farfallina +chitown1 +ilove3 +chief +cookies! +cole +buddydog +lotus1 +stefangreil1983 +jackjack1 +naruto5 +makenzie +0909 +limited +791159392 +monkeys2 +hannahmont +jet +hfleuf +121285 +lebron1 +priscila +redab1993 +letitbe +pelota +danny2 +myfather +virtue1234 +southside2 +bri123 +wheeler +julieann +aninha +zooyork1 +adrienne1 +serafina14 +4mykids +111680 +leonor +bou +brandnew1 +naruto9 +fuckit! +ladiesman1 +me12345 +heart123 +wishbone1 +redbone +dark123 +2kroliczek +total12scherz +baseball +1234567p +single123 +201 +nene +bright1 +abcdefghi1 +poiu0987 +cutie14 +jmoney1 +slash1 +lover14 +sample +hockey8 +stunner +cummins +ogplanet +tulipan +dracula1 +freeway1 +adams33486 +lakewood +chocolate4 +o12345 +12345678987654321 +bitch666 +010180 +marsik +crybaby +sweet17 +gabriel2 +fuckyou +111111111111111 +whoknows +kkkkkkkkkk +contra +sss111 +spez3012 +julie2811 +ch +lucinda +vijay +smokey420 +cutiepie2 +daniel18 +max12345 +mormor +chicken11 +f1uuhza723 +eve +moi +razjel1 +november8 +tinkerbell1 +cierra +a54321 +tapout +rose24731 +mildred1 +qwert54321 +pendejo1 +150556 +trainer +softball21 +studio54 +jasper01 +lisamarie +shortie +damion +getsome1 +kimmie1 +mickey +goldberg1 +reloaded +eva +wpcakir264 +r1234567 +wert123 +eatpussy +emilio1 +myspace88 +132680 +par +armstrong1 +cervantes +anthony08 +rooney8 +buddy5 +whitetiger +power12 +mickey3 +54321q +vader +joshua21 +4224035 +andreita +viola +mario140773 +accounts +asswipe +sunshine9 +manolito +64impala +badgers +alex17 +umbrella1 +mob123 +oojs4ykl +ruler1991 +paquito +dav +ramon +treflip +november24 +bbleo1zz +tendulkar +marilena +william5 +angel27 +oldnavy +green8 +legendary +rhodan01 +nathan +voltaire +fuckyou88 +guardian1 +weyersheim +honey215 +carebears +cool22 +ripcurl +linusd8 +vanessa2 +rainbows1 +depechemode +bandit2 +gidget1 +purple16 +dabears1 +01011988 +marko +axlrose +armorgames +superman01 +dkz1999 +lucie +sodapop1 +santamaria +father123 +m1chelle +pg260365 +mexicano1 +sexymama12 +bumper +121284 +sacha1234 +winter01 +mgreen39 +moderncombat +q1a2z3 +baller13 +stella123 +hola1234 +nazareth +christina2 +19810301 +november27 +zz8807zpl +theband1 +123459876 +nimbus +mendez +dance12 +december28 +rockon! +dora123 +tuxedo +nice123 +pizzahut1 +lucky10 +billiejoe1 +getlost +polenka1 +magazine +bootsie1 +beast123 +la +gruby12 +taiwan +jesus143 +babababa +duncan21 +olivia2 +ace +southwest1 +pomalo123 +rocky3 +863560 +theshit1 +somanypickles27 +forever3 +ahbird1984 +norma1 +01470147 +services +michelle +mil +moonmoon +chr +jujuju +latoya1 +dd123456 +191191 +vanhalen1 +leliane50934 +lmapacey +gggggggggg +smith123 +peggy +shorty69 +august2 +papatoma1 +forsaken +fudge +wayne123 +sammy7 +159487 +rabat1945 +333221 +optimus1 +rachel +imelda +aczx7812 +sadsad +chanelbag +puttana +hester23 +blunt420 +johnny1959 +rashad +masina +herbalife +jessica. +daniel16 +pussy5 +yancai +12345a +lovers69 +andrew5 +678678 +awesome2 +sexe +123456ok +madonna12 +hattie +saint +257ers +hello101 +oasis +damaris +desadesa +libby +bored1 +drifter +fuckme12 +onlyyou +sanders1 +blix729 +1234five +2password +nickie +monstercha +a1169619 +badboys2 +pascual +kitty101 +itisme +brooke123 +gab +bambolina +nottingham +softball23 +cubbies1 +marian1 +nancy123 +onlyone +4rfv5tgb +pokemon +lacey +edmond +puppies2 +purple9 +1tigger +purple15 +cowboyup +maxima1 +rangerover +3232547 +wrestler1 +castle1 +momo12 +przyjaciolki +beavis1 +morton +yellow! +123678 +viagra +moonshine1 +123zzz +zombies +stripes +sdream +christian7 +lenka +wigolf +hawkeyes +21864812 +satnam +tanja1993 +butterball +mexico01 +cooper123 +erotic +music5 +rosaria +fuckyou01 +iloveyou88 +bergkamp +50505050 +ahmad +ligabue +pookie12 +mpeater +wsxedc +sevgilim +jomacapa +crash +lolo12 +lilwayne2 +edmonton +hollie99 +advent +youporn +eastern +benfica1 +jesus23 +e2yfp41b +b00bies +8008070 +tkfkdgo1 +lacoste1 +zesh1412 +makulit +jasmine01 +ignoranto +henni1907 +hooper +music13 +dragon8 +1007 +monster7 +zac123 +crunch +escola +soulja1 +good12 +han +dark666 +faca210898 +northern +dogshit1 +grateful1 +december14 +goodmorning +lovebug2 +bff4ever +chris19 +flyers1 +yaoiisgrand +fineboy +221133 +rosco1 +haha11 +1ofakind +roanne42300 +murali +nokia3250 +allsop +candy101 +fantasma +01012009 +qw12qw12 +graffiti1 +rs11220 +pokemon9 +sokolova +clown1 +776158ab +one234 +phoenix888 +102 +jyothi +123456789as +sk8ers +lilmama2 +mexico7 +kerry1 +rover +alex24 +1234567n +marie7 +oliver01 +maldives +bubbas +baller11 +1205 +xlsl9963 +icetea +islamabad +aaaa11 +c1234567 +laurel12creek +1e+14 +kingfish +kfcnjxrf +bball14 +91866709 +2w3e4r5t +chutrung +malcom +tadpole +cavs23 +560001 +mase4ever +yoyoyoyo +deirjj +edmund +mom1234 +qwertyu8 +romy01 +1106782 +seanpaul +escobar +coco1234 +fucked1 +bangaram +kassandra1 +andrusic1 +yandi20080527 +manuel12 +ezekiel11991 +marek14michal +fuchurli +lovehurts2 +721521 +jimmie48 +raffaella +liverpool +monterrey +haggis +unforgiven +lancia037 +golfinho +davidoff +yanks1 +484066 +barker +jordan06 +fidelity +boomer12 +gambion32 +0icotpd785 +hateme1 +guillermo1 +trivium1 +treu14 +042945d +rakaii +scanner +qwerty4 +puma123 +landmark +dogg +ronaldo07 +november3 +arsenal12 +cosmopolitan +muffin2 +ice123 +ossi2000 +qyahzn +gigaman8891 +author +1shorty +hermann +alyson +101087 +yt +assface1 +cxy831126 +rocks +fabregas4 +bibi +lucky6 +bre123 +mufasa +117117 +keegan1 +mercy +ibicguwjic +comcast +heartbroke +sparky12 +mustang +carnage +apple11 +greatone +becker +monkey18 +trandafir +blackout1 +birdhouse +fossil1 +winter123 +delphi +saxophone1 +jes +121292 +floyd +101085 +87calis +metal123 +lucky77 +123abc +sestra +blue88 +qwe456 +josh13 +power999 +carrots +xbonesx +working1 +holler1 +boguska123 +tmvlzj12 +156156 +skillet +illuminati +w12101957 +snoopy13 +rover1 +black22 +lightbulb +milk +gazelle +1208 +emmanuelle +maddox +74699723 +super7 +jenjen1 +chandan +bball5 +jasmina +cal +cream1 +2933455 +michael18 +aguilas +wrigley +komodo +sig53num +shorty01 +baby05 +wubin007 +ballin3 +brebre +grine89 +popper +teetee1 +iloveu13 +8008beb +ruqueb +marvel5454 +covenant +00 +yamato +cierra1 +aaaaa5 +hotlips +kris10 +camden1 +butterflies +madara +thebears12 +doug +aimee +eragon1 +sammy13 +555000 +181920 +wan123 +black23 +20070509031 +asdfghjkl12 +789321 +james4 +1bigdog +bobcats1 +testtest1 +67529353 +46265216 +solo7590 +2pacshakur +bukola +forever4 +papabear +iloveu22 +marie23 +panorama +samsun55 +brother2 +assh0le +soulmate1 +pink08 +kylie +robert22 +lydia1 +crysis +prisca +peepee1 +italie +colgate +waldiw82 +salmankhan +skateordie +batman5 +robinho +icthus01 +123333 +michael08 +malik123 +malaysia1 +chelsea8 +tigger5 +chitarra +jm0753 +almario927 +thinking +dogs12 +jjjjj1 +rosa123 +kakaroto +eighteen +1102 +heterosexual +hardwork +meowmix +jamal +maganda1 +kira +smashing +mateus +poster +lapinou +awesome12 +wolf123 +monster5 +gisele +weekend +phoenix +giggle +makeup1 +mariama +sheshe +capecod +spiker +lucinka +alpacino +neopets1 +breathe +madison1 +tracker1 +waterman +thieric +arabella24630 +jigsaw +tigger23 +patron +chasity1 +guesswho +softball15 +justin18 +dominion +jojojojo +killer1234 +anjana +royals22 +junior3 +2727 +seatleon +2416101113 +calderon +concepcion +chinook +xred4654 +micah1 +rdukv46x +soukayna +hummer2 +lovejoy +bela2404 +edwardcullen +money4940 +aimee1 +alex99 +jr1234 +alterego +siempre +heinrich +america7 +anatoliy +khan123 +jose1995 +bingbing +power2 +chivas2 +120n2x +diego10 +cat15175 +winter07 +z1234567 +march7 +overkill +eightball +1zzzzz +soulfly +killa12 +michael15 +3d8cubaj2e +metro1 +ania1986 +chanelle +x12345 +098890 +mostafa +weed13 +lasalle +dipset5 +pluto1 +sandoval +red321 +jolinek33 +meatball99 +01011986 +110110110 +smokey11 +vfvfvfvf +ada +600041 +my5kids +000009 +philly215 +quake3 +slut123 +pokemon5 +hockey4 +monyet +lilli2006 +myspace16 +fishing2 +focus1 +superboy +pilot1 +myspace17 +seneca +1banana +tronwell +weenie +krystyna56 +newton1 +sinned +20072008 +whoareyou +23628221 +geniusv +raleigh +rksk3210 +71191926 +pri +festival +minister +simson +pranav +myboo1 +petting +yomamma1 +daredevil1 +sebastian106 +peace! +gautam +monkey +marie14 +slunicko +nitro1 +baby25 +angela12 +badoobadoo +b00b00 +cookie23 +jackie2 +oliver2 +jayden07 +cameron12 +royal +gobucks +panda12 +aja152 +trader +lionheart1 +buceta +dabomb +theodore1 +fifa2010 +he635789 +224488 +mm170667 +igetmoney1 +bears54 +freedom! +rayman +elite1 +lestat1 +shaney14 +marica +snake123 +85726648 +easyas123 +fallen_angel +colour +racerx +puto81 +jackpot1 +knackwurst8853 +mommom1 +852456i +400059 +pingvin +carnaval +110058 +pimp15 +asdewq +s12345678 +turtle12 +111444 +miki +3141592654 +irock +5234055 +volkova +dbrecz +nicole8 +betty123 +teetee +baby02 +veri1234 +lizbeth +pop168168 +dalbas73 +наташа +pinky2 +2246926 +frisco1 +hoffman +121287 +hello14 +money14 +parolamea +baritone +gennaro +0p9o8i7u +tommy12 +giulietta +1124 +james69 +ethanryan01 +kjiflm +jimena +paul12 +mikael412 +198484 +supreme1 +arianne +godim001 +pussies +tony13 +andrew! +lucky69 +istanbul34 +rockford +march9 +p1466186 +fullmetal1 +yoyo12 +independen +lovely3 +1215 +ghjnjnbg +chemical1 +babygurl14 +thedude +4me2know +croskey +sindhu +atletico +kitten123 +carito +lilsexy1 +salerno +bitches! +imsexy1 +caroline. +taylor14 +heather123 +accountant +1badboy +shania1 +carmelo1 +gdcc9921 +marshal +juan13 +bratz123 +michaeljackson +221 +wil +licorice +create1 +megafon +cradle +renee123 +adv23 +sammi1 +1111111q +444 +mayank +clarinet1 +sol +fiesta01 +abcabc123 +tomek +odette +kaboom +clochette +mammina +grandad1 +milly1 +ziom82 +gabbie +babygirl06 +ohcaptain +electronic +pinkpanther +friends5 +feathers +incognito +tkgsoo083bsr +volimte +lehjxrf +angola +heeren981a +nougat +ezekiel11989 +hallie +perry +vanessa141175 +shawty +d6ug7epz +noel +astroboy +teapot +253314 +alisher +nebraska1 +proverbs +grinch +kinky1 +marsel +mytime +kaden10 +cats12 +channel +4567890 +destinee +killer45 +shashank +spiderman4 +layla +freedom +sabine21 +daniel07 +lovemom1 +lilou +lilmama12 +cr1st1an +terrence1 +maribel1 +sampdoria +47593893 +skittles12 +ggg +ravens52 +kenya1 +proverbs31 +cars98 +bill123 +pakistan786 +kipper1 +bobcats +leeds1 +poiuytreza +dolphin7 +ilcerchio +mygirls3 +889900 +timfranzke +beans +metallica6 +freedom12 +01011984 +zippy1 +nataliya +wonderwoman +119911 +password? +jessica9 +15731573 +crescent +black21 +211 +qwertzui +justin69 +198410 +computer11 +mustang123 +deeznutz +pablo123 +tagesgruppe2010 +hockey15 +?? +speranza +md1998pb +cronos +ashley4 +mamina +kingjames +robert69 +jemima +gbgbcmrf +hans +nickelback +ytrewq1 +schokolade +marie22 +manjula +nglw9840 +chris06 +morelle45 +gilmore +wilma +charline +uae_boy +jp72l05w +baller10 +karaoke1 +pimpjuice1 +1947 +neeraj +renate +freemusic +jibopogie +redemption +november30 +columbia1 +taylor4 +robby1 +palomino +lucky07 +anthony07 +christo +camron1 +lana +fialka +fatboy2 +alexis10 +tweety3 +pimping +redsox12 +grazia +memorex1 +chester2 +hanson1 +monange +josemanuel +nene123 +shell1 +12312345 +12345678c +1209 +rapture +starship +yorkie +holycow +hermosa1 +jasper +summer21 +zaq1xsw2cde3 +enocnayr +football45 +texas2 +futbol1 +zk.: +51615801 +kaifer124 +blackhawk1 +raiden +acdc123 +020304 +estrada +yasmine1 +redskins21 +vitor1 +1948 +abc123123 +silverkey3 +8520 +clark1 +miguel12 +tiffany123 +namaste78 +maddie123 +j12345678 +slimjim +hiphop123 +dewayne +ledzeppelin +kolodiy +oscar2 +mia305 +dresden +hateme +wiccan +blueangel +tanisha +elmira +socorro +precious2 +airsoft1 +flower7 +miniclip +jonas3 +hernan +joseph3 +marvel1 +tater1 +sweethome +oliver11 +qwerty66 +dimasik +35365123 +jonny5 +blueboy1 +live4him +12345678b +527728 +baby19 +06lb18 +abercrombie +danika +defender101 +shannon2 +kasandra +love2006 +foundation +newvision +jack13 +108108 +299kgj8hgf +111111aa +neneng +asia +pink18 +splendid +hateyou1 +mexico3 +password34 +cayman +nessie +dale +prison +tania1 +haley123 +mjdh065 +welcome6 +webber +cutlass +bigboi +toaster +cg9600 +crazyman +22021988 +jadebibou +cheer08 +weewee +bob12345 +lahmy1 +baseball. +lumiere +justin07 +fluffy2 +toulouse31 +893208 +goliath1 +123456ss +faith7 +salsa1 +gerrard1 +airtel +nastya +zebra123 +qwertyu123 +what123 +trapdoor39 +madafaka +marykay +lllll +beeline +horny69 +abiola +john23 +maik1996 +ananya +barton +amina +perkele +cabrera +1236547 +utjhubq +maryanne +794613852 +tanaka +godson1 +kitten2 +rockman +979575 +mesedka +c0mputer +greg123 +domdom +jackson12 +zxcvbnm0 +197979 +nasser +lucky22 +papers +imissyou1 +woshishei319 +lahoumti +wow +lilred1 +dominator +olympus +allyson1 +aysa2423 +qwe123qwe123 +hondacbr +kxdw0980 +nashi1996 +master13 +dylan12 +1420839army +matt11 +110006 +federer +jolene +doctorwho +alex +fenohasina39 +kaulitz +love2000 +samir +12356 +maxix565656 +44f16f17f +iforgot2 +qqqqqqo +c00kies +buddy13 +ks120473 +rhino1 +sophie2 +anton123 +mclarenf1 +123443 +patch +chidori +november26 +motorbike +asassin1997 +guruji +taylor22 +facundo +1701 +sunshine23 +billiejoe +hippo +astray +kehinde +gal +nmt89109328673 +flash123 +nuclear +velocity +asd321 +80173rroom5 +midori +julian1705 +16246149 +savings +poot62 +soso +pangga +marques +560066 +sonysony +halo1234 +oluwafemi +fraise +wrestler +casandra +fireworks +bulldog2 +babi123 +junior5 +elizabeth5 +tayuya44 +julio123 +george11 +qwerty67 +pussy4me +ee19920528 +gremio +132040 +123456789000 +qamilek1 +chantel1 +renard +leloto +kiwi +xup6xup6 +lover! +89173371487v +qawsed123 +lh6209lh +987987987 +d1e234tp +oooo +112233qq +forgetmenot +vanessa +albatross +774517397 +15727666 +1234567890qwe +borec123654 +26r10d +magma9824660 +pussy3 +toutoune +sinister +315315 +b4272327 +inibif47 +morenita +klopik +dardevilk +dimas34rus +brinchen23 +tracer +8-9899578642 +chowder +nemo +tristen +212212 +9508402243id +89058895869cth +brown123 +fgjrfkbgcbc34 +kretsaha53 +cristal1 +rachel2 +hejhej123 +1loser +holuha00 +manchesterunited +123456* +mummy123 +vladcherktecktonik +eileen1 +101092 +lenny +jumanji +duke12 +huangfeisuny +brady +3tktkthth +silverfox +312881040 +james14 +lightbulb1 +emmitt22 +esidez57 +brenna +44442013vkkv +chimera +198312 +montoya +november9 +mymusic1 +bo1997 +littlegirl +qazwsx11 +1357reti99 +521125 +paula04 +dallas11 +bublik +lover7 +destiny5 +searching +camel232 +padilla +adsl120 +family11 +bullet695 +13301827475 +josh11 +g +looney1 +olufiz14 +brandy12 +25nuvaha +11231123 +soccer1234 +toni +summer +ramzes +1590736tany +rejoice +dental +harley13 +sarika +nj2mp73t +snoopy01 +80fefune +baraka +narendra +9121318barssuki +butter2 +taco123 +sonya +funtik +andrade +119872653 +ashutosh +k25061405u +juliadronina1996 +disco1 +qw10081973 +andrey1412ua +110096 +maine1 +usarmy1 +578322 +iloveu143 +marcus123 +3106934abc +william11 +05081980bija +19541954 +mortgage +blackburn +lucky01 +metallic +alexis3 +ethiopia +gualapmi +011151zangetsu +d04081999 +latrice1 +fragile +yfnfitymrf +reflex +payback1 +hacked +junior08 +lanlan1234 +51200000 +j: +ccopacell1 +pookie123 +jandre007 +laurie1 +islam +mustang12 +newyork12 +amnesia +cam123 +josh1234 +ktvt6tn9 +jeremy123 +moldova +cisco1 +cow123 +buzzard +ltybcrj1992 +dougie1 +loveme01 +class06 +esprit +m8a8vhr6 +beardog1 +080365 +hoodnigga1 +1urkilbth674 +casanova1 +nicknick +november6 +maggiemay +814336633 +dank420 +cameron3 +starter +asshole5 +pimp09 +bella13 +coke123 +madalena +1488 +mosima11 +honda2 +chemistry1 +lukas123 +min +mother01 +rastaman1 +kirik26trimyasov +ellie123 +ranjan +12three +gummybear1 +bullet83 +treehouse +sasin414 +asemmanis +alex08 +theboys +punky1 +japanese92 +settembre +mcr123 +dedamiwa +angel26 +iopjkl12 +qawsed1 +spanner +bristol1 +belinea85 +sexygirl2 +klg604 +usuck1 +blackbird1 +aspen1 +love31 +justin17 +ingo10477 +britt123 +soccer00 +junior8 +jessica16 +jesus4life +diplomat +juicy +freedom3 +fanculo +e123456789 +antonino +p123456789 +nevergiveup +tiptop +c3por2d2 +fuck22 +aquamarine +pasha +kimberly12 +whiskers1 +jeannette +zy19791201 +190190 +dusty123 +anushka +spongebob5 +gaby123 +austin +cyber +maks +andg1705 +q2345678 +xzibit +arsenal11 +comics +1pepper +honeybee1 +126126 +toriamos +mayra1 +kapusta +rolandia42 +fabolous +goodlove +newlife09 +disaster +jonasbroth +scraty98 +enjoy +matthew13 +shotokan +immanuel +asdfghjkl0 +royals +sassygirl +vangogh +dadounet +911turbo +semarang +lucky9 +poulet +mocha +vaemai31 +bella11 +jarhead1 +dianita +1abcde +potatoes +u79999i +alexander7 +hello21 +zxc123zxc +bijoux +susie1 +peekaboo1 +ju2002 +totototo +goaway1 +northside +211211 +moneyman87 +bimmer +queenb1 +clarissa1 +agnieszka1 +rhfcfdxbr +princess06 +comet1 +marcus12 +giuliano +patterson1 +1234567890987654321 +jayden2 +cristobal +snickers2 +scouts +ooooo +conpro73 +sakina +bitch16 +spider12 +pregmar2 +happy! +candy7 +inflames +hannah4 +123456789zxc +john2567 +database +nicoletta +sdsdsd +723723723 +maika2006 +iloveu5 +arkansas1 +26 +jesus4ever +login1 +aquino +fuckyou14 +hopkins +reptile +neptune1 +1basketbal +560043 +7eleven +110070 +bryce ++ +gayboy +joshua22 +justin4 +slater +chanda +chicken4 +imation +gudiya +ele +andi121382 +seymour +1111112 +t +sweet15 +019283 +was123 +giselle1 +redbird +kenwood1 +lookatme +1993ga4mi +13489277 +hotdogs +underoath +friend2 +donaldduck +snowy +shorty15 +mypass1 +ronaldo10 +etnxtxsa65 +kitty69 +transfer +killing +hohoho1 +a159753 +woowoo +chewy +jackoff +tiger01 +john22 +iamawesome +broadway1 +donato +jam +dopeboy1 +f +jess12 +patrick7 +schilf02 +banner +114114 +capitals11 +crackhead +01011982 +pimpin3 +lala1234 +money15 +zpaqrt2963 +shadow9 +cutie4 +ilovejohn1 +baby88 +shorty5 +gemelli +engel00007 +dodgeram1 +morgan +aabbccdd +bulbul +15516210 +vflfufcrfh +martinique +sandokan +iluvyou1 +joseph +1203 +milanista +hshn7669 +love333 +madelyn +gag5691 +jesus22 +clarke +rahul123 +eagle123 +happyday1 +kikikiki +13marino +bloods5 +66613666 +mischa +koupelna +major +oregon1 +monty123 +piccolo1 +silver2 +grecia +tiramisu +euphoria +chelsea01 +jessica18 +tucker12 +please123 +111188 +18297649 +bulgaria +jac +satria +marcio +leilani1 +1orange +shiningeagle +locked +harley07 +rajeev +redwin3d +carroll +llllll1 +patrick3 +301285mn +frederick1 +salama +121233 +cookie22 +blue25 +biscotte +naruto924 +sonicx +mnbmnbmnb +rossia19 +freak123 +mara +osvaldo +ramos +198282 +robert23 +tink +wolf359 +sonyvaio +sisters2 +sutton +starwars03ja +burrito1 +sainath +45533990 +harley08 +srikanth +fkbyrf +allstars +fu00190 +samson123 +love2012 +sober3 +wm0001 +hhh +josefa +december24 +shadow +kristi1 +wanderer +binky1 +cookie10 +aldebaran +michael09 +stubby +angel02 +nvidia +54226269 +120689 +nthvbyfnjh +galant +mydream +marisha +mad123 +johndoe +teufel99 +vidaloka +garlic +swansea +t1234567 +ilovejames +password42 +mandarina +inter123 +mona +escorpio +master +dbnfkbq +jetski +xenosaga1234 +david69 +mob4life +telefon1 +ilovedogs1 +smurf1 +55chevy +yellow23 +cassius +rohini +reality1 +emeline +111985 +uhbujhbq +band123 +sweetgirl1 +darwin1 +oieoie +snoopy +blacksheep +loveme21 +tabatha +iloveher2 +kamil555 +blackboy +sanjose1 +121088 +isabell +1aaaaaa +better1 +peugeot206 +happyman +apple7 +november28 +search1 +menace +fuckyou08 +snoopy11 +spiders +memememe +myaccount +petrovich +gabber +burnout +mexico5 +olive1 +69664848 +kahitano +joana +blade123 +virgilio12 +linkedin01 +1234567e +audi +roscoe131 +fantasy7 +suckdick1 +fairy1 +concetta +lakers12 +kmk420 +sofiane +jayjay123 +misiek1 +ilovemoney +blackbelt +nicole69 +smithy +chairman +topdog1 +pieter +teejay +poop101 +trikers21 +december29 +radical1 +therapy +12345789 +angel +runaway +tielandros01 +happy4 +thomas21 +srbija +qqqwwweee +daniel17 +130989 +approtec +warwick +brighton1 +stargirl +rosana +dsadsa +number22 +rubberduck +dutch1 +89272585 +gillian1 +1hateyou +missing +viet12 +herbie1 +vampires1 +258147 +honeypie +biteme! +ghjcnjgfhjkm +bush25 +impala1 +zz123456 +ouioui +19551955 +callme +8phrowz622 +austin7 +gunit50 +emmawatson +andrew14 +killerin66 +angelgirl +court1 +merdeka +station1 +diamond5 +pisces1 +christian0 +farside +dancer! +pinpin +bbb123 +111987 +megan12 +love86 +jnkwear1 +alex12345 +tigers11 +youknow +falp5050 +softball! +civic +1q2a3z +bank24 +sammy11 +photo +170845 +abcdefg12 +29271188 +tarantula +angel675 +ballack +cadbury +november4 +jason13 +elcubano1893a +urdg5psk5 +doggy2 +ashley +ashley07 +1matthew +mantis +player23 +tigers123 +terry123 +frost +andrew +avenger1 +thanks1 +lucky23 +uzumaki2 +bro +123580 +daddy5 +slimjim1 +loveyou7 +nonenone +htown713 +197878 +kmzwa8awaa +chicca39 +karishma +27140621 +ltdjxrf +ganster1 +67890 +brianna12 +zxcvbn12 +leroy +kokot +rfgbnjirf +xiomara +secret! +leader1 +christoph +q0tsrbv488 +tropical1 +grasshopper +alan123 +95135876 +secrets1 +meimei +cuervo +musift10 +bremen +password1 +source +goku +monte1 +love98 +twilight13 +naruto14 +playboy13 +wwwwwwwwww +shannon123 +chango +fucku! +ozzie1 +jaw138whet330 +jaisairam +caterpillar +lydia +gaspar +eagles10 +2233 +73439984 +pokemon1 +lucien +kuwait +venom +hannah99 +fugazi +residentevil +8616695 +clyde +83742222 +iloveu. +idiota +haylee1 +123963 +james15 +kevin13 +poopy2 +32flame +asshole. +puddles1 +alyssa01 +a696969 +poupou +rex123 +heitor250493 +metropolis +saint1 +r041stcu +dlfaor09 +vfhbjk1801 +poohpooh +infinite +valentin1 +1234567w +brandon14 +wokami +rider1 +czsxumtf +diva12 +golf123 +abc123. +cooter1 +vitolino10 +audiopel +verena +glacier +blood12 +dickens +qqqq11 +kevco33 +littlebear +wrinkles +amanda10 +baller15 +11223343 +strelok +vector +luckystar +johana +hotdog12 +pussyeater +jokers1 +cookiemonster +hi123456 +katiebug +seaside +brandon8 +valdez +daddy11 +female1 +columbus1 +sk8ing +bas +zaphod +medina1 +greenday! +shanna1 +luther1 +cyclops +696969a +wwwww +princess25 +woody123 +carollo12 +tinker123 +michael07 +p@ssword +fab +goodwill +switch +bigmike +bunbun +abbey2010 +876543 +shine +smiling +ozzy +gutta1 +engelchen +valentino1 +nico39 +raerae1 +tokio1 +akasha +angeles1 +nederland +beastie0 +nathalia +nolose +magno456 +pfkegf +1114 +gopher12 +owt243ygbh +mustang3 +three +aaaa1234 +support1 +nodoubt +tomas1 +fishman +brammi1 +peleleco +yyyy +leno4ka +karlita +anastacia +daniel! +skydive +112200 +pacheco +vandah +lin456 +ernie +299792458 +zimmermann33 +yeahbaby +paddy +badboys1 +berlin +daniel4 +grinface +charlie8 +pidaras +mother11 +london2 +sherlock1 +linkedin4me +102010 +karlos +01011989 +king22 +capitan +tigger10 +tangina +ghjcnbnenrf +sunkist1 +manuela1 +packer +moomoo2 +hunter69 +march2 +1lovers +mom101 +dzxtckfd +scooter12 +654456 +comando +kavkaz +bradford1 +yoshi +dei3mutter +earnhardt +marbles +sha22una +1616 +cooldude09 +reggae1 +lilone1 +13579a +gerardway1 +19960122 +blood2 +andres123 +chica +pacific1 +111116 +fosters +softball6 +emotion +furball +ballack13 +kendrick +bugger1 +snowwhite1 +chinese1 +kolkol90 +nicole24 +newdelhi +chess +256256 +irock! +whitepower +loplop +22janv67 +undergroun +mariage +lucky14 +nhanngu +9198425200 +pimp07 +197600 +120588 +casillas +w3wjnhek +zhenya +wright1 +summer2009 +auckland +560017 +sha123 +stallion1 +redsox24 +kenshi21 +con +tttttttt +robert21 +hawkins +476730751 +12345678l +senthil +linda12 +01011983 +cali +highlife +elizabeth4 +ltymub +500034 +mojo +chino +pianoman +wildlife +666satan +rolling +dancer11 +skater3 +sc00ter +gargamel +120789 +59230120 +kardelen +mauro +oluwatosin +volvo1 +sexual1 +tvs3108 +jesica +flipflop1 +perez +kocham +peacemaker +pitapooe1 +orioles +1getmoney +beijing +amanda7 +hijodeputa +199000 +ralphie +jellybeans +vesproongh12 +vladimir +king21 +3456 +erwin +gabriel +ryan01 +150781 +lauren! +hollow +wendy123 +palmtree1 +caroline +jacky1 +600017 +7heaven +jorgito +ravindra +howdy +leedsunited +vadimka +diabolik +pourquoi +website +brm600 +carlita +bandit +march8 +puddin1 +khongbiet +ayanami +alina123 +pass1234 +brandon6 +keke123 +nihaoma +refresh +jhonny +gre +girlsrule1 +ricard +super2 +musashi +alexxx +thursday1 +dmsgk0103 +2q2w3e8r5t +grendel +gracey +marie15 +travis12 +kevinbg01 +goodyear +774411 +yana +mindy +desktop +butler1 +robert5 +3tutso24qf +just +hyperion +tank +worker +pepsi12 +apinoy +brandnew +janine1 +alex69 +delivered +caracol +sophie11 +broker +whatever3 +sc00by +chrono +shady +440226 +jayhawk +fake11 +skittles2 +valkenhayn +ripple +carlos01 +reagan1 +xerxes +nofear1 +ural +ballsack1 +starman +63245009 +comanche +umit1406 +goldenboy +karappinha +lowell +saleen +magno07 +skater8 +cfif +jacopo +brook1 +theend1 +minecraft123 +umberto +hotsauce1 +mordor +webkinz1 +blind1 +pringles1 +strobe93 +bryson1 +ihateyou12 +buddys +mycomputer +iloveyou00 +yacine +sanfran +sean12 +260686 +triforce +fucklove12 +123qweasdz +opendoor +133113 +familyof5 +koolio +dinner +ballsack +tomek1 +111986 +pioner +hunter21 +hovno +x8coqx1f1zh +spikey1 +123159 +laura12 +2626 +brandy123 +jaypee +ganja1 +qsdfghjklm +socks +baby03 +1cowboy +aaa000 +xsdsxs +hamtaro +kristian1 +chowdary +jkl +babies3 +hunter09 +manana +mor +thunder123 +campanita +abbey +lovehim +bigben7 +realtor1 +lancia +198211 +39073588 +cocodrilo +cheyanne1 +vesper +jackson3 +tech +redsox07 +120286 +jesus. +vinayaka +smooch +almeida +dance2 +nokia7610 +alex06 +qazxcvbnm +pimpin123 +astro1 +gobears +hardy1 +poopface1 +cobalt +pitiponc +ocean11 +cheer09 +sheep1 +bernice1 +crap +carly +tiger21 +happy6 +fox +calendar ++++++++++++ +ama +chester123 +1101 +mintal24 +anapaula +marcus2 +gunther1 +12345677654321 +sexy77 +fuckshit1 +marie5 +110049 +12qwer +82597971 +jenn +bball15 +121087 +honeymoon +jackass12 +requiem +republic +4friends +taichi +bathroom +5550123 +biology1 +jemoeder +boxer +v3xafy4k3y +football42 +angelic1 +0123654 +400080 +sunflowers +money99 +randy123 +enamorada +demons1 +sexy45 +nicaragua +maddie12 +1winner +198212 +hewlett +namour +electro1 +magodeoz +1qaz3edc +jenifer1 +thing1 +january12 +sebastian2 +math +sixtynine +cheeks +aaaaaa6 +sayangkamu +neville +fritz1 +connor01 +andersen +hustla1 +tickle +vtldtlm +cincinnati +profile1 +leeminho +metallica +newhouse +ppppppp +125478 +kristie +hornets1 +fresno1 +greatness +steven01 +bear11 +danny13 +inlove2 +satellite1 +basti_1014 +peanut7 +paulchen +5stars +junior23 +1thomas +oldnavy1 +rerjkrf +babyboy13 +1sexygirl +jardin +filter +loveit1 +cj: +sunflower2 +anna1234 +family +jbond007 +faster1 +carcar +teddy12 +parliament +generals +121984 +christel +baby2010 +gagoka +fun4me +girls3 +peanutbutt +magica +pinball +westside12 +alissa1 +hardon +bolivia +gaetan +30seconds +1104 +keaton +lavalamp +10971199 +ccc123 +ganster +1ty2an3ja +01233210 +d9189498 +richard3 +098123 +john01 +$money$ +stafford +mystic1 +cristine +heartbeat +lipy110593 +slasher +hongkong1 +1queen +endless +futuro +bonehead1 +carvalho +thunder12 +jesper +dblock1 +silver7 +gamemaster +001234 +michael17 +basil1 +herbsmd +maple1 +timeout +hottie22 +g123456789 +candles +melissa7 +28 +keke12 +eastside5 +butter123 +z +atticus1 +blue18 +121416 +zmx870919123 +str +danzig +fester +babaji +brasil +vball1 +truffles +1103 +ambrose +rivaldo +jackson1 +peanut13 +1lovely +poppie +1949 +christoph89 +cnfcbr +120589 +toocool +baybay +mike10 +maxie1 +bullshit2 +march4 +01012001 +magpies +puravida +joshua5 +cherry7 +me123456 +210210 +yomama2 +raumschiff +harley06 +backsdau +twilight2 +lourdes1 +thecrow +gypsy +)ryan +pogi +92246247 +napster +judy +1903 +alien1 +eliane +iloveu +sunshine. +gladys1 +monkeys123 +naruto22 +560068 +jennifer1 +chispita +susieq +money! +yesyes1 +allegro +purple17 +ragnarok1 +bikini +nashville1 +vivaldi +shikha +120587 +venkatesh +xx123456 +gardner +jmoney +joseph13 +555999 +hockey18 +copyright +paintball2 +daniel08 +6661313 +toby12 +kujawka98 +messina +booboo3 +familie +loyalty1 +skulls +whatthe +philippines +kayden1 +batistuta +february1 +spongebob4 +justin6 +jellybelly +bloodz +emmett +cannabis1 +omgomg1 +rustydog +tilly +hurricanes +angelface1 +12451245 +diablo123 +bender1 +lina +167943 +cooking1 +beruska +lollipop12 +shadow0262 +cash123 +joonah +747546 +angel03 +bnm123 +dogfood1 +milkman1 +master10 +willis1 +sexychick +pikapika +she +1school +cannondale +martin2 +dogwood +oceano +verygood +alexander0 +gaygay1 +mario2 +dakota11 +ponpon +101288 +football81 +skelitor66 +gabriel12 +juliocesar +purity +tucson +soccer02 +vernon1 +siddharth +sunshine123 +dougal +nananana +elcamino +venture +passer +choppers +barney123 +2121321q +brooklyn12 +110009 +fofinha +horace +tra +camels +kazanova +lovehina +12101210 +meatloaf1 +keyblade +63145151 +bearcat +natashka +dotcom +juillet +woohoo1 +muschi +fuckit69 +vinny1 +timosha +sami +michelle19 +3doorsdown +workout +l58jkdjp!m +w1970a +belinha +pepper5 +lpz93ssskqw8q +sandy12 +seashell +110022 +liz +talk2me +babyangel +fag123 +tweety01 +1234567890p +brenden1 +jonalyn +merlin +198222 +honda12 +120687 +sinaloa +darian +paige123 +daniel. +kelebek +fallout1 +bunnie +analyn +mamatata +vagabond +caleb123 +ninguna +justforfun +1kitty +audi1991 +casa +fandango +star16 +cheese7 +weirdo +keeper1 +violin1 +mafioso +banker +benedetta +guyana +death13 +009009 +slim +2boobies +mexicano +mauricio1 +military1 +12231223 +gohome +999777 +goodman1 +baguvix +gra +4freedom +mer +xxx111 +karim +smeghead +fancy1 +qvo78evm +nate123 +isis +t7u9hx +tito +polinka +m1ul9x9i20 +signature +.ktymrf +120788 +graces +anisha +alizee +mother4 +5610405 +m0nster +panpan +686611 +password12 +superman9 +werilopert +repytwjdf +respekt +boston12 +tyler10 +zodnat +piggy123 +loxpider +louisiana1 +1234567f +113322 +555551 +dixie123 +batman21 +newspaper +tata1964 +volcom123 +wwewwe +soccer03 +branden +love2hate +sss123 +123www +alex09 +a12b13c14 +ingeniero +beastie +ya623349 +celinesimon +1jennifer +donjuan +27 +peachy1 +nadegda +sweety123 +king10 +bh90210 +longlong +olivetti +tonyhawk1 +home12 +nick01 +nicole88 +wweraw +joker69 +gamers +money24 +ss123456 +maricon +hate123 +gambler +mjordan23 +pollito1 +1badbitch +goodies1 +andrea01 +mike14 +roosters +vikavika +azacos +nothing123 +manutd7 +ebeans +adidas12 +qazwsxedcr +balboa +kissme12 +050607 +katelynn +fishes1 +zoezoe +qw12345 +rosetta +pomidor +myworld1 +interista +harley +angelgirl1 +yousuck! +matchbox20 +pass@123 +joshua23 +jonas12 +edward11 +123cat +odyssey +vicekw +delaney1 +babyblue2 +allan1 +samantha11 +pink17 +cheese4 +delight +thedog1 +barbiedoll +cool23 +mod7tygrysow +chitra +michelle10 +polpetta +scarface12 +marcelle +li0903 +hhhhhhhhhh +seaways +01 +emopunk +8675309a +j0nathan +freedom08 +thekid1 +30303030 +tyler7 +wingzero +frenchie +fishy +yellow01 +chukwu +james09 +blessed1 +silver11 +roman123 +deleon +ginevra +osiris1 +glenn1 +lashay1 +1125 +askimsin +113456 +monkey25 +norwich +booter +december7 +sanantonio +yenyen +rakista +lovebirds +pan +salamat +hott +emi +toietmoi +shelby2 +michelle5 +kill666 +lol123lol +wareagle1 +pippen +12233445 +konijn +alexus +cholo13 +sweet5 +james07 +tucker2 +ilove420 +playmate +cowboy69 +maggie10 +baseball07 +brian12 +1buster +fripouille +blackboy1 +happy12345 +villa +preety +connor12 +niggas +dagestan +12341234a +hero +chatte +program +hello +december5 +super5 +korona +zzz +bubbles11 +skull1 +tomato1 +malibog +im +123 +passwords1 +dancer13 +pokemons +gobucks1 +avenged7x +121090 +white123 +sarah11 +kiran +masterchief +12152325 +1brother +tony11 +astral +knicks1 +sheep +ankara06 +jesus08 +govinda +franco1 +cyborg +007008 +hokies +ivanka +baseball1 +moo +milo123 +jackass3 +feniks +i12345 +010191 +cowboys123 +baby20 +mateo +jerico +dada123 +naenae1 +golfgolf +emokid +andrea11 +1029 +castro1 +hate666 +brandon22 +snowball2 +dor +bessie1 +sensation +anita123 +gladiator1 +billy2 +a123456b +soso123aljg +1tweety +adam11 +jujuvivi +arwd89 +irisha +huhuhu +soccer44 +lfiekz +jordan05 +sky +futebol +jb1234 +888888888 +wer +220a220a +excite +abenteuer +h123456789 +cherry69 +tiffany12 +dennis +dct +stormdogs +alpine1 +qazxsw2 +dexter123 +dbnfkz +omgomg +supermanboy +hallo1234 +azsxdcfvgb +fullhouse +lasvegas +sukasuka +qwe123123 +justme2 +888777 +protection +azazel +cards1 +galadriel +pilot +forfun +naruto1234 +saleem +koolkid1 +melanie +free4all +mybossmyhero1 +napoleone +sugars +taylor99 +nascar48 +blink-182 +killer101 +brenda123 +bronson1 +norris +flego0815 +10101990 +rebecca +west123 +jaja +lovemusic +nairobi +3647226 +fuckoff666 +112255 +mexico14 +monster11 +tatertot +chillin1 +football52 +beta +1226 +padlock +f1f2f3f4 +141 +!qaz1qaz +venezuela1 +kathy123 +iiyama +chantal1 +1220 +hakeem +yjdsqujl +010190 +hellsing1 +justin09 +xyz +reklama +geronimo1 +satriani +ybrbnjc +urmom +blondy +rossana +foxtrot1 +andrew4 +poopie2 +1357900 +10101987 +pinetree +946hvt +economia +121986 +penner +poopoo123 +jojo11 +volcom12 +rocky4 +cicero +121312 +william01 +jacob01 +poiuytr +gulliver +cavalier1 +forever! +1323456 +daphne1 +52525252 +dahlia +ayodele +1q2w3e +reallove +lovemyself +121987 +lights1 +rerehepf +witch1 +december27 +raketa +brownies +stellar +lilmama123 +lisenok +vbkfyf +08080808 +buttercup2 +lonnie1 +ers +boohoo +pokemon13 +mayflower +411038 +a12345a +january13 +cccccccc +choco +everett1 +csyjxtr +36363636 +turtle123 +gloria123 +bitchs1 +vasile +krishna123 +august5 +karol +sex6969 +helmut +password2 +asshole7 +vintage1 +willard +secret7 +secret +sexyass +planet1 +gigi123 +december26 +margera +333111 +helper +7783757s +nadezhda +momomomo +sakshi +killer14 +tushar +560008 +corndog +101084 +north14 +1201 +madeira +thunder7 +jamie12 +1monster +myfriends +paco +gooner +harry12 +slash123 +keekee1 +hotwheels1 +tristen1 +escape1 +fanny1 +nevertarget7 +775533 +bigdaddy2 +love<3 +james08 +julian123 +helloween +upyours +rocky11 +lucrezia +trinity2 +peacelove +nyjets +bebebe +caveman1 +cor +2212 +elizabeth! +ass1234 +deathrow +slappy +elias +1christ +oldman1 +windsor1 +danone +dream123 +yzerman19 +highland1 +kid123 +devin123 +element12 +peaches123 +tapout1 +lili123 +casimir +macho1 +120488 +celtics34 +solutions +assassins +x7vs8mxg +151 +wocaonima +football66 +simeon +12345670 +nguyen4thewin +dublin1 +1003 +12345ab +samantha3 +twilight! +meowmix1 +yasmeen +jenkins1 +colasisi +naruto3 +redwing +munchie1 +eagles11 +morozova +christian3 +jason11 +six666 +rogers1 +lalala2 +zaqwsx123 +rafael123 +alphaomega +yj2009 +182182 +ilovepink +playball +open4me +polonia +sprocket +michael16 +defiant +rottweiler +antonine1 +fotbal +ser123 +peace7 +august4 +candie +rastafari1 +david1234 +privacy1 +158158 +nbvjif +juliet123 +freedom09 + +dragon14 +malaya +campus +sexy33 +sweetypie +darryl1 +nathan23 +jaguars +lover01 +obama09 +bre +максим +123456789@ +alex88 +k47rizxt2g +hippie1 +rocknsock1 +512512 +perlita +p939468 +1025 +jasmine1 +zydfhm +jamesbond0 +heaven2 +cheese5 +hellyeah1 +carlos11 +bombon +ashley. +richard12 +kahuna +wormix +mikmik +aaron2 +jessie2 +aceace +mormon +cobras +nutrition +december3 +blackangel +cheddar +resistant50m +1234o8o +avril1 +honeybear1 +douchebag1 +sayonara +ballin123 +bugaboo +sticks +robert10 +cbcmrb +20102011 +person1 +70142021103 +naruto23 +joker2 +casey2 +contreras +mommy6 +rachel01 +intel +111111z +drpepper23 +desperate +smiley123 +tuffy1 +angels7 +brodie1 +161718 +ludovica +qaz1234 +muerte +hendrik +blessme +malakas +babmicmar +ceasar +shadow6 +taylor6 +manning1 +tanner12 +black6 +morado +abcdabcd +lynn12 +game123 +poop13 +hannah22 +gangsta13 +qwerty555 +fr33dom +yellow4 +198610 +500003 +canucks +arsenal10 +hoihoi +saved1 +minnie2 +lipstick1 +kkkkk1 +theboy +lepidus +merhaba +968574 +windows123 +181181 +hunter06 +rose11 +liliane +159123 +metin2 +babyboo2 +dupont24 +rocky7 +epiphone +shadow666 +741236 +mailru +hawks1 +westside2 +tigre +belle123 +master7 +anakin1 +jcfs32014 +250588 +pink88 +burgerking +good4you +somierda +america11 +dmoney +frankie2 +touchdown +inuyasha2 +loveme4me +giuseppina +250250 +sexo69 +90801 +cooper2 +packardbell +barney +classof11 +54545454 +joshua19 +brandon1 +tierra +pool +1228 +mortgage1 +1joshua +daddy13 +197500 +1thursday +iloveyou33 +allah123 +marcelino +sullivan1 +jaybird1 +kevin7 +fyfcnfcbz +boner1 +looloo +kristina +niagara +clara1 +yingyang +purple. +bazas52 +ladies1 +drakula +things +shampoo1 +export +martin01 +wildflower +baseball99 +kamil123 +chelsea1 +fktrcfylh +marie16 +fucktheworld +jesus111 +cacacaca +292tom +alexandre1 +sonic2 +all4love +millwall1 +jalen1 +l1qoh9wq2u +master5 +aquarium +natalie2 +cattle +kailey +chris8 +okokok1 +plants +choco1 +fuckme3 +dennis12 +tigger4 +111984 +flatron1 +jennifer3 +barber1 +gracie01 +eagles2 +lectures +ceckbr +anna11 +paranoia +andy1234 +friend123 +96132925 +junior22 +calabria +rrrrrrrr +elise1 +timisoara +chicho +bowler +cocktail +12123 +bobdole +g4life +micky +wood +november29 +010203a +level27 +steelers12 +800001 +net +foxracing +bud +mutley +alex2010 +patrycja +baby2007 +tumbin +rosita1 +0931541082 +321ewq +premier1 +timmy2 +hahaha2 +olympia +snowbird +direct +checkers1 +theman123 +111111m +guerra +4561230 +summer04 +social1 +hhhhhh1 +muneca +bichon +accord1 +war +sweet11 +booboo13 +vfhbyrf +doggies1 +david14 +lumina +angel143 +120590 +australie +schoolboy +bouncer1 +canada12 +yankees123 +baboon +password92 +hammerhead +bonkers1 +egghead +stockholm +400607 +qw12er34 +booboo22 +120688 +hilltop +killa2 +jessica6 +happyness +ltkmaby +stargatesg1 +dylan2 +skater5 +minnie123 +hottie23 +millionaire +appletree +schatzi1 +chenchen +111189 +password93 +cisco123 +dfghjc +fuckoff12 +angelique1 +050585 +aabbcc123 +cody11 +sexsex69 +granite +steven11 +chocolate0 +300000 +teamwork +hotdogs1 +test12345 +1107 +mussolini +123456lol +pinky12 +taylorswif +sneakers1 +135799 +flexible +sabaka +1218 +latitude +communication +colt1911 +withoutu +nokiaa +army +santander +v1ct0ry +411027 +smiley13 +batman10 +pointer +minnie12 +mumanddad +supriya +zafira +dollface +120586 +kkk666 +matthew8 +cara4com +summer4 +jonatan +abdallah +kumari +chowchow +groucho +gizmo2 +sabres +147258a +cristiana +hunter +airsoft +master22 +payaso +jade12 +sonnenblume +mapamapa7 +250585 +nathalie1 +tiny +101189 +jordan16 +avalanche1 +logan2 +drogba11 +fotografia +monita +blackheart +william +lollipop0 +chivas14 +badakhshan +paparoach +donatella +omega123 +charles123 +bitch9 +1432 +family10 +joseluis1 +hakunamatata +radar1 +rodman +december30 +password123456789 +gangsta3 +1134 +guitar7 +120489 +spiderman5 +graceland +aaff +becky123 +taylor08 +sweet10 +777000 +159963 +223311 +dbrekz +sixsix +mavericks +marie10 +120690 +180888 +3762352 +rockstar! +ericson +1234qwerasdf +wisconsin1 +shorty101 +macross +flora +hoosiers +werdna +chelsea10 +christine2 +cunt123 +shitfuck1 +default1 +memyselfandi +rbcekz +minchia +bambina +110048 +pepe123 +medellin +sunny36 +cessna172 +bowling300 +buster22 +jakub +andrzej +derevo +2much4u +zv_!80lo +spice +chester +ranger12 +butterfly +master77 +nbvcxw +katia +3434 +griffey +gonzo +serebro +monkey +liberdade +1105 +gallagher +casper13 +jojo1234 +jazzie1 +tititi +open1234 +01011970 +hunter23 +tricia1 +chucho +lachlan +cheer2 +michelle22 +sommer1 +dakota +lakers2 +sujatha +1005 +morrissey +brains +mama22 +trapper1 +balls123 +makoto +joshua08 +wibble +austin99 +123 +elena123 +brandon15 +peaches12 +micron +ghana +slutty1 +johncena2 +13311331 +klondike +family! +bball33 +marie21 +luckygirl +remo1d72a +coconuts +wrestle +sarahjane +hotgirls +tyler4 +wellness +antoni +nicole06 +45m2do5bs +essence1 +qwerty89 +brandon9 +cesar123 +spongebob! +luv +kukolka +retired1 +vladvlad +nicotheo +camaleon +bean +jake13 +sexy4u +bonnie +zmf1704c +wawawa +haslo123 +hazard +badass2 +erika123 +ros +111222a +cheer! +indonesia1 +cdtnjxrf +belladonna +daydream +gungun +ceckbrcerfkbxyjcnm2 +bateau +hehe +tonytony +elephants +iklo +seccion33 +maxi +bettyboo +mewmew +negro +lonestar1 +barron +maumau +internet +aspirin +aqswdefr +sanjose408 +dragos +hollister7 +jediknight +martino +maximovie +branden1 +sexysexy1 +yakuza +snow123 +enzo +121085 +gaby +boner +fart123 +1james +eagles20 +gomez +fernandez1 +draven +cashflow +antonio12 +526452 +january11 +crf450 +bartender +june06 +2daughters +matthew6 +enfants +brooke2 +portsmouth +faith2 +hahahaha1 +andrew15 +zelda123 +martin6 +070787 +lassie1 +dudeman +4r3e2w1q +minecraft1 +chantelle1 +alex1995 +oskar +zzxxcc +jennifer +ooo000 +subaru29 +players1 +camaron +tombraider +favorite +crazy88 +seth +1booboo +texas10 +sharmila +poohbear3 +templar +password02 +romero1 +blood666 +manatee +eagles123 +segredo +chellam +nika +fatty123 +football50 +monaliza +dulce1 +bedford +110288 +bennie!! +aiden +soriano +eminem11 +1samantha +123123m +nantes +q1w2e3r4t5y6u7 +637846 +engage +doris +lakers23 +12312300 +alexus1 +kanada +7seven7 +hottie10 +19870212 +170787 +shraddha +businka +hunnybunny +impulse +brandon21 +silvestre +mobydick +string +blue17 +zach123 +fatfat1 +far +celine1 +banjo1 +panter +boring +as +skate3 +fruitcake +bull +chloe2 +kieran1 +hottie16 +aaaaaa11 +aeynbr +tiantian +jaguars1 +vepsrf +jackdaniels +supermom +121985 +larson +paixao +sammy3 +198011 +boobs123 +121280 +helios +food12 +semsem +laser1 +purple24 +mjmj12 +maria11 +101285 +bmw525 +friends11 +30 +karina123 +nicole9 +anais +james6 +mimimimi +lewis123 +searay +oakland510 +rhapsody +1qw23e +168888 +9lives +33rjhjds +habbo1 +dragon4 +porche +nigga5 +258789 +dingo1 +dudedude +jamesdean +jennifer8 +120288 +william4 +password87 +robot1 +qazwsxe +lesley1 +meg123 +sayang123 +lopez123 +hottie15 +hockey77 +101188 +oks65b6666 +spongebob8 +papito1 +500081 +1batman +moochie +middle +rockrock +legacy1 +213141 +nookie1 +slugger +albany +bomber1 +vick44 +163163 +shakti +jayjay12 +service45 +123xxx +sapper +patrol +magic12 +interpol +cdjkjxm +ashley8 +numbers +buffon +temptation +125521 +mikhail +joujou +abubakar +christie1 +jennifer7 +smail.ru +purple18 +jessica17 +10101991 +nameles +nova +icandoit +winamp +single09 +stallone +baseball01 +xtube +billy12 +marios +gangsta74 +edward13 +babypapa +asss +olga123 +yf +hatred +yankees3 +ashley19 +cowboy2 +bajskorv +irishman +sugar2 +peace3 +tomahawk +10102010 +asshole11 +121188 +999888777 +kelechi +adorable +bell +kamiloza +compass +hannah08 +isadora +2monkeys +slash +bethel +951753852 +qwerty654321 +chris9 +johnnie +hoosier +ferris +looping +333333a +proton +swagger1 +6820055 +imawesome +cowboys13 +999999a +chicky +motley +caesar1 +120000 +elenanesterova +muaythai +sakura12 +walleye1 +mother5 +ducks1 +arielle1 +aurelio +adamadam +video1 +flossie +123123s +121089 +mamacita1 +keywest1 +020406 +bitch18 +wwwwww1 +gulfik +fishing123 +dimafilippov +753951852 +1222 +ohmygod1 +5845211314 +mrbean +2brothers +tmoney1 +jalisco +400601 +corey123 +10000 +james +natalie123 +primetime +thanatos +gundam00 +newone +spice333 +101286 +crazy11 +stripper1 +christine +myspace18 +gracie123 +sefa1986 +heather7 +pavlova +1013 +sisters3 +brandon23 +nighthawk +603575 +jones123 +1dumbass +conan +snivanie +soccer27 +fatboy123 +jasmine10 +yuliana +nilesh +ops111 +assword +byron1 +ad2021 +joseph7 +taffy +volkorez +owolabi +milan88 +etnies1 +j0shua +delaware +naranja +man55580 +------ +slava +rrrr +greece1 +225522 +marylou +michelle4 +missika +baron1 +gleiser4 +saleens7 +glory1 +bmw318 +maxwell2 +ilovedad +nutter +whatthefuc +july0788 +january22 +rightnow +pink24 +de +yourmom12 +teamo13 +1202 +213456 +110588 +carmen123 +123456q +happyface +hasan +h2opolo +michelle21 +boys123 +kj +abe1973 +jessejames +atlantida +honeybunch +stingray1 +shadow15 +edwina +carissa1 +powerful1 +boss167 +varico +newlife2 +smiti1 +beatles4 +mia30 +gemini2 +123ass +customer +hatelove +bellissimo +ingeras +1babygurl +babygurl3 +q1234567890 +wizard101 +gady123 +t326598 +1236547890 +kokoro +simonona +pooter1 +michou +computer5 +cunt69 +sex1234 +capslock1 +slaptasis +dorcas +tobydog +qwerty1517 +soccer55 +waterboy1 +camillo +evelyne +cranberry +yeahyeah1 +k2010302 +robert1708 +ernestsantikov +bubbles5 +shirankova42 +620850 +matthew10 +crunk1 +quadd +shiznits +august7 +elektro73 +123555 +100686 +lailas +kelsie +lyva84 +loveme +kotox76 +michelle14 +vitaminka88 +maxpredator +1mickey +jimelen +kotyk22 +dorota +vibi123 +shuhrat007 +sulamifcherenchikova1979 +vkuradovetc +mushroomka +yanchikchmoki +fredfred1 +moshco +summer2011 +1qasw2 +varga43 +musyka85 +vkrbashyan +troika93 +dantheman1 +1234567qwe +lenyi +lifestyle +vfvfvskfhfve +princess99 +spread-hop +myzone +baronessa87 +gorlonis +olgastrashney +god7507 +123321456 +sta93 +cobain1 +arkoximsp +dfdfdf +daewoo65 +kuzya-ser +eremei_vasechkin +loveko +nif686 +forgin +679956 +thug__ +maksimka876 +charlie6 +22222a +vkorotin +rtertuy77ijyhu7i +grih-rom +casper2 +volkova.ksyusha.89 +kotkova37 +maks.abramov.99.99 +kotmichanik +valya.kryuchkova.1990 +d9160847880 +papuskin +ramsia1986 +volkovoi_net +muhon +strekoza79 +sunnyest +lorik197110 +pokey1 +r_masick +betsynx0kof +aliya.mutallapova +aleksej.shorin.86 +gifema +buster10 +bellaboo +maksimilian_nasirov +5695595 +shukshinasveta +erast.82 +rio7777 +nusha.88 +renkanom +prosvirkind +spection +solomaha-denis +sagalil +valya-garanina +galina9181 +soloveibormalei +oksana130279 +robby +zabivay +kotya_bagdan +jeremie +lexa.maxus +560029 +okein +tema-bushelev +sans2010 +alexrv_06 +inar_ka +enyvbuois +maria-fam +g1hp +guldaniya.galina +sgga +len_nik44 +lopew +sivenkovklin +skrip-natalya +filatovaev1981 +63val63 +blond72 +sergeev2212 +raymonde336schwegel7331987 +zarinalin87 +tyrell +miha-nov +djedenhit +e.ovcharova +sofya.kulikova.87 +elwooo +marinaorlova1991 +vkot_2010 +shukurova-ismigu +yulyasik2002 +123654q +taskaev777 +borismf5tsh +volohovich-t +smirl +maxonina22 +trustme_k +sewewf +mbrim +len4ik31 +stronghold +serban24 +rezo_2010 +victorclavier +varduhigohar +vkravchenko +annagor20 +volkovanata77 +kirill.kirillov.2013 +sin1_19 +supervista +wwwksenechkawww +kotovichvalentina +cowboys09 +texasdoor +artov.95 +mknaxhxeh8yp3tf +sheela +nbvcxz +vargden +mkjhgf1996 +11-05-1992 +kovalienko63 +ghusieva1958 +julia_eduardovna +vip_trading +mihail_alekseevskiy406 +sidorow64 +rer-tuy +hugo854lataille1988 +andreyka.gorshkov.98 +aleksandr.ustinov.2012 +stavr75 +fggjkbyfhbq007 +maxim3999 +tolstyh.oxana +regina-rebina +mishanna1936 +gluxov70 +rickjames1 +bolshoj_zmej +sgydvntep +kotovas-70 +mir-180991 +aleksis1611 +oleg2ci +summer.fruit +x444am +vkoomare88 +sraka105 +zabolotnov1968 +61atnakaeva +beloved_a_devil +zablo +yulianaz85 +volfram.kozlov173902 +possum1 +veralipatnikova +rena.vano1990 +antonichmeli +zabolotneva_ira +sheba417yorck1986vxm7 +ineedajob +rus20dem +nika_kisa88 +madtubes +kotikova_n_m +zabelina12391 +ghrhfh +kovalskaya-t +emo_limonad +stassenka +baleri22 +opiumbaron +goman1985 +yy.tt.67 +dmitrii-skargo +yuliasha87 +mr.stas192 +dimok091 +antonls +spiridonmarkin1982 +bandidas747 +hismatdan +radik070775 +victori1967 +serg-niki20 +marina.shapovalo +cheetos1 +shar-vin +firakoki +masjnj67 +boromirus +sredina-va +vihlaeva2012 +cutegirl1 +mol.kos +mam_p +mihail-saratov +1qaw321 +ggolob +sevgeyq9v7kor +ksushapanda +vm.shlykov +malhotra493ozzy1991282151 +lobkova.1979 +delirium9111 +sava_72 +radion-dankov +valya.2057 +romka_ya93 +6610_2006 +arina-sharapova-80 +jannaarhipova +rusali_1979 +dnina666 +forgiven1 +kovach8 +d-x-m +mavriciy +burchenkovi +subprodukty +6651953 +isaulov.a +nust007 +stone_mitich +stecova85 +irinabrig +stas.gorodissky +lucky17 +rashaun966krager1993 +victoria.kl106 +vadyusha.isaev.83 +oleg272727 +lexir777 +sonya200102 +rusiphon4 +sor1989 +imabitch1 +miss-evgeniya-93 +ivankaterinchenko +mkolendzyan +panmen188 +gheniagabb +hermina617berno1990f6i +sergan11 +kudielia.anna +asa62 +valya-city +varich-masha +ser_kuzmin +qwert.0002 +olga.rumyanceva.1985 +kovalevagn2057 +vkors +victoria989 +101083 +asil.dovlatov.1982 +kotova.69 +svetlana-mironova-13 +venta021 +6552090 +max_masha +nastina33592 +sirazhdinov.shamil +alena_plotnikova_1995 +elenst14 +netti-88 +vkoval87 +vks1zz9v_7ceu69 +sveta-kisil +313233 +plankova2012 +varadero +u.hohlov +tarik-66 +raskevichtanja +stepanov_georgij +yluy1981 +duskolyan +innabuk +mpnaduysi +anna2976 +victoria14.09 +samitluiza1 +razdvatri3 +mirlan_o +nikolay_thebest +mobiline_b +teh-consul +zabludshaya +asabsmelik5g +marinochka.zhelannaya +rachelle289ariyoshi5251987 +derector-85 +narashchivaiunoghti +kotovam85 +volgograd.orlovka +aliev0583 +75fs +kir-ettk +slavik200887 +rinat-88 +serash2240 +belinova14 +computer3 +madcow +mmakssimka +galinkaru +zabirov2 +r6a50de3ujwtog4 +surooo777 +su4ik +shaquillesecx10 +ksyusha.kulagina.91 +loveone +sssuka80 +mudok +ravich92 +oleginator1 +zabolotniy.a +kelly2 +bolatov.almaz +bavixepym +stas_the_best.ru +macegorova.mariya +nastya-b86 +sopli22 +monp5haynes +prosto_chelkynchik +serpa7 +zabor.hut2 +dud_1995 +kirill999_97 +maitland571ka1994 +axssyha +vkontkate +grishin0308 +jasmin-ris +ribka227555 +volkova.elena.13 +111zabavina +vkryshkin +djdjfedor +i18bzbk3ay8 +mikhayildopy +asotjan +mozellbranou81e +simonova_lyudmila_73 +777kroxa +matrassesotk +stason729 +ok20.07 +nataliystre +nata271283 +kukatov86 +mklmkl22 +tyumchenko_ok +dovbeshkosushova.1972 +thehock +aukewpyrt +miuaybecv +olga.kazakova_85 +almaz_kiramov +marina.ushakovaznuv +ms.cc.gg +vktorov +golubinskij.87 +spn5 +fler_2351 +julija2010x +spuvd +volhsara56 +yansubina +6572757 +natalya.dmitrieva.1978 +yana.kolomoets +ira.klopot +apalkova.tatiana +bayrafis +yxelik +scsc78 +bulka-a-shah +renesmeecallen +ifuckyou1987 +vkovshut_annab1988fg +elensobko +silantyi1987 +zarygalina +olesya.kolchina +igaev90 +irina280374 +tor8585 +shevcov_alesha +elynca96 +botafogo +ghkdf14 +volodya-ivanov-63 +mutalim.gusenov +djhjyf010 +silakova.nadezhda.2012 +olechka061187 +victorfrunz +ktv910 +ahmed_orudzhov +guzel.t.f +sergey.lushnikoff +voroshilova.liliya +maxa-06 +oksanav-13 +goderdzikarxjxv +helga_557634 +moscowcallin +victor_evdokimov +sirik010875 +levenyatko2007 +victoria392eliezrie1992frp +moshkin1998 +vic685 +zaxarov-1976 +maxemys +slipchenko2004 +manovitskaya +zabelinaalena +igorek-filatov +constance626boilard1987 +aleks-270379 +rendakova_sveta +sodikov.talat +dok74rus +sss-nastya-sss +rauzawcsiv +victoria-berkat-energo +simonovskiy1970 +raduga388 +sorokina7778 +artemblya +erofka +maxchislov +soyma.ivan +siiifonjiknalivai +victoria_shkurco +ksyuta76 +smail2u +mayrik67 +minkova_i +sungatullinad +reginka2393 +sp.zakaz +mishaghbdtn +milay-ven2011 +rexrex +albina-1945 +julia.olga +kubnik +mmedinaa +275-22-74 +miss.marina.nikolaeva.2013 +spamar33 +astigor +victoriandr01 +zaborskiy80 +maximus1393 +sigreic +89217657066 +sergeevna_10.10.91 +sin-gulya +valya.ivko +victoria_002 +rita497 +valentina.victoria +djtatko +kuchelaeva +maksus_2003 +stella354926 +margo.emi +aminin94 +dan_cheb +serj-gr1966 +strelka.m +almira +raduga2508 +ratashn67 +ms.dolgikh +stan021092 +kudrina1962 +stas_kolos +andrei_rew +egor.vasilin +blyad_be_90 +sukasbliat +len_rin_kagamine_02 +marininys +annhen1 +vgizetdinov +fedorov717 +sergey_brrr24 +mnenrad6983616 +denis_nazarenko +pokopushkin +kirienko_svetlana +13grom +sidorval +rcalgif86 +style_style +semina-alina +zezina80 +andrey.shalanov +antoha50a +7777_74 +6917123 +666fafnir +valya.korobeynik +elvira198927 +sophieytorf +komnatnyy88 +milanova-kira +torgsotra +6215348 +oksanaorgadykova +varfeevich +ch_vitalij +raif.21 +evgenii-shenderovich +egorov_maxim +kudakova.83 +gvinpinka123 +feram0n +yanaluch +svoron1977 +irochka-ova +e-eremeeva1976 +dima199219921 +qwertykolakola +svetlana26rus +dimapet09 +mikalyalia +mariagoncharenko +galina-davidyuk +galinka_korneeva +foks8484 +manka198707 +miraa_84 +zarina_sabirova +piankova72 +maximova_elena77 +mrdmarina +varfolomeeva0990 +svetlana_07 +nadjaem +panda_3108 +srcuqq1_2j1h3rbf +sibiryak5 +valya-sidenko +olqa_motosova +victoria_91 +olyashev12 +yulia-dubrovina +ghrimachiova64 +ya_nochka86 +volgirevagv +volfram.kozlov123633 +dolgushina.76 +nata_titj25 +sergei_man9 +9602929770 +isatelt +thesmokin +nastyaanciferova +olga.lekarewa +alexdok76 +aydani_ +voliahim1891 +sfasdfsdfa +michel69.69 +shponka35 +lexaafanasiev84 +milankasanakoeva +mikhailova-w +limonyk +dima35360 +dmitrij.mironov2014 +vika.krivonos.1995 +andreyka.zhilin.1981 +arinayu0 +vkulak +mariannaz2 +sh_o_a_2013 +rinat.76 +andruhova.1982 +www.ivan-18 +angarova81 +olya.i.02 +victoria-dyatlova +drozdovaksusha +florida123 +kakosja +xalitova1988 +mar_prod +vova436 +kudrjashova62 +nargiz-a +s-firsova +sharmaine005foskett6071988 +silenakriv +mitia159 +svetik_kryuchkov +zarinochka_b +vkundeyai +antusenok_zhekonya +shishmarev76 +maksim.bychkov.1986 +lady.procenko71 +seregakalygin +slava_kulbidyuk +serova2008 +bazueva.1990 +golga.70 +lisicyna704 +mocanuv +kuchierova1994 +lllllll +volkova.67 +moss032 +stepa-2009 +kovshikova1981 +vihrova1974 +ravshan1017 +armyach-aleksandra +slastenka93 +natasha_19.65 +vkpxrnoda +mjuan5ogm +valya.gorodn +r.polinin +neslyxovska +sergio.b93 +victoria.20000 +reyrtutyd +89140041205 +dimlimonov +dr.karaul +maximova.60 +ira202909 +g_alisa1502 +mkalancea +pridprid +vikatc +zabloczkaya2012 +listopad.iuliia +simorodok62 +canon1 +zarinka1111 +kovrnatasha +tamriko0942 +naz-74 +levana928 +akkolesnikov +onamrdiu +yulia_yulia_13 +djon.net +yahnox75 +kuponatora +filatov_and +zabotin_sasha +prozukin-shift +mila90974 +ber +n_pletneva +oleg.jann +kovalha +cartoons +dymkovpavel +slava.grinco +volga11955 +molchanova_tlt +goluboglazka08 +marinadeduxinaa +lupashku89 +natatuma79 +vashenko.u.u +djmaikl86 +sm.karat +qwedcxzas +andrey-1983_08 +blackpearl +dianochka1924 +mishas001 +max6751 +bad_boys_adience +rozlori +manin-d +ololoeva-99 +chucha0810 +vakantie +6125060 +bytopmcd +zuewamarija +kotopes_o +spring938burston0001990 +serega-cash +manuliktatyana +zenit-talnah +olgha.pietrova.1979 +rerghr +dana-14 +kurmangazieva_gulmira +oriflame_1910 +melmel +vika-selfish +sungelika86 +volhina-73 +seregjvich +maria_q +osynadepu +mzyankin +101020 +misch.sosnin +playboy7 +sigora79 +aztyvl_ka44ze +yushinazena2009 +ben_a95 +safronov_3112 +mito.lo +ignatova_1978_09 +ralphc8xf +avkhachev78 +valya-lera1 +pyanzina_elena +sorokina-999-01 +sonia-91 +motrya.larina +sakoshka_masha +glafira110169 +rbtsozeva +vkoryano +hamulakvitaly +zarina_loves +max.kirilov.90 +shunia0505 +milena699803 +rkamkin.karoli1988mp +mahmudali1987 +bolno_18035 +rezvanov_a +shirshov.1968 +zabolotnova31337 +nat5g +olegshut +nati.beridze.92 +riwr2hky4w3tjgg +tender +mixaxa2003 +kotova_74 +posoxina.88 +avetisyanartur +morozovavalya28 +voloshink +kuliiev.79 +kuznecovviktorr +eanovozhilov +valya-valya-1982 +varida.alibaeva +raisa720290 +mandds1mg6bv8re +aksenov.dms +sergei1986inna +lena5stars +rita_nizhnik_r +prikoluxa +avikuzen +standard1 +oxana.o +crosby +mojurus5575566 +machukreeva +arividerchi_shatalov +zolotarev08 +lisenkogv +rexocinod +ghalina_1971 +rzaev_ilgar +ivanov2305 +6430130 +tema.barabin +never_desponding +litosik +dimebag +varfolomey_72 +azik_06 +pletnevakaterina +simonova5570 +karusev_spb +felix.1957 +dove797 +gofman_osk +rahmudinov92 +tasya.5 +volokitina.olga +kati-leva +fishbaracuda +rogovsasha123 +777dashuta157 +ms.polza +hallucinationse +magic-n12 +azefirov.inno1987.r +davidstrokov +lexa-let4ik +gjcaixxx +victoriy70 +bakuman.manga.drawing +mirellabroersma1987570 +mordva1783 +mityukova.anya +stroikarat +welder1 +zarinaismailova +mylfard +qwertyuiopasdfghjkl151515 +k.u.r.t +sergey-personal +starpozitiv +victor_sakhalin1990-20 +dimulya.vasilenko +alfakran +fs.swl +safonova.1967 +evial_marina +mede_voda +kuchinovao +sporu-netu +aylyan2001 +anna.savickaya.1986 +vartk +ivanovamotya +blackangel09021 +slonenok1009 +vihotsieva94 +simonoff-dj +regawf7ss1dm7rn +krick.bk +golovizina_elena +aceeva.irina +vicusa.tatyana +gidrometeoburo +stalker_lemurrr +volik-yulia +mks.01 +damira.shagabutdinova +tishenkoff +malina_bratsk +0210-605 +jeka-ka85 +aqwleeb_6e0pk59 +mks33 +iurkeawov +ksyukha1990 +mak301988 +football26 +andohz +kejan82 +simakov_evg +sieuwaprd +tema_ku +sogevigdil1981 +jeter02 +valya.lantux.83 +jekan860803 +ylik1911 +stsnatasha2008 +zaborov_t +volkovaolguna +dgonni86 +maxa-78 +universidad +matveev792010 +gadjieva.gulmira +famar219948 +valya.shapoval +vs-nd +fyujk.fyukf.87 +connor123 +sbally_64 +6041074 +slava-45 +zevs_ev +annywka_86 +kinyabuzova.eleonora +e_dovich +popovkin83 +fomalex10 +alija-gatina0 +sgtrsgh +sunnny56 +laobidenko +strezhetova +sovin.sv +zabihullin99 +stason16.92 +wwwamador91 +aza_93-93 +sergej_de_sad +olga.ponomarenko.2012 +sattorov-q +armada-n +marimax.85 +leto-nataly +thecrazymaxim +26.09.67 +sov1_86 +maria-demidchik +eloisa +korostelev_3333 +fjodorova-natashenka +avto55.rus +ari-kyarova +valya.klimenko.87 +sergey.melnik-1996 +londra +serikpaevna_92 +vik22535477 +frant_nat +voljanka1976 +koala_1995 +nemochkao1975 +marina_stryazhkova +fotinia-66 +oleg-andry +rogovivan72 +stepanov.ag +evgenkac +barkov_65 +serg.aleg +fatimah +hrustem65 +sergdock +ry1dtv +gaar_vitalik73 +balentinra +monaliza2786 +shilard +strange.lena +sataieva.elinka +babich.e +romanova.natalya.96 +redko5 +abrejkina +gatina_albina +trofimishe +volodina.elena66 +lizasp07 +6450716 +arturamirov89 +black10 +t_v_belyakova +efimkin_igor +ilya_al_80 +aram198309 +sergio-emperior +samsuchonok +arsik-di-noxcho95 +fardubay +zarina_zhasan +fedotovsa76 +laser +palmer1 +mihailpezhemskii +sosexy1 +antsiferova1973 +monk3y +serg-ks.87 +kamazist.tsobenko +mogychajagopa +dimitr692010 +gholovach75 +zachodnio +skorpions23.5 +shorty23 +serega_torov +telegina_65 +parfenovav +llll.70 +ramis_bairamov +simmons1 +raisa_smelkova +compaq2 +ss_1983 +kafedra_oisp +ametistfatal +dua82 +shea019bernabei1992 +donskihv +varika0 +marielwfledlow +dimastic +volkslt35 +leeann1 +bikers +nastenabendel +amigo +kudryavcevavalya +ilovekiss +nikkie +ryabec.m +myhouse +lexa290195 +lipovv70 +shakmakovataisiya1992 +79621601378.kirill +ryan13 +143love +10101989 +halohalo007 +231288 +an4oys12120 +vedro.ru +marcia1 +1space +monica2 +january23 +sexy_julija +bigdaddy69 +pepper13 +codered1 +dawid +loser7 +chocolate6 +criminal1 +monkey55 +1guitar +bubblegum2 +231089 +rfnz +brianna123 +alcohol +ei33a +chrome +gargoyle +560100 +bwfq23jp7f +douche1 +alchemy +sinead +1taylor +bonnie123 +10231023 +1mexico +joshua07 +candys +badboy69 +whyme +asshole4 +denise12 +selenagomez +nfhfrfy +thedoors1 +joachim +danielle3 +bigger +gatto +1357997531 +mshelp12 +hussein +coolcool1 +bailey13 +02020202 +festus +dindin +doom +bondage +newlife08 +hannibal1 +1junior +7878 +motherof4 +girlpower1 +buster3 +edcrfv +matrix12 +rock101 +mylove4u +providence +keekee +080888 +120388 +1206 +elohim +560032 +moses123 +hummingbird +pierrot +kilian +maciek1 +travis123 +200100 +hybrid +2gelaf3h4a +babloo +zaq1234 +skate13 +554433 +loser. +fulham +marek1 +corndog1 +123456qqq +waffle1 +1black +lauren13 +alvarado +december8 +sexyback +ashlyn1 +ronaldinho10 +5482 +shocker +sleeping +++ +august08 +minou +shithappens +indy500 +michelle23 +pwlamea10 +adeniyi +101091 +elias1 +mark11 +soleil1 +michael24 +f123456789 +savemoney +ivonne +stas +aa12345 +kikay +3monkeys + +avery +raerae +1hotdog +chance12 +101187 +biodun +sabrina2 +peaceful1 +barbara +miamiheat +yellow21 +lobito +micky1 +petrus +angela01 +friends. +julianne +nokia6630 +f22raptor +dude1234 +nipples1 +cntgfy +nickname +1231231231 +tsubasa +firetruck +dre +103103 +outkast1 +zimmerman +damiano +shanshan +sloneczko +oneone +espresso +manda1 +firstlove +doughboy1 +imagination +reddwarf +5tgb6yhn +kristinka +jeff12 +sorry1 +maria10 +ararat +fourteen14 +helloyou +splash1 +3stooges +gorillaz1 +jesus21 +conrad1 +kamal +tiny123 +rock11 +tillie +freeride +mikejones +fuck_you +freeme +friendly1 +nbuhtyjr +chelsie +my2babies +jaiganesh +sunkist +rockband1 +laila +beemer +emergency +youtube123 +223366 +060686 +010188 +12345678p +1021 +luckie +password90 +burberry +dia +audi100 +reece1 +snookie +johnny +830928urodziny +llllllllll +tina12 +miley +198510 +alaina +daniel99 +praisegod +ukraina +leila +pitufo +12121987 +george +batman! +2bitches +rey123 +monterrey1 +saun +anutka +sorry +1dream +mikado +jenna123 +putamadre +stocks +120987 +amerika1 +guzman +nokianokia +lostlove +seven1 +buddies +papa12 +maxx +organic +yoda +petewentz1 +708090 +pass007 +hardstyle +matrix2 +rubber1 +rockwell +password91 +getalife +кристина +halo23 +bailey10 +xboxlive1 +jjj123 +dragon15 +newman12 +thomas7 +ramana +cayenne +wertwert +blahblahblah +maggie22 +margera1 +preacher1 +thomas23 +fabricio +chelsea3 +yankees12 +toujours +margosha +12541254 +jessie +troll +mentor +12351235 +cake123 +martin11 +aa112233 +csyekz +loveme5 +omar12 +qwerasdf1 +718293 +gbyudby +ficken123 +princess88 +scarecrow +r0ckstar +12121990 +dianka +brenda12 +january21 +perez1 +mercy1 +arcoiris +massimiliano +120686 +cho +030609 +markmark +jackson7 +naruto01 +steeler1 +imogen +bigblue1 +5xq57cgseb +tuermchen +number21 +hannah07 +suarez +000333 +rose13 +mamo4ka +souljaboy +niknik +king01 +196969 +amanda15 +123321s +invincible +august3 +lyonnais +richelle +43211234 +dilara +gamer123 +400097 +brigada +google3 +avanti +ahovwpib +guerrero1 +hel +savita +milly +slayer123 +1106 +50cents +blackmetal +qqaazz +i81u812 +t1gger +midnite1 +hassan123 +randolph +kakadu +lppnldtzx +10101988 +trapdoor43 +charlie9 +chloe12 +playa69 +020508 +rerecz +iminlove1 +apple4 +michelin +405060 +qwerty09 +nisha1 +coorslight +mydick1 +vasco +gaygay +szymon +0o0o0o +redalert2 +sangoku +chivas01 +purple77 +custom1 +bbb +400001 +daniel6 +gamecocks1 +stgiles +brittany11 +derek123 +123456prof_root3.sql.txt:, +welcome01 +ig4abox4 +lulu12 +energie +monkey00 +hattrick +bicicleta +london10 +hellno +bearcats +tyrese +49ers1 +hicham +12123434 +happy10 +aidan +susana1 +harley03 +cookie14 +alexis7 +truth +richard +pinkrose +rexona +sweet3 +555111 +dudeman1 +roflcopter +bball4life +gretta +linden +micah +murat +silence1 +jimmie1 +lolly1 +bonethugs +babygirl25 +patrick5 +aka1908 +anthony69 +computer1 +123456 +fingers1 +infamous +pippin1 +antalya +baldwin +senorita +949494 +ron +edwardcull +101082 +apple1234 +sewing +olivia01 +44magnum +fer123 +carina1 +pornstar69 +pepper +blowfish +accent +foreveryou +cowboy12 +visual +jonasbrothers +aaaaaaaaaaaa +jordans23 +120485 +altima +rosewood +cameroon +oakley1 +sarge1 +lambchop +morten +sydney01 +tiffany +dfghjk +breeze1 +cherry11 +lover15 +pppppppppp +flirt +lockdown +francais +angel04 +1superstar +101287 +852147 +coventry1 +111983 +green16 +alfa +ofelia +hallo123 +amanda18 +woaini521 +asstastic +amber13 +brock1 +computer +niko +nicolo +lala22 +zeeshan +magadan +greentea1 +qwerty14 +sunshine6 +dongdong +jomama +zigzag1 +010109 +okidoki +leomessi +fuck23 +titleist1 +123dog +contacts +101289 +hungry1 +in2806rbk +stefani +veracruz +conway +jitendra +lexington +gandon +octobre +seatibiza +alex05 +today123 +balloon1 +marcelo1 +tmoney +wingnut +atdhfkm +kbctyjr +hannah +sakuragi +sonne +sweet! +fight1 +jeremias +mikkel +198811 +101290 +locoloco +ilia16739 +htubyf +punjabi +filipino +koukou +molly11 +justin +mourad +percy1 +highbury +family05 +beautiful7 +annann +cheer13 +defense +disney123 +peace&love +thetruth +babygirl. +single12 +books1 +olo65b6666 +qsdfgh +jess1ca +nascar08 +jigga1 +rapunzel +alexei +hyacinth +1elizabeth +14521452 +mohawk +melissa3 +skater7 +110388 +hunter6 +chelseafc1 +richard1 +135 +flowers12 +wellcome +kristopher +buzz +j3ssica +nakamura +redneck2 +maddy123 +nitro +reggie25 +hardrock1 +12345678t +owen +blink1 +morgan13 +brianne +bear1234 +booger2 +112244 +offspring1 +600042 +mike15 +alex25 +charlie22 +3030 +quinton1 +mike08 +michi +natale +12345trewq +asdfghjkl;' +taylor07 +newbie +optimist +bassoon +jayden123 +dawid1 +flower10 +vedder +fuckm3 +roflmao +purplehaze +150150 +gilligan +dionne +marlin1 +3429795 +macbook +baker123 +josiane +yorkshire +110589 +baby77 +11211121 +dragon00 +ashley24 +fallon +tyrell1 +noah123 +ramadan +1buddy +draco +webster7 +tretre +volkov +romanov +fuckyoubitch +25tolife +sugarplum +147852963 +baron +chesterfield +230388 +andrea13 +spider2 +baseball27 +sexyone1 +10111213 +perro1 +sidewinder +okinawa +chevy123 +pervert +david4 +forester +whatever. +dickie +force1 +fresita +torres09 +arlene1 +anthony09 +mememe123 +marie01 +chevy69 +delta123 +tarantino +pheonix1 +1password1 +brandon08 +connected +dunhill +katelynn1 +margie1 +diamond4 +cheetos +2828 +disco +zaxscdvf +clock +classof10 +cloudy +ginger13 +ziomek +bolero +millie123 +wilson123 +jesus4 +gewinner +cassie2 +dallas13 +1poohbear +270787 +limerick +kodiak1 +hinata1 +zxcvbn +cghfqn +bluebear +angelina +usnavy +reefer1 +9379992a +weare1 +mallard1 +051988 +korn666 +del +jesus09 +junior7 +андрей +noemi +rebeka +happyme +mustang99 +camron +290989 +alphonse +riders +godfrey +10121012 +football51 +denise2 +pass12345 +123456prof_root2.sql.txt:, +soccer04 +industrial +puneet +420420420 +justin8 +1207 +angel89 +trance1 +chicago2 +rockstar13 +robson +mydaddy +dayton1 +w1w2w3 +blaise +120888 +blue07 +jayjay2 +manchester +sidekick2 +lighter +pitbull2 +gatsby +nurses +ilovemommy +jeremy2 +cali123 +misery +amanda23 +gbgrf +benjamin2 +201201 +cherish1 +azer +ashishbiyani +135797531 +060708 +sometimes +fifa09 +coffee123 +120585 +kalinka +sarah13 +raiders123 +drums +cadence +bigfish1 +584131421 +makarov +jacob11 +100688 +th0mas +nene12 +carlo1 +a11111111 +jayden09 +88889999 +rene +virgilio +lmao123 +солнышко +kush420 +123400 +titoune +dogface +a123a123 +mother +eroticy +1bigboy +mika +raja +tennis2 +cneltyn +111980 +dell1234 +iluvyou2 +leighton +alexander9 +myspace33 +kobina +012345678910 +elektra +http://www +gol +jj123456 +grammy1 +110789 +130588 +artemis1 +beatriz1 +amitie +cutie7 +alexis5 +calcutta +geibcnbr +jeanne1 +genius +doghouse1 +nick22 +onelove2 +megan2 +147123 +biggirl +mnmnmn +1031 +peanut22 +merlino +manyak +hilton1 +blue52 +chanchan +auggie +macgyver +chemist +suck +sporty1 +520123 +jazzy12 +gracie2 +s9qxa9yn9cc= +ahmad123 +120988 +lovealways +110487 +turismo +summers +1120 +suckit2 +stalker +cookie101 +pittbull +terror1 +nicole19 +football30 +ross +kirsty1 +fling1 +sesshomaru +russland +bubbles4 +imsexy +joshua4 +thatsme +tabasco +ou8123 +downtown1 +selina1 +plies1 +savior1 +1cheese +plymouth1 +manga +erica123 +virginia +universe1 +explore +detective +sa123456 +bigboobs1 +emploi +143445254 +cocochanel +08082008 +4242 +crazyboy +joshua06 +cowboys21 +destinee1 +forsaken1 +gaylord1 +tiziano +lekker +ytngfhjkz +junior21 +jeannie1 +322223 +brabus +bitch24 +o0o0o0 +priest +bettyboop2 +jose14 +gfgjxrf +david15 +afghan +asdfghjkl2 +l1234567 +september6 +andrew69 +zxc12345 +deathmetal +water5 +thelma1 +flip +abcd4321 +asdf4321 +paint1 +sweetbaby +vfylfhby +20080808 +furkan +camino +star55 +janeth +owen10 +lovely11 +volkodav +orange4 +gremlin1 +lions +10001000 +258025 +@yahoo.com +dima1995 +skater14 +forever +doris1 +bogota +9268356683 +pinkgirl +greenapple +121291 +dragon24 +nana11 +110989 +trent +forever13 +ladybugs +110065 +aslan +hollister5 +angela +1227 +zxcdsa +cyy813zrvr +210588 +1david +vanguard +emma1234 +nadeem +evil +metoyou +phenix +aliyah1 +grandma3 +mexico15 +ilovetyler +ottawa +paradiso +bella10 +rockstar7 +sexy12345 +capullo +yellowcard +renaud +101010a +12345666 +pepsimax +shamil +dance101 +ababab +tooshort +samantha1 +shelby01 +520520520 +cheese13 +01478963 +alex77 +shorty10 +9874563210 +rebecca123 +224422 +nachos +++ +1478520 +shamus +420smoke +tahoe1 +cinder1 +7890 +11223 +shocker1 +rockstar10 +mustanggt +furniture +everquest +221288 +harryp +chetan +197300 +mailbox +solo +guyana1 +hottie6 +chrisb +jessie01 +пїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕ +3344521 +misskitty1 +lalala12 +000ooo +abbie +214214 +google11 +258258258 +macbeth +orgasm +ghbdtn1 +myboys3 +kaden1 +bluetooth +remote1 +stranger1 +1qa2ws3ed4rf +topgear +bartender1 +john3 +louise12 +heartbreaker +trucking +141001 +112233aa +snapon +daddy7 +emmitt +jaqueline +12251225 +junior +skyblue1 +fabolous1 +keesha +fxzz75 +healthy1 +jajajaja +molly01 +elisa1 +qa27111985qa +cooker +vthctltc +1133557799 +passwerd +whyme1 +qwerty56 +vfhrbp +1jackass +deshawn +beograd +datnigga1 +rostov +transformer +fruity1 +salina +chelsea +olivia +blunt1 +password101 +amor13 +grunge +chocolate. +rugrats1 +a123456a +blade2 +romania1 +1joseph +pavlov +amanecer +tubby1 +lambda +credit +400063 +shadow88 +fortune1 +pawel1 +toomuch +1madison +vjhrjdrf +willy123 +bronze +niggaz1 +fusion1 +ckfdbr +buggy1 +uruguay +1tiger +schmidt +guitars +wtpmjgda +poetry1 +sunshine09 +sweet6 +131211 +hockey33 +aremania +pinnacle +glory +пїѕпїѕпїѕпїѕпїѕпїѕ@mail.ru +quinton +lexi +bigdog2 +gmail.com +cheer07 +cerveza +allblacks +soccer +dancer87 +kotek +sweet7 +марина +guitar3 +august6 +screwyou +100888 +120486 +198622 +fordtruck +green77 +bb123456 +sujata +nygiants +ibrahim1 +funfun1 +jason01 +boobs2 +betsy1 +beautiful3 +231188 +iceland +trees +cool101 +maymay1 +bimsta +sassygirl1 +matthew23 +hannah14 +lovers! +alex101 +123412341234 +5203344 +jimboy +babushka +jacob3 +tommyboy1 +subwoofer +blu +maestro1 +iloveyou77 +560075 +jesuslove +10101986 +rookie1 +sonnyboy +michelle8 +princ3ss +dolly123 +cherry3 +leon123 +greenday7 +hannah6 +samantha7 +dorian1 +135789 +hihihihi +cookies3 +work123 +naruto99 +shinobi1 +retarded1 +suckit! +asgard +shithead2 +florentina +memyself +maddie01 +december9 +120487 +123321qq +jenny2 +jesusislor +james17 +idunno1 +rukawa +evergreen1 +recipes +eatme2 +player3 +emily13 +blaze123 +mustang1 +jas123 +1raiders +otto +davidson1 +bluegrass +shanthi +salmon1 +warcraft2 +iloveben +gurudev +carolina12 +keith123 +mollymoo +crayola1 +patrick1 +olives +bartolo +polish +peanut5 +aguilas1 +khalil1 +uptown1 +chicken. +movie +wilfred +222888 +12141214 +dipshit1 +143001 +shauna1 +tri +duracell +5683love +nostromo +1yellow +molotov +officer +1dancer +dorina +cla +green33 +000011 +howdy1 +492001 +prettygurl +astro +jason5 +00998877 +icecube1 +ilovepink1 +carlos22 +120989 +vfvf123 +carlos23 +matrix +puffin +vfnbkmlf +bubble2 +gomez1 +charizard +wookie1 +naked +mikey12 +superman6 +destiny4 +raissa +franny +miguelangel +weiner +costa90 +carlos +school11 +dom123 +samantha13 +++++++@mail.ru +lerochka +apple23 +560093 +sosiska +rfnzrfnz +1008 +blowjob69 +carlos3 +maggie7 +hard +skylark +bball32 +200588 +dandan1 +hemant +midway +543216 +naruto15 +oxford1 +8080 +belfast +hottie21 +sofiya +filosofia +nothing2 +bunnys +smart123 +flossy +sowhat1 +mysterio1 +happylife +ginger22 +family8 +september5 +guitar11 +squeaky +shitfuck +frisky1 +mariamaria +saranya +111982 +pussy23 +password26 +saturday1 +svetka +170986 +lfhbyf +123! +denisse +buddy10 +superman. +mangas +different +fatiha +shannon12 +pratibha +freedom11 +chispa +james18 +orange23 +callofduty4 +pf +3131 +godschild1 +amber11 +football72 +ghbdtnghbdtn +94793763 +friends6 +olabode +celestial +emo4life +tripod +1redneck +pinhead +fs7600 +pendragon +whatever11 +martyna +whitey1 +batman +alex2008 +mike24 +jacque +harriet1 +hobbit1 +punker1 +film +daniel09 +123hello +sslazio +400092 +fantastic1 +jason21 +pipiska +loveme. +morozov +retire +shorty21 +dipstick +murugan +dasdas +121989 +charmander +paragon +shay123 +1234576 +n111011 +christopher +tacos1 +cupcake3 +peaches3 +crazy69 +goofball +alias +timothy2 +boulder +alex777 +bulls1 +sysadmin +sparkie +jaden +amanda14 +yankees27 +drumline +24081986 +morgan10 +sneaky +sakura123 +austin5 +pepperoni +decembre +strider1 +ilikepie2 +laserjet +conchita +travis2 +courtney2 +jellyfish1 +philou +leviathan +cameron7 +200300 +chance123 +marlen +333222111 +tweety7 +lin +friends13 +monday12 +methodman +fleur +timeless +lbfyjxrf +carmen12 +anth0ny +231231 +damion1 +adrian2 +sparky2 +nigga3 +loreto +eastern1 +dammit1 +chance2 +fatboy12 +ryan22 +120887 +130988 +montenegro +taetae +emily3 +tigger14 +122 +george3 +thor +memory1 +oriana +2580456 +daisuke +worldcup +edgar123 +fucker. +sunitha +sonia123 +deguzman +natasha123 +topbutton +god1st +poop25 +meandyou2 +carletto +chip +mcfly1 +pepper22 +tonight +daniel69 +bimbo +mantra +deleted +palembang +whosyourdaddy +rock1234 +champs1 +hotgirls1 +claymore +2hearts +stephanie +q18lg49iq8bhu +varsity +palestine +makenzie1 +mooses +graziella +z1z1z1 +foot +bitch8 +aventura1 +221286 +triumph1 +12241224 +blackmagic +balloons +achtung +wonderwall +buttface +zxzxzxzx +nathan3 +carioca +temple1 +nelly123 +ddddd1 +133133 +loki +tiger4 +class2011 +411007 +yinyang +lindas +gangster2 +peterbilt1 +garuda +babyboi1 +chris20 +rachel11 +merlin123 +byebye1 +abuela +metro +197000 +buster7 +oluwasegun +250587 +321cba +kenworth1 +loca123 +duke11 +rico +kahlua +alla +harper1 +sexy88 +killswitch +black69 +acidburn +scareface1 +payday +111187 +12311231 +katie3 +newyork7 +weedman420 +buddah1 +yetunde +samara1 +only1god +alex20 +vlad123 +itsasecret +ketchup1 +120986 +vancouver1 +br +nicolas +tianna +13579246 +four +mountaindew +angel007 +machoman +301087 +steelers86 +berserker +babygirl +warpten +yourmom69 +jajaja1 +1911 +karine73 +patricia +greengrass +120889 +carotte +madison11 +clarice +minerva1 +guadeloupe +77778888 +toto123 +sydney12 +peter12 +james16 +jocker +marialuisa +jos +carter2 +baby89 +lisa1234 +68mustang +a987654 +xtreme1 +cocacola12 +robertson +christiane +flower +123myspace +cancun1 +strike1 +1015 +helsinki +p00hbear +12qwasyx +ginger3 +dazzle +23wesdxc +peace11 +pianos +091209 +hollaback1 +countrygir +cs_000 +fatoumata +tumadre +javier123 +baraban +ban +tequieromucho +edward01 +arshavin +daniel20 +hibiscus +profession +abc.123 +miaomiao +sexy55 +angel33 +bidule +cherrypie +aztecs +wetpussy1 +antonio +jesus14 +joshua14 +bella3 +bullrider1 +bmw +lunchbox +frog12 +happys +220788 +loveu3 +collie +logan12 +suzana +shana1 +amadeus1 +heaven123 +neoneo +121186 +1233211234567 +cowboys8 +john14 +january17 +74123 +skater101 +patches2 +disciple +shadow4 +cross +sexygurl +matthew +kevin01 +nonsense +100689 +klimov +sar +loveyou4 +flower22 +smokes +brooklynn1 +louise +generic +120490 +bruins1 +chicks1 +nina12 +verano +fuckubitch +madhavi +mu0lfpv2 +110686 +tatertot1 +delfina +18121812 +cancel1 +ruffles +kingdomhearts +asdf456 +198383 +jason23 +110889 +carling +heybaby1 +soprano1 +love123456789 +lucia1 +johnson +cactus1 +cheese. +fagget1 +1sister +sorrow +success123 +polo12 +rainbow5 +triniti +rainbow69 +dianne1 +luigi1 +pollo1 +786000 +rugrat +penis! +rocks1 +playboy3 +freshman +yo +mexico23 +iloveu11 +loaded +redeye +1234567v +bball4 +dortmund09 +commodore +karamel +brian2 +softball24 +amore1 +nigger5 +emolove +baseball44 +p0o9i8u7y6 +track +datsun +ranger01 +iamgreat +joshua18 +127127 +kolkol +oberon +shana +090989 +buster5 +caution +evaeva +december6 +bitch420 +chevy454 +manny123 +adams +dumbledore +marmar1 +return +stockton +vidanova +ford123 +diamond6 +iris +bebeto +231090 +changes1 +password78 +speak2me +mami123 +110389 +kirakira +110888 +lottie1 +monster! +barrett1 +crespo +theworld +killer007 +augustin +gilmore1 +mus +aini1314 +rjcvjc +amit +sweetu +turnip +darknight +ilovecody1 +spillo +k1ller +julian12 +5252 +1216 +maverick +alicia123 +hogwarts1 +jose11 +boom123 +tamerlan +happy69 +cadence1 +sixpack +lovey1 +john69 +198911 +001973 +wingman +120187 +chessie +iluvu! +beverley +hotmail2 +110088 +capcom +marcela1 +mia +hehe123 +patagonia +paris75 +lovable1 +223223 +david07 +sober1 +sofia123 +save +drew123 +custard +sgdhhfc4x2 +freddy123 +maritza1 +02021987 +kzkzkz +luckyone +knuckles1 +1qqqqq +gnusmas +mimoza +brooklynn +ivana +november +8letters +grimreaper +discus +technics1 +trustn01 +daniella1 +jomblo +crazy7 +geisha +intelinside +cardenas +annalena +nicolas123 +pig123 +bbbbbbbbbb +scooter3 +gracie12 +lazaro +lanena1 +jjj +henry12 +storm123 +gangsta7 +blue56 +upyachka +matthew9 +starlite +smile3 +marie08 +help123 +220687 +eliza1 +nastja +121185 +address +partygirl1 +dragon101 +william13 +1qayxsw2 +costarica1 +nihao123 +bluejays +babygrl1 +hilltop1 +vampire666 +wankers1 +shalimar +iseedeadpeople +play123 +command1 +smartass +harley3 +carlos21 +bilancia +polipo +georgiana +speakers +rescue1 +cheese22 +135531 +123lol123 +candyfloss +freefall +clifton1 +mouton +buster +moumou +198522 +chris +123445 +fucker5 +hannah23 +whatwhat1 +blondie2 +matt13 +biatch1 +12121986 +bisexual +taylor23 +daddyo +savannah2 +teamo2 +mexico9 +ganapati +120790 +rrrrrrr +zebras +cosmo123 +daniel06 +sandrita +198012 +12356789 +shinchan +peppers1 +indigo1 +khankhan +asd123123 +321987 +edward +california1 +solitaire +orchidea +january10 +jaihind +ginger7 +316316 +katusha +family09 +811224bai +pizzas1 +nemo123 +amanda16 +typetogether +hedwig +sugarbaby1 +bb1234 +pajarito +bootsy +bitanem +my123456 +dwight1 +worldwar2 +121988 +12many +punk12 +1111aa +ich +cooper +22061941 +carnage1 +suburban +gfgfgf +gabriel7 +nicole25 +210688 +vijay123 +vladimir1 +kareem1 +arrow +1217 +ben10 +profesor +january28 +123sexy +popcorn3 +slipknot13 +0202 +friends +element5 +flower13 +1rockstar +openopen +shuttle +my4boys +jimbeam +420000 +vodafone1 +phones +bailey7 +tombstone +gasgas +sambo1 +jackie01 +woainima +loco12 +analog +741147 +lamejor +feelgood +jayla1 +love4all +vaishnavi +banks +beautiful! +masyanya +jordan17 +provence +jameson1 +luckey +110786 +softball16 +abraxas +killah +hawk +camcam +doggy12 +isabelle +yourmama +vinay123 +gostosa +angela2 +garfield +1drummer +snappy +qwerty90 +daddy23 +6789 +filipa +joshua99 +watford +sangita +12121988 +sup3rman +mydick +argent +loveall +fhvfutljy +joaquin1 +fresno +rocko1 +shippuden +rosina +poop99 +michelle69 +flower! +110990 +tx9z6ht5eo +luckys +u6kz2lppto +raghav +pompiers +123123qq +benjamin12 +minimini +miguel13 +pentium1 +vincent +pandas1 +pugsley1 +secreta +diving +summer23 +happy101 +balong +lamine +556655 +babes1 +flaquita +bamako +emily11 +razor +1369 +happybunny +koolio1 +fuckthat +forgive +building +bel +pooky1 +asdasdasdasd +tomasz +kantutan +100486 +cherry5 +prospect +a2a2a2a2 +shizzle +muffy1 +hunny1 +rockydog +hunter05 +fafafa +liefde +123qwe456rty +cedrick +jordan18 +220288 +denise123 +leanna +defender1 +trinity7 +rollin +jun +weiner1 +roseline +helloo1 +pussylover +notorious1 +mummypapa +pa1ub65udd +pepper3 +neenee +ab12cd34 +thizz1 +millos13 +ch33s3 +cutie15 +junior09 +papercut +december4 +07071987 +sitaram +lanena +wallpaper +171 +eduarda +blue08 +jojo13 +010185 +221088 +goxyboib +beaumont +whore123 +casey12 +pepsicola1 +lauryn +crayola +z010203 +birdhouse1 +mousey +1234567qwertyu +cowboyup1 +qqqqqqq1 +godswill +dragon! +fighting +sas +vk_vk_777 +sabrina +qwerty15 +loraine +superb +music01 +moustique +deskjet1 +7788521 +melissa13 +caligula +sco +canes1 +survivor1 +bombers1 +moment +matthew! +chelsea13 +goodnight +120188 +samuel +batman +lizzy123 +110590 +sadie2 +xzsawq21 +intheend +miss +dtkjcbgtl +chippy1 +deandre +110045 +nirmal +snikers +libera +bowl300 +tool +biscuits +jenn1fer +fuckhead +01011978 +pookey +legoland +idontknow2 +kashif +pepper7 +sting +killer! +021084 +alonso1 +jane123 +kendrick1 +cheska +1234go +innocent1 +winter10 +slippers +jasmine8 +10101985 +xsw23edc +doobie1 +scooby-doo +goirish +sexy100 +elvisp +6poppin +topsecret1 +johnny7 +superman14 +201088 +bong420 +lover6 +198210 +zero12 +namaste1 +assfuck +yankee2 +firdaus +audir8 +123456789987 +redwall +pineda +chameleon +111111s +skeptron +crissy +juanmanuel +football31 +makita +dexter12 +blondinka +hopper1 +january25 +smiths +stonewall +maggio +1stlove +junkie +saturno +kelsey12 +ruby12 +blinky +roselyn +blunts1 +january2 +dipset2 +thc2000 +mysterious +champ123 +creator +bhbcrf +minina +babygurl01 +12121989 +maggie! +london99 +himmel +191 +hope12 +lori +ilovejason +анастасия +bailey3 +vorona +knowledge1 +pekpek +bigass1 +brandy2 +element7 +miller12 +nissan240 +ibiza +120685 +1hannah +anaana +1128 +deuce2 +fabiola1 +dance! +christa1 +lucydog +hahaha3 +140289 +pumkin +hambone1 +marley420 +sucess +bambola +dagmar +jesse2 +1478 +cheer11 +luvbug +seminole1 +110489 +cubalibre +cooper01 +tony14 +wade03 +masterp +netball +catcher +ashley9 +dallas21 +nico123 +peluche1 +angelz +morocco +emo +sergio123 +eliza +eumeamo +crusher +jingles1 +thrasher +chikita +egor +easter1 +230689 +kassie1 +567765 +postman +kukuku +abc123456 +krypton +pussy13 +francesco1 +bowman +music4 +bhabes +guadalajara +juan23 +jologs +jared123 +snoopy7 +0p9o8i +evgenia +cole123 +786 +adrenaline +jiggaman +password12345678 +justin06 +ghj +sandy2 +100585 +oooooooooo +code +rkfdbfnehf +gaming +lolol1 +gary123 +fbu89bxx5f +babygurl15 +fatfat +starlet +frenchy +mustang +ver +fucku3 +flvbybcnhfnjh +220688 +123456love +maggiemae +000000q +silvester +foreverlove +jeanie +subzero1 +facebook12 +green9 +hounddog +lion123 +jacob13 +yokohama +karuna +printing +11223344a +parol +bitchs +smileyface +carlito1 +301090 +whatever5 +piccolina +05051985 +bigbuck1 +olgaolga +usmc1775 +5454 +chips +ioioio +ilovejake1 +150585 +senveben +vanity +godofwar1 +fuckyou99 +acdc +eastenders +iloveyou25 +allegra +topolina +vertical +under1 +kayla13 +tastatura +stokrotka +pokemon22 +sweet14 +exit_window +dotnet +jordan03 +cocopuff +12121 +gameover1 +pizzaman +3151020 +braden1 +bowwow12 +gogo123 +biggirl1 +olatunde +sashasasha +makmak +sunshine19 +mom&dad +198912 +skynet +silly123 +copper12 +vbhevbh +chris25 +angel12345 +ready +rainer +pooh13 +poopoo12 +watever1 +flyfish +#1hottie +lucky101 +tori +luvme2 +godofwar2 +220488 +prabha +blowme2 +construction +poornima +eudlekb645 +sunsun +a0123456 +frimousse +fars419 +001986 +nature1 +daniel9 +jordan02 +acosta +rockstar11 +chocolate123 +iloveyoubaby +1ladybug +198722 +nyt +my3babies +il0veu +andrew08 +sommar +wings +orchard +120385 +harley99 +glamorous +girlygirl +anupama +nurlan +231189 +jules1 +1233214 +121003 +jennings +harley7 +f14tomcat +spinner1 +eagles36 +shekinah +sexy26 +1christian +sylwia +qazqaz123 +buckshot1 +mama12345 +alcapone +noob +nirvana123 +duck123 +meuamor +okay +hannah06 +hooter +08081988 +eduardo123 +andromeda1 +january14 +war123 +iloveyou99 +woman +castello +minmin +kimberley1 +prabhu +grandson +sadie12 +mooney +mamasita1 +bigbutt1 +nicole20 +supercool +boston123 +2244 +w1965a +albert123 +junaid +4brothers +arjay +kwiatek +master23 +apple13 +1212312121 +catnip +jennifer11 +4twenty +mexico86 +jessa +jetaime1 +zuzana +psalm91 +classy1 +9thward +crayon +szeretlek +1111114 +bubbles01 +chaos123 +iloveyou +nokia2000 +890 +whitetail +a789456 +001985 +120390 +10101984 +mylife2 +porshe +loveu123 +tester123 +family08 +1108 +sanpedro +damage +garnett +saratov +alex19 +stefanie1 +juanjo +dragon18 +docrafts +besties1 +dadmom +2pretty +sting1 +fynjybyf +bert +twiztid +hello111 +elizabeth6 +senior10 +inspector +120785 +password1234567 +takecare +origami +fuentes +trujillo +4meonly +1127 +dino123 +sweetmother +hondas2000 +tucker123 +eldiablo +camping1 +pet +cameron5 +master1234 +cutie09 +110062 +atlas1 +marina +oluwole +boomer123 +creature +sandra +giordano +secret01 +iphone3g +wakeup +ladybug7 +bennyboy +ginger5 +cameroun +1028 +101284 +soloio +100487 +barney12 +kasper1 +corrie +goonies1 +bowhunter +diana12 +sugarbaby +1234me +1sexymama +mirko +coolest1 +spalding +amapola +snowball12 +funnybunny +spencer2 +stephy +1412 +bigbooty +koliko +123121 +cocker +franzi +smoothie +phillips1 +cnhtktw +kapitan +ashley06 +supermen +noob123 +121277 +lokiloki +dickface1 +new_user +2friends +ihateyou. +sara1234 +funtimes +blackjack2 +13691369 +avgust +bumbum1 +saheed +grape1 +crazy3 +543211 +westside3 +jewell +lollipop2 +baobao +1forever +understand +wireless1 +starr +jordans1 +zimmer +paulita +sonoma +melani +harvest1 +shadow8 +sasa123 +babygurl10 +davida +201090 +annick +london2012 +130688 +mamama1 +death12 +fuckin +killbill2 +110690 +annamarie +1109 +120386 +olya +six6six +tink13 +120584 +123520 +coco13 +highway +bubba3 +gabby12 +21122012 +jenny13 +trainer1 +loveme09 +01011992 +steven13 +240484 +samantha01 +10101980 +120484 +a1b1c1 +bojangles +anthony18 +angel28 +15963 +robyn +qwerty2010 +bucket1 +acmilan1 +bullshit! +pimp08 +chocobo +irule1 +sheeba1 +miami123 +espace +twenty2 +squishy1 +qazwsxedc +230588 +cameron +lickme69 +1q2w3e4r5t +acer +yomama123 +pink33 +012 +crazy5 +147852a +edgardo +dbz123 +jordon1 +one23456 +qwe123 +holiness +australien +turkiye +saphira +hanane +tuborg +mickey22 +110386 +121187 +cartagena +high +green18 +pisica +gfhjdjp +theman12 +ball12 +001984 +louis123 +toaster1 +sssss1 +taylor15 +acura1 +widzew +onetwothree +cromwell +treacle +gogetta1 +yourmom. +maddalena +jezebel +senior1 +malagu +121200 +jelly123 +rammstein +sierra12 +iloveit +alexandra2 +andika +mountains +sharingan1 +3ans97t397 +1346798520 +destiny01 +spiderman9 +south +555666777 +t-bone +159456 +0808 +brownpride +chivas7 +fiesta1 +elephant2 +gay +supers +xxx777 +january27 +blue101 +198310 +bonovox +me2you +becool +ladybug12 +samuel +skates +trees1 +inter1 +mama13 +byajhvfnbrf +fiorellino +bigbaby1 +beerbeer +grace2 +cowboys24 +spurs21 +martin +michelle1 +kevin3 +phoenix2 +senha1 +nigger. +ferrari +dancer3 +222666 +3brothers +vwgolf +230589 +springfield +alinochka +black9 +shorty22 +redeemed +sinatra1 +900900 +secret11 +12031990 +ericka1 +greenman +cornbread +tigris +olabisi +oneday +chipmunk1 +mustang05 +terranova +ariel123 +finally +spa +septembre +warlord1 +ladygaga1 +tsunami1 +alex1994 +lightsaber +smokin420 +shamanking +aaliyah2 +qwertyuiopasdfghjkl +cummins1 +thomas! +beethoven1 +lionelmessi +14321432 +snicker1 +melany +jazz12 +joshua05 +44445555 +nikolka +richboy1 +cookie21 +1017 +peaceandlove +russian1 +jasmine6 +peanut! +johnsmith +football75 +gtnhjdf +january7 +versace1 +198812 +vineyard +951753aa +131189 +frankie123 +1hxboqg2s +january16 +deltaforce +80808080 +hanumanji +lancaster1 +lala13 +charles +frogman +myspace25 +120287 +258 +florida +pussy11 +zaq11qaz +leeds +maldonado +joshua09 +2cute4you +polska12 +iluvhim1 +discovery1 +521314 +123345 +welcome3 +djljktq +samantha! +redalert1 +beastmode1 +astra1 +love78 +axel +221287 +chillout +diamond11 +dina +7654321a +smiley12 +mickey5 +denise +harley10 +angelwings +121281 +eva123 +maniek +ezekiel1 +melina1 +alfie123 +barcelona2 +jack22 +sparky11 +02580258 +corky1 +polly123 +sunshine08 +geraldine1 +120190 +royalty +dingding +maya123 +angela +cholo1 +willsmith +jasmine9 +nothing0 +parigi +kalyan +helpmegod +justin99 +311 +050588 +agata +larkin +trish1 +gertie +2bad4u +farhana +dragan +redapple +5566 +zachary2 +159789 +shiraz +mamans +sex4me +baby_girl +kicker1 +181 +11223300 +mitico +sassie1 +hawthorn +mailman1 +wildfire1 +poopsie +280888 +32103210 +kmzway87aa +hobbes1 +ichigo1 +january18 +fran +candyland1 +111289 +ladybug123 +basketball23 +poopie123 +yeah123 +1411 +r2d2r2d2 +seventeen1 +alex1993 +isaac123 +january15 +writer1 +whiterose +simply +volunteer +summer6 +babygurl16 +glendale +batuhan +ilovedad1 +yjwfn73j +marcos123 +familyof4 +20091988 +jaclyn +poppet +pepper! +100588 +adminadmin +blue09 +every1 +tipper1 +lalala3 +avenged1 +chelle1 +moemoe1 +password28 +slipknot +andreas +persib +159753q +badbitch +glasses1 +volare +petunia1 +monique2 +senior2010 +natnat +snickers12 +spoon +woodie +paroll +teatro +casper01 +11001100 +soccer45 +p1234567 +221090 +loveforeve +140290 +220689 +freelancer +fanta +commander1 +numlock +bermuda1 +w111111 +aline +pimps1 +100490 +feedback +234432 +bluedragon +sweet22 +assholes1 +hidalgo +gangsta5 +matter +harmonie +bigmike1 +morgan3 +gonzaga +ybrjkftdbx +basil +hurensohn1 +guitars1 +southafrica +daniela123 +verseau +vans123 +muzika +massey +ronaldo99 +251088 +blueblue1 +steel +man12345 +happy21 +isa +winter06 +theo +hotshit1 +slayer69 +1cowboys +atmosphere +sankar +january19 +porsche +westie +oc247ngucz +120787 +lorelei +milenium +pajaro +253634 +murphy +prachi +1qaz2wsx +19531953 +aleksandar +barcellona +00123456 +space4me +reddragon1 +lastfm1 +0505 +class10 +bubbles8 +12312 +jessi +tito123 +bamboo1 +tyler14 +250788 +applejuice +yellow10 +precious12 +julissa1 +rock666 +malaika +1113 +burgess +leone +freedom4 +josh14 +251 +666000 +hitman2 +mickey10 +madhatter +walton +369147 +thomas5 +bubbly +tabby +catman1 +jake22 +lord123 +maddie2 +hannah09 +12121991 +stuff1 +baubau +250589 +jeanpaul +money20 +jayden01 +221289 +greta +djdjxrf +dawgs1 +michoacan +chocolates +789632 +vickie1 +000005 +gogogogo +090990 +delta88 +dolphin123 +metalhead1 +lalala! +kitty4 +carmina +sweet21 +120786 +bigass +ilove4 +1812 +askim +rfntyjr +12345678i +fuck14 +fausto +degrassi +fatgirl1 +96321478 +patrick11 +qwepoi +mauritius +daisy01 +jose23 +12ab34cd +mclovin1 +vicious1 +piyush +long +earth1 +angel55 +mensuck1 +nokia1100 +edward3 +muneca1 +zackary +ariete +bubulina +211288 +guitarman +230988 +himalaya +jolly1 +demetrius1 +rebecca2 +02 +valeriy +6173580 +jose15 +supra1 +ashlynn1 +234 +friends +bowser1 +newworld +pooja +informatica +120886 +asdfg1234 +alskdjfhg +katzen +m1m2m3 +1horse +bling +udacha +higgins1 +january26 +czz123456 +octavio +rom +123aze +complicated +12345u +dkflbvbhjdyf +live +6y4rv0a992 +evangeline +fuck777 +110890 +empress +jonathan13 +izabela +sassy101 +gunslinger +1richard +bandit11 +101186 +lincogo1 +caprice1 +tit +nikoniko +advanced +2311 +arsenal1 +darshan +harley05 +kanarya +00000007 +volcom2 +alex1996 +v123456789 +1heaven +coolest +mother1234 +82468246 +.......... +love1995 +fenway +rocky6 +cheerios +12121985 +prince22 +jensen1 +workhard +kk1234 +raj +pacers +poontang +maelle +1q3e2w4r +oscars +jason22 +198181 +250388 +okmijn +dogsrule1 +kerala +9090 +maltese +jose10 +shinichi +nakita +bella22 +gossip +baller4 +asdqwe123 +chiquito +thalia1 +akira1 +241188 +infotech +soledad1 +121086 +yasser +seos1234 +halfpint +davina +stopit1 +fuck-you +david17 +natalie +popcorn7 +rudolph +cj +ttttt +carver +asdfgf +weston1 +anand +180180 +guildwars +lolilol +acer123 +410210 +241088 +shobha +console +hollydog +bullfrog1 +password94 +love1994 +230987 +raphael1 +lsutigers1 +booyah +olaoluwa +roxie +1qazwsxedc +yfnfkbz +alexis +loser22 +coach +vinayak +password05 +destiny11 +5683 +marcolino +misspiggy +dasher +iceice +123444 +karin +sunny2 +1prince +madison6 +capitano +wolfie1 +password +devilman +andrew16 +director1 +tamika +nazgul +020288 +snicker +cris123 +lock +kris123 +cooper11 +right1 +1maggie +marivic +omega3 +jennifer13 +bored +roma123 +ddd123 +niggaz +collection +jetta1 +annabella +roxygirl +100789 +bryanna1 +orange01 +tango123 +130686 +qwer11 +vanvan +ravi +charlie08 +robyn1 +6666661 +piotrek1 +12332100 +milan1899 +david6 +zippy +kitsune +redeemer +tigercat +tomorrow1 +claudiu +bibibi +00000001 +babyboy7 +softball08 +120290 +col +hannah02 +sportster +samiam1 +110788 +sacrifice +psalms +grenoble +021 +101081 +jayden12 +cochon +1234 +nena12 +andrew07 +dakota13 +lashawn1 +squeak +didi +googlecheckout +foufou +daisy13 +200808 +pawel +rich123 +froggy12 +05051989 +mylove3 +bigdick69 +nguyen1 +j3qq4h7h2v +john21 +excellence +september4 +1234qwert +killer09 +1946 +utn05wwy +st +qwertyuiop12345 +holysh!t +szerelem +kitty! +imperial1 +happiness2 +jessica08 +bobo12 +210990 +martita +dima1997 +weeman +steel1 +louie123 +daniel1234 +pepito1 +taytay123 +brando1 +jacinto +servant +23031990 +spoon1 +rainbow! +july07 +pronto +passe +logout +maniac1 +jesus8 +catlover1 +asdfghjkl9 +loveme1234 +ladybug3 +asdcxz +number14 +211221 +landscape +best123 +spankme +reebok1 +love97 +superman19 +gatinho +asakura +bonifacio +face2face +hack +redsox11 +12345678911 +babyj1 +090988 +phoenix7 +wanted123 +cuntface1 +honeydew +quaresma +samolet +aassddff +987654321z +fathima +speedracer +phone123 +heyhey123 +ricardo123 +bismark +corinthians +bello +rubbish +mongolia +chavez1 +12300 +iloveyou!! +hubert1 +forever5 +jasper2 +nokia8800 +vitamia +bengals85 +cabron1 +120491 +maxdog +1014 +baseball34 +davies +james24 +12349876 +billyboy1 +sh +130689 +dallascowb +tanya123 +first +camacho +basketba11 +nikole +amanda5 +starz1 +chelsie1 +smokey +dragon1234 +1026 +superman24 +squishy +maximius +lizaliza +fan +bigcat +hottie07 +wilbur1 +kennwort1 +budgie +aliska +master3 +fuckoff3 +reynolds1 +196666 +mopar1 +trout1 +parola12 +sparks1 +america01 +dreamland +naples +mapuce +nirvana +77777778 +caring +140288 +wildbill +love1993 +7thheaven +shantel1 +angelfire +121190 +gerber +penguin123 +eintracht +tre123 +anthony16 +terra +chappy +101184 +viktorija +kimberly2 +tanisha1 +911119 +pogiko +seadoo +imperator +11111z +262728 +hunter14 +220188 +kingdom2 +alexander5 +password: +isobel +010407 +5starchick +lover10 +penis2 +daniel24 +garrison +sadness +hamlet1 +fuckhead1 +hollister9 +foxfox +quinn1 +kevin22 +preciosa1 +avenir +marianne1 +sami123 +her +weewee1 +maricris +foxfire +freshman1 +12q12q +kiko +swag +sanane123 +ciara +daisy11 +stephan1 +sexymomma1 +shosho +yesterday1 +amaterasu +princeton1 +qazxsw21 +2000000 +hockey23 +dancer101 +robert! +isabella2 +bloodlust +1nonly +1030 +121084 +carlos7 +amores1 +shopper1 +monkey27 +paolita +schlampe +jennifer01 +210987 +anthony06 +salvo +chuchi +linkme +jas +ilovesex69 +yankees +123456654 +stop +123456qwert +rockie1 +800800 +aaaaa11111 +roxy11 +cameron1 +patpat +bavaria +115115 +a222222 +addict +monito +village1 +prisonbreak +perfume +vfvfvf +darkness +square1 +johnnie1 +godiva +mot +blazers +z123123 +barcelona10 +654 +blah1234 +birgit +halo117 +tigger +schnuffi +user123 +130690 +happy23 +contrase+a +info123 +bububu +shine1 +stoney1 +stronger1 +referee +pin +lola1234 +romanova +mine123 +madison08 +20101987 +sparco +1234561234 +matthew21 +andriy +montana16 +dmitrii +dulce +taylor8 +lookout +blacks1 +iamgod1 +sunny12 +carley +sycamore +110490 +chandigarh +erasmus +ultraman +01011977 +passionate +120387 +compact +fortaleza +420allday +hrvatska +lexi123 +queen2 +novikova +newlove +planning +godfirst +aaa333 +369 +rayray12 +pretzel +karolinka +thornton +sparkey +lockout +texas13 +pongo +katina +q123321 +120985 +love1992 +250590 +cypress1 +internet12 +imthe1 +asdzxc1 +spring08 +leland1 +goodfood +anthony17 +hesoyam123 +brianna3 +moe123 +1126 +monkeys! +asroma1927 +leopardo +horselover +3353212li +linklink +poohbear13 +xxx333 +mike07 +padres +lauren10 +matthew22 +david08 +100388 +espinosa +izzy123 +victor2 +101190 +passcode1 +samina +141288 +vvvvvvvv +1fuckoff +duke01 +f00tba11 +girish +22332233 +boozer +vaz21099 +onelove123 +manasa +catwoman1 +liezel +almost +baller14 +belkin +123456789qq +110003 +120990 +daisey1 +desperados +dolfijn +samantha +svetlana +hitler88 +crystal7 +ponies +tupac2 +zinedine +2wsxcde3 +andrew06 +cowboy22 +bohica +princess94 +greenhouse +amylee1 +995511 +herkules +leather1 +143444 +65656565 +josue1 +linux +get +1234567890qw +alex1992 +skeet1 +120890 +roadster +joemama +iloveu8 +babycakes2 +thistle +dre123 +nebula +slipknot69 +hayastan +123098a +top +1playboy +filler +parts +2puppies +3141592 +architecture +rubyred +soyelmejor +sonic12 +mouser +gangster13 +newyork5 +tammie +blubber +hotel +waiting +angel00 +111223 +biker +ilovekevin +ambulance +czekolada +zoltan +kitty22 +kisses123 +sasha1998 +benjamin1 +boss302 +fuckedup +dalejr08 +******* +happygirl1 +clarita +jason3 +dtythf +gatita1 +mommy101 +nbvbb32fa9 +kitty10 +thebeast1 +010181 +computer! +@mail.ru +bonethugs1 +221189 +findus +buddy23 +alexander8 +phyllis1 +password95 +johnboy1 +azzurro +tttttt1 +1alexander +hottie09 +flhtyfkby +gangstar +mymoney +feeling +diamond1 +contest1 +redsox123 +celtic88 +diamond8 +15975346 +lovers3 +christina +marquise +110586 +adventure1 +centurion +hiphop12 +death2 +pepper10 +saiyan +superbad1 +united123 +hotty123 +akatsuki1 +07072007 +sweetdream +pap +aisha +admin12345 +lauren3 +shaker +internet2 +attention +110015 +august9 +100889 +jughead +001987 +princess95 +smartboy +rudeboy1 +ocelot +hotbabe +231186 +cutie23 +anna13 +ma +lolz +miguel10 +spiffy +rhbcnbyjxrf +jeanine +blackbelt1 +231088 +willywonka +ironman2 +music22 +exchange +120885 +denny +hesoyam1 +smurf +manuelito +excalibur1 +1234578 +1928374655 +oatmeal1 +michaels +ninja2 +waldemar +mavericks1 +metalhead +shikamaru +dee +lucy1234 +tonka1 +bitter +doors +iluvu123 +kenny12 +makenna +lilwayne3 +junior07 +ve +hannah05 +belarus +400058 +kayla11 +panther2 +q2w3e4r5t6 +elektro +ppppp1 +aberdeen1 +baby143 +babette +110985 +sa2rawybas +football80 +purple99 +camilita +olds442 +231286 +mandela +avrora +150388 +homerj +petite +charles3 +all4you +candy01 +kozerog +livewire +johnston +getmoney5 +marciano +karmen +herohonda +sexymama2 +alonzo1 +clay +agente007 +karoline +brandon16 +booboo7 +jet'aime +fuckher1 +pebbles2 +thugstools +monsoon +queen12 +spoons +kane +juju123 +edward! +monies +369874125 +2wsx1qaz +josh23 +890iop +hamza +wordup +123456kk +qwer123456 +vlad1997 +shadow16 +drago +getmoney12 +sdfsdfsdf +rockhard +ktutylf +witch +vicious +veronica12 +411028 +boating +eric1234 +love42 +tweety11 +air +nathan10 +greatday1 +allaboutme +purple09 +140688 +198721 +summer8 +goodcharlotte +1music +beetle1 +papounet +001002 +king15 +100827092 +andrew6 +loveyou +jasmine +matheus123 +111288 +baseball123 +jesus15 +knockout +1234567abc +210487 +islander +bastet +241 +tierra1 +parol1 +dingo +handball1 +dasha123 +tigger08 +rosalina +val123 +natalie12 +abimbola +attorney +corinna +naosei +baylee1 +chingon1 +111186 +british +1597535 +cjytxrj +mickey23 +hotboy2 +tigers10 +christian +olajide +melisa1 +pride1 +1hotboy +0815 +theatre1 +fallenangel +963214785 +wrestling2 +facebook123 +garibaldi +juggernaut +26041986 +01011975 +120483 +ererer +escort1 +nirvana2 +nomercy +cccc +liebe +radhasoami +princess92 +!qazxsw2 +thakur +freak69 +spotty1 +trapstar1 +blackhole +210586 +220022 +gerrard08 +mommy10 +cumming +bharti +letmein12 +five55 +220589 +super1231 +silva +segun +power5 +franz +milkyway1 +travel88 +jesus666 +ayobami +vasquez +yankees1 +29 +kb9zc8uxtx +kylian +1george +freedom5 +benita +nightwish1 +cameron01 +stunner1 +kevin21 +ser12345 +blahblah2 +ashley20 +lyudmila +bigpimp +horizon1 +hotsex1 +diabetes +arrowhead +master21 +heaven12 +missouri1 +pakistan +kryptonite +jledfyxbr +pramod +hippos +maranata +faith12 +bmw325i +vic123 +cambodia +foo +wolf12 +emogirl1 +reporter +marie09 +tayler +310589 +lovebug123 +deadly1 +niharika +123789a +201286 +wildchild1 +blood13 +157157 +starwars123 +meathead1 +1001wdst +daisy3 +oswald +cruzeiro +paroli +hammertime +player11 +alexis08 +babygirl#1 +100589 +mamabear +100289 +brittany7 + +candy69 +baby12345 +belize +speed123 +shadow00 +baby1 +2210 +loser6 +manman12 +zcxfcnkbdf +y12345 +latin1 +1006 +150688 +justlove +moochie1 +maniez +neenee1 +sososo +iulian +asdfg6 +iloveyou05 +loser01 +ian123 +muffin11 +210890 +111988 +gordo +1219 +karen12 +michelle. +ikechukwu +cat12345 +brighteyes +duarte +303677 +dog12345 +andrew17 +emma11 +17931793 +fifa08 +lucas12 +111286 +ngockhoa +mayfair +blumen +death2all +230687 +110587 +salinas1 +10121990 +mamusia +251089 +justlooking +vermelho +241086 +hopeless1 +vasantha +clitoris +joey11 +friends4ever +cassie01 +shimmer +210789 +smartie +halo3odst +joaopedro +backdoor +chester12 +chicha +banana! +210690 +1love +mazdamx5 +john +froggy123 +lera +computer. +02021988 +skate11 +submarine +apjsqpm844 +lovely01 +marrakech +230393 +cyclones +nick16 +princess89 +cocoa123 +saravanan +monkey44 +family13 +hockey6 +230390 +110687 +teclado +vignesh +cbr1000 +b12345678 +hercule +sexkitten +sabrina12 +magico +mai +mikey2 +251090 +jesus123 +football06 +jean123 +bruce123 +ipodtouch +ron123 +kara +cubano +weirdo1 +ghbdtndctv +slinky1 +42424242 +jc1234 +murphy123 +key +brittany! +abc123abc123 +198523 +penis12 +metro2033 +tabatha1 +damian123 +blackmamba +margo +15975300 +210188 +trey +230389 +junior14 +231087 +ggg111 +maroon +100489 +dancer7 +lovingyou1 +seguridad +volodya +compassion +151188 +asuncion +question1 +2balls +1492 +killer88 +123456321 +emilie1 +micasa +outback +maruti +cruiser1 +momdad123 +123654789a +oli +anubis1 +nevada1 +alexander4 +winniethepooh +wildthing1 +jolly +asian +weapon +danial +rockin +kareena +karissa +55555q +jaydee +madison10 +soumya +lifeline +230688 +159357123 +088011 +kikokiko +go +lovegirl +charlie07 +ilove13 +shelton +beach123 +testqa12 +rfnmrf +acacia +fender123 +pbvfktnj +omerta +210488 +310588 +tre +homealone +erin123 +09 +11121987 +pimpin7 +sugar12 +moore +love911 +fairways +web123 +boston2 +chocolate +goonies +brandon09 +behemoth +ric +tigger07 +131088 +mohamad +201288 +spawn1 +super10 +323323 +sunday123 +justin24 +131186 +softball09 +eyeball +emotional1 +candy22 +charleston +newmoon1 +197700 +equinox +happy8 +loveispain +325325 +angel95 +charlie21 +06061986 +43046721 +police911 +birddog +jasper11 +1bulldog +saravn +150890 +trustno1 +dodgeviper +prince01 +velasco +ambrosia +vampire13 +5432112345 +iwantyou +nikitka +bowhunter1 +antoshka +hahaha12 +ducks +fiction +tennis11 +l1verp00l +linked +wonderman2 +cornell1 +destroyer1 +thomas69 +llcoolj +paolino +arjuna +freedom +cvbhyjd +maria15 +barca10 +cbr900 +100890 +xsplit +loca13 +arcangel1 +atalanta +machines +cross1 +postal1 +taylor09 +22112211 +brandon07 +buterfly +topher1 +kikugalanetroot +pimpjuice +raiders7 +bianka +azrael +alcantara +lucylucy +moomoo123 +bassmaster +rfgbnfy +thethe1 +family04 +urlacher54 +muller +cameleon +love520 +rhodes +infantry1 +sevens +gametime +22011988 +newyork3 +marci +ukflbfnjh12 +center1 +231086 +husker1 +varsity1 +kevins +sarmiento +remember2 +guille +140789 +daniel88 +kotek1 +job +lanzarote +251188 +nick10 +asshole13 +raheem +january29 +bujhtr +factory +261088 +jesse13 +chelsea! +teufel +nana1234 +princess05 +carlos14 +55556666 +tiger6 +bahamas1 +smarty1 +iloveadam +christ7 +abc_123 +roosevelt +woodside +katie11 +amicizia +january3 +teddie +bitches69 +spiderman0 +pitbul +louisiana +bff4life +victor13 +serene +music. +symphony +icecold +100389 +123123asd +termit +12341 +destiny13 +amo +911911911 +maniak +251288 +balla +010189 +tiger69 +bigbig +katy +jasons +pretty3 +ninja12 +jamielee +poop23 +anthony. +delboy +abcdef1234 +100687 +jaredleto +killian1 +1010101 +znt +silvestro +mj1234 +sammy5 +110987 +thedon +201289 +summer2007 +foreveryoung +197400 +mandala +fishface +kittycat12 +catsrule +230383 +danielita +fuck420 +ingrid1 +elvis77 +scirocco +prikol +bryant8 +stoned1 +dolphin12 +chris05 +zombie666 +buster69 +++++++++++++ +1580@welcamino +martinka +246246 +sunnyboy +4linkedin +goodie +donkey123 +johnson2 +mindfreak1 +andrew18 +petra1 +grand +candy10 +apples11 +eniola +lebanon1 +joseph10 +daisydog1 +ilovelucy1 +diamond +р№с†сѓрєрµрѕ +skills +zxcvvcxz +redskin +ham +hannah9 +myspace666 +momma +mets +surgery +bonnie12 +goodlife1 +sticky1 +010186 +al +sasha2 +09870987 +niceday +carlisle +delmar +stanton +brewer +floppy1 +qweasdzx +admin12 +thatshot1 +mike16 +deejay1 +lovely21 +gracias +carlos15 +wyatt +destroy1 +fresno559 +151288 +passwor1 +brownie2 +iwantu +yadira +drumline1 +boytoy +savannah12 +198710 +monkey92 +jarrett1 +220388 +bitches123 +bismarck +alex00 +daddy69 +roller1 +openit +triplets3 +mombasa +220487 +tunafish1 +barefoot +rocky13 +daniel8 +kukushka +makarova +curly1 +thomas14 +100190 +jeremy01 +cookie69 +winston +buddy1234 +1spongebob +manutd123 +ade +dance3 +241089 +orange10 +maria01 +ronaldo +cheesy +diablo12 +closer +scuba +simplicity +reese + +getmoney08 +media +animal123 +surfsup +purple08 +130589 +q1w2e3r4t5 +292814lolo +rickey +raoujfl963 +bubble123 +happy420 +mentira +heybaby +danielle7 +singapore1 +coronado +400703 +sarah01 +flyaway +scooby11 +alexander6 +bambam123 +fightclub1 +raptor660 +martin13 +sword1 +120783 +131131 +mabuhay +tolentino +kitty01 +password31 +candyland +crush +georgina1 +liuchang +blades1 +monster4 +dipshit +stars12 +my3angels +cubswin +emmaemma +die +guam671 +greens1 +tumadre1 +orange21 +sombra +troy123 +longlife +220987 +sorrento +pearson +220690 +aprile +soccerball +jaishriram +192168 +andrew99 +stretch1 +$money +bubba7 +mydaddy1 +161 +jeroen +milica +210489 +trick1 +tara123 +lhepmz +tagada +charon +metallica7 +rerfhtre +nickolas1 +fuckup +marie +titans10 +company1 +motivation +900000 +cars12 +goodguy +tiger9 +b00ger +u0hgtkt617 +schnucki +joker5 +green69 +1qazxcvb +frdfhbev +131286 +favour1 +lovely22 +luvme1 +1234qwer +killah1 +victoria +theater +dima1996 +shelby11 +emily01 +3636 +peacock1 +lifesux +131087 +robots +gilipollas +blazeit420 +angel94 +david18 +400066 +coline +firefighte +tinatina +mustang07 +78907890 +nigel1 +puppys1 +sexyone +easytocrack1 +stream +donkeykong +oassw0rd +new975wen +angel2008 +john10 +ratchet +buttmunch +101001 +jackoff1 +cris +passwor +turtle3 +family07 +ohshit1 +ccccccc +google5 +120189 +lawyer1 +noles1 +goalie1 +filhos +dabest1 +aleks +50000 +beer123 +yaalimadad +blaine1 +inspiron1 +everest1 +hancock +baggies +timur +florida12 +mike18 +110984 +feifei +alex1990 +buratino +brad123 +daking1 +123fuck +world123 +mtizndu2 +creamy +peace13 +beacon +bronte +boobies! +spidey1 +fyyeirf +edison1 +katarzyna +fuckoff. +thetruth1 +microphone +olemiss1 +grace12 +marlyn +sammydog +231187 +kovalenko +198623 +13421342 +hellokitty1 +nolan1 +mohamed123 +underdog1 +stones1 +231289 +ledzep1 +americano +210385 +erhfbyf +tiara1 +5544332211 +11011990 +lickit +qwerty33 +amanda +hustle +gelato +imani1 +donbosco +monkeys12 +poiuy1 +taytay12 +100488 +mama10 +karinka +manny24 +moises1 +rajput +thesims1 +ilovedan +survey +badass123 +bubbles +nigger3 +michelle08 +destiny6 +1jackson +ismael1 +mishra +wealthy1 +hellome +lemon123 +rockstar3 +14021991 +chango1 +pft: +010187 +jumong +jarjar +sexy34 +newyork11 +nicholas1 +dani12 +204060 +politics +labtec1 +123321456654 +favorit +dickson +monkey0 +vivalavida +greeny +asdfgh123456 +201186 +liteon +bella08 +hellno1 +supra +bambam2 +whore69 +computer7 +studioworks +buddy101 +88888888a +giggs11 +ayrton +mindless +21071988 +baby92 +kitties1 +aj1234 +230585 +220590 +123pass +samson12 +lc519qlpuu +nikki13 +february14 +panda2 +love007 +zachery +fish1234 +uptown +gonzales1 +fishhead +bloom +halohalo +fh +flower01 +71 +ilovecats1 +sunfire1 +lambert1 +kaka12 +gfhfljrc +231190 +sickness +buddy22 +grandprix +veritas1 +hihi123 +robins +madison07 +september0 +banderas +manhattan1 +110887 +sardar +candy23 +yang123 +nishant +knitting +222000 +110790 +shinoda +maksik +qwert11 +oooooo1 +michael06 +youngblood +cute11 +clippers +honey3 +slipknot7 +150690 +dragon25 +realtek. +luv2shop +711711 +tammy123 +scarabeo +pickles2 +sexy05 +ally +godlove +shadow17 +thewho +231085 +qwerty17 +jessie11 +080880 +kk123456 +adelaida +021288 +pigpig +230789 +secretary +dadada1 +jamie2 +brokenheart +sara2000 +cxfcnmttcnm +playa4life +pimpin23 +qwertyuiop1234567890 +123579 +maxmaxmax +tabata +monkey19 +fleetwood +toodles +piopio +1256 +hotman +leckmich +knockers +music08 +alexander +fredrick1 +qw12qw +robert14 +my4girls +bedrock +alvarez1 +icecream! +schalke04 +peanut10 +onlyone1 +welcome7 +cthulhu +paula123 +1018 +machado +august +cheer5 +daffyduck +mustang88 +pistol1 +316497 +beachbum1 +megastar +brandy +pitchoune +oussama +gjmptw +algeria +hannah15 +1mexican +carlos5 +lilone +jeremy +1hotgirl +antonio +radost +michael19 +matt22 +123qaz123 +tony69 +nicolle +k.: +i<3you +yamaha250 +rocawear1 +crf250 +superman15 +morley +tazmania1 +221087 +fuckabitch +lovely23 +hottie8 +muziek +dooley +sanmiguel +knickers +beast666 +sweetlove1 +guitar13 +210988 +redneck01 +january31 +kisses12 +mannheim +steven +110486 +fake01 +mm1234 +maui +soniya +jayden06 +olakunle +jodie1 +monterey +tashkent +345543 +jiajia +mommy23 +gaga +060689 +reyes1 +scenic +110005 +joaninha +bball20 +children5 +concept +hello00 +arrows +1friends +derek2 +34erdfcv +211187 +cristiano1 +oliver10 +kathrine +eagle2 +bilbo +pantyhose +doudou1 +kolyan +110986 +marnie +saunders +think +sissy123 +titanik +william8 +logitech +cowboys7 +110390 +guanajuato +threesome +maria23 +chaparrita +king14 +olivia11 +my_space +rebirth +brittany +tututu +hothot1 +abbott +tygrysek +silver +hottie9 +nathan13 +rock13 +hayabusa1 +dbjktnnf +kids03 +hinder1 +4family +slayer12 +tigresse +den123 +n0thing +1016 +123baby +jordan98 +11041988 +05051987 +jomar +brianne1 +penguin2 +123456aa +buddy4 +bailey22 +111290 +pretender +purple25 +gina123 +shreeram +stripes1 +12091209 +browny +simons +abercrombi +pascal1 +geneva1 +flubber +abacus +reeses +100590 +31121987 +miki123 +godschild +halowars +1whatever +patrick +wanda +tempesth1941 +fgfr56hfve6 +samuel2 +myshit1 +dogman1 +parrot1 +dante123 +111088 +12345qq +12021988 +999333 +3691215 +iloveyou89 +apostol +250188 +angels11 +700091 +pallavolo +mama01 +elissa +w1960a +lakewood1 +anfield1 +molly7 +01234567891 +130789 +forever22 +recall +zhanna +nathan08 +220585 +cyclone1 +bhavani +221186 +alex123456 +superman20 +zaqwsx1 +hoochie1 +money16 +century21 +chips1 +christian9 +amateur +hockey101 +ladylove +jessica09 +jello123 +reussite +bebeko +cisco +deepti +lilman2 +waldo1 +130585 +130586 +corsair +xxxxxx +triathlon +1234567895 +buddy6 +cfvfhf +tweety5 +benetton +pasport +solene +larsen +paul1234 +137137 +bitch00 +240587 +joseph22 +z1z2z3 +carolin +030388 +clocks +shorty! +e8szn4e5zc +nino +horton +radar +281188 +r0bert +bigpoppa +gabriel +joey1234 +karina12 +decker +19101989 +yessir +jack10 +thomas4 +asasin +misha123 +honey01 +blue20 +bless1 +gan +duende +parolparol +waterpolo1 +humbug +rebel123 +121091 +060690 +cocorico +chukwudi +160686 +marie4 +dickies +!@#$%^&*() +chubbs +aspire1 +guesswho1 +brooklyn5 +1heather +bubba01 +rostik +raiders24 +bosslady +ilenia +comedy1 +boyboy1 +marathon1 +chamber +emilee +150290 +lovely. +kurtis +jeanjean +ipod12 +131089 +123admin321 +bobobobo +chinito +casper11 +amir +comets +100586 +vengeance +34523452 +gallina +tt1234567 +fresh12 +w1234567 +ilovekyle1 +max333 +fuller +tippy +sonson +261089 +yo1234 +harry2 +calogero +saviola +spider13 +albino +metalgear1 +blanka +120583 +2myspace +100987 +aguilera +med +kayla5 +kamilek +amanda17 +cory +jason69 +loveyou. +george13 +101291 +nicegirl +nnnnnnnn +euclid +251187 +aspen +daylight +bloody5 +cheer4life +peoples +tweety14 +210388 +maks123 +bug123 +170588 +110287 +palacios +relisys +dragon89 +arellano +spaceman1 +roseanne +pujols5 +zxcvbnm7 +aeiou +moroni +casa123 +david16 +january8 +nipper1 +actress +241186 +babygurl09 +12041990 +whitegirl1 +socom3 +hallmark +bear01 +packers12 +jacob5 +v000001 +pussy6 +963214 +bat +zinger +password30 +147369258 +small1 +west12 +ilovegod2 +jaisriram +mommy22 +231184 +muppet1 +tundra_cool2 +112233445566778899 +lisette +frisbee +paperclip +viviana1 +ripper1 +summer02 +angel92 +popsicle +210587 +genius123 +carman +221190 +princess27 +lilkim1 +111981 +krzysiek +rolando1 +aakash +808state +suzette +lovebaby +cyrano +molly3 +morkovka +987654123 +nicolai +ada123 +duffy1 +severus +mouses +algebra1 +ub6ib9 +death6 +forever. +trase1990 +codename +heather1 +skater69 +sebastiano +mustang73 +19491001 +bike +soccer26 +220988 +tenchi +anderlecht +videogames +christi +january24 +mashina +woailaopo +preethi +finnegan +love2dance +198425 +suikoden +02021985 +joshua15 +sexy27 +pogiako1 +dmitry +shaolin1 +heather3 +anthrax +boss12 +austin22 +jana +lambofgod1 +mahalo +loveme08 +miley12 +january6 +michael88 +pretty7 +121983 +nike10 +friend12 +rjcnbr +poiu +chinadoll +naruto21 +balla23 +bigdaddy12 +stan +whatthe1 +emma01 +ljrnjh +12051988 +amarelo +frank12 +maelys +eddy +sweet23 +integral +pencil2 +230487 +domingo1 +cornbread1 +1q2w1q2w +jannat +nickcarter +kochanie1 +dfgdfg +outsider +bongbong +alex2009 +987321654 +miller2 +beware +eeee +cena123 +ginger! +draco1 +12121992 +dima1998 +babyangel1 +xtkjdtr +goarmy +spinning +975310 +goodwin +rossi +21101986 +estrellas +ladyluck +kil +linlin +122436 +star17 +222324 +leeroy +301 +230888 +nigga23 +tatanka +jesus1st +050589 +ireland +dummy +babe13 +heaven11 +yellow. +adam01 +vanessa13 +ambers +nadia123 +251286 +peterson1 +cowboys11 +4r5t6y +linkedinpass +98741236 +150488 +sairam123 +wildman1 +12344 +marie17 +dimitri1 +58585858 +20101988 +ball123 +cashmoney2 +executive +veronika +mommy13 +girly +records +just1n +misamores +jeanpierre +abc123def +110289 +barbados1 +100690 +assclown +merlyn +peanut +jimenez1 +123zxc123 +bass123 +pass2 +nicole05 +101283 +233223 +908070 +redbaron +amanda. +madison06 +kayla3 +shadow77 +100886 +glass +fannie +comet +nikola1 +110886 +per +gabriel10 +1world +butterflie +orange8 +galway +astana +albero +ilove7 +milano1 +123456aa +251183 +nipple1 +daughters +231287 +01011979 +monkey06 +iamgay +greatest1 +summerof69 +kitchen1 +lau +cowcow +amadeus55 +saverio +dead123 +babygurl7 +220588 +corinne1 +antonio13 +comeon111 +marriage1 +19501950 +drummerboy +schwarz +314159265 +138138 +010184 +nisha +shaira +gotenks +sk8forlife +1stupid +agent +tigers08 +outside +lumberjack +entrar +tacoma1 +pharmacy1 +rizwan +sammy101 +rock4ever +09877890 +patric +melissa11 +lovex3 +alyssa3 +lizaveta +alexis4 +arhangel +josh22 +teacup +nolongthing +silenthill +bal +hairspray1 +mariner +lovely +richman +alltimelow +one123 +southwest +caravan1 +smile13 +dandelion +love555 +bella09 +forzalazio +pimp24 +jackson01 +computers1 +gaviota +magics +glenda1 +nick14 +maria5 +jocelyne +rhbcnbyrf +gemstone +popolo +bigboy3 +paramore12 +lebronjames +loading +ayanna +dragon55 +badass12 +hunter03 +jeadmin +110787 +billgates +habibi1 +radek +getmoney09 +kiki11 +230989 +dragon16 +666devil +qwqwqw1 +marie07 +220888 +students +260689 +spike2 +dkair8dda +121990 +rahasia1 +stella12 +test01 +momof5 +balance1 +lovely5 +150590 +naruto! +gonavy +xavier12 +asdfg5 +apple10 +jordan. +bubba13 +sparta1 +halo2 +a123sd +navyseal +400709 +miroslava +130487 +spawn +lilred +dondon1 +lakers11 +marie18 +1129 +29292929 +teabag +hunter! +powell1 +24681357 +w1w2w3w4 +cbr1000rr +bluesman +eagles05 +lovesick +ceejay +150587 +01012008 +monkey66 +tan +orlando2 +sonya1 +120391 +darien +dempsey +sublime420 +a123123123 +data +poopface +jordan25 +kaplan +ignatius +230986 +hacked1 +1beauty +thejoker +flapjack +loverboy12 +killer66 +1ginger +blacklabel +monster69 +mayamaya +fylh.if +fairies +assface +austin08 +500082 +damon +beautifull +bricks +allh11 +12021987 +wer11111 +jurassic +290988 +bollywood +michelle09 +joecool +20051987 +charlotte2 +nicole89 +lautaro +beastmode +james8 +oinkoink +220587 +5678910 +198919 +jonathan3 +dallas +baby93 +dade305 +volvo850 +josh01 +neopets11 +softball17 +110387 +000555 +redskin1 +hotmail.co +zaq12wsxcde3 +rupali +gabi +go4jobs +number24 +devon123 +singh123 +landry +madison8 +210689 +popcorn! +van123 +chaser1 +bitch17 +171288 +220586 +yaya +giggle1 +gallery +zxcvbnm12345 +230786 +oscar13 +negative +gsxr1100 +w1973a +welcome +dfcbkmtdf +monbebe +101282 +hannah8 +moore1 +kissme3 +fender12 +alex02 +02021986 +w1969a +cheddar1 +poop09 +charcoal +mymyspace1 +tookie +201020 +655321 +candy14 +220890 +nikolaev +bacon123 +farcry +kukuruza +love222 +daddy4 +lambretta +rodent +mexican123 +vika123 +teacher2 +ginger10 +lbc562 +junior15 +87654321a +rabbit123 +run4fun +111989 +cheshire +110585 +jacinta +110007 +brookie1 +александр +sheriff1 +lakeview +magalie +lmfao1 +silver01 +micro +apples! +spiderman8 +ma123456 +fishon +summer. +sexyboy123 +anatomy +infoinfo +el +elijah2 +10021987 +fr33d0m +cazzimiei +master99 +baby26 +3e2w1q +ilovemom2 +date +0303 +dede123 +sharp1 +linda2 +tweety21 +sacha +shadow1234 +mifamilia +stripper +molly5 +bcp201109a +120691 +cullen1 +justin05 +purple88 +whitehouse +251186 +mario13 +baller7 +12031993 +gato +angel2009 +001453 +020292 +maryjane420 +110292 +alyssa11 +cutiepie10 +joshua! +gar +1312 +baby04 +boomer2 +lilkim +141289 +2crazy +moonie +220289 +beavers +iamsexy +promotion +091088 +shortcake +landrover1 +funmilayo +sept11 +anthony24 +builder1 +12121984 +cherub +option +emyeuanh +ambassador +fernando12 +lamour +yogurt +carnell1 +sakthi +dana123 +rawr12 +hunter00 +sdf7asdf6asdg8df1 +iloveme4 +134567 +190989 +nick15 +forever23 +fenomeno +genova +asshole22 +12345678912 +gryphon +champions1 +qazxsw111 +040484 +confirm1 +harald +sanfran1 +120684 +unreal1 +pi314159 +jesus100 +fordfiesta +chapstick1 +batman08 +131187 +tanker1 +seeyou +silver22 +wrigley1 +hoffman1 +orange6 +221086 +destiny8 +pauleta +magic2 +yz250f +mike17 +joyful1 +sulaimon +pussy4 +terrible +speedy123 +honey7 +siobhan1 +abcabc1 +baby33 +thomas99 +sexyma1 +disney12 +131288 +yamyam +johannes1 +150489 +151286 +cheech1 +lansing1 +girlie1 +ruthless +drache +lilangel +ruthie1 +198080 +magicman1 +jennifer5 +10111986 +january20 +lamisma +200585 +caldwell +googoo1 +boobs69 +gambit1 +101079 +oleole +adams1 +fuckyou101 +holly12 +200489 +candy4 +whales +archer1 +hannah03 +redneck69 +121002 +hearts2 +lorenza +goldman +tomas123 +172839456 +wweraw1 +150989 +070788 +prince +001982 +000013 +789520 +120292 +bunny7 +producer +zmxncbv +princess02 +a1l2e3x4 +kevin5 +milagro +franks +william10 +sparky01 + +100387 +neil +lostsoul +northstar +photoshop +flaca1 +rosalba +evertonfc +kevin10 +marsha1 +oaktree +marijuana4 +ollie123 +1942 +mylover1 +120891 +14101987 +2312 +normandy +bambam12 +socrates1 +mercedes +asdfgh1234 +krasnodar +single08 +passion2 +210389 +poppin1 +mascara +heroes1 +brandie1 +maricela +kill12 +iloveadam1 +miller123 +satana666 +brittany13 +lover45 +password56 +123456456 +england66 +defjam +star24 +community1 +fri +21061989 +cutie16 +shining +221221 +dork +15021990 +sammyboy +black01 +ben100 +daboss1 +evildead +fktrcfylhjdyf +villevalo1 +coo +shabnam +alex2005 +safira +99xfxlo19ui +massive1 +money25 +15101987 +samurai7 +jesus25 +cosimo +system123 +catherine +dollface1 +pretty11 +mot2passe +william! +a777777 +munster +wasted1 +ffffff1 +muruga +nik123 +111089 +c0cac0la +arrow1 +dallas08 +dead666 +brujita +dancer01 +inspiration +201189 +stopit +sydney123 +mik +110488 +hermine +middle1 +qwerty007 +scratch1 +poohead +10101992 +kevin23 +burning +nanou +orchidee +dreambig +delfines +1teacher +gianfranco +cccccc1 +eddie12 +jandikkz +delfin1 +nhfrnjh +saudade +500032 +passw0rd1 +matvey +666666q +playmate1 +deniro +261 +22223333 +sativa +mamako +select1 +151090 +qwe123 +mike1 +sexmachine +220390 +wombat1 +250789 +bubba11 +gretzky99 +xoxo123 +1944 +tomasek +yorkie1 +200688 +alejandra2 +javier12 +yusuf +kungfu1 +241189 +1rainbow +rj +lollol12 +sienna1 +invest +brookie +12021990 +shaq32 +311287 +sparky +hummel +02021989 +dfaeff34232 +jagger1 +pokemon99 +waterski +rockandrol +donthate1 +hockey88 +120892 +sergeant +shiner +austin! +1234a +wakawaka +rocky01 +thunder +papatya +poklop +yandel1 +inspire +199200 +location +softball20 +skunk1 +kitkat123 +amadou +angel93 +garland +123q321 +strelec +141088 +bellabella +99problems +ballin! +killer8 +seether1 +121189 +1austin +q963258741q +january5 +wheeler1 +poobear +300487 +jenni1 +bella5 +little123 +isa123 +melati +powerade +gateway123 +cali4nia +cows +christian5 +fiore +1337 +shyanne1 +menace1 +tomboy07 +123654123 +6lfxlo629ui +201187 +lalito +josejose +heather69 +gerry +150589 +veterinaria +protoss +royalty1 +cherrypie1 +pass01 +dogsrule +toffee1 +rockstar5 +class2009 +photography +davids1 +morelia1 +kerrie +rockstar69 +bubu +moulin +210590 +davey1 +news +314314 +kobe123 +dominguez +1carlos +hooligans +ty2t1hv3oc +madelyn1 +hollister! +ira123 +operation1 +santa123 +lol111 +25121987 +robert4 +jarvis1 +1234567890qwerty +121279 +crazyhorse +free2bme +megatron1 +240588 +jasmine14 +nikita +bananas2 +princess93 +maryse +julissa +usmc0311 +ilovedick1 +22051987 +121083 +richard7 +skater4 +251189 +251085 +fuckall +211088 +savana +sempre +11335577 +kleenex +notvalid +camelot1 +jarred +aeiou123 +fucku13 +111185 +230189 +chainsaw1 +grand1 +logan5 +01020102 +hallodu +lauren22 +chivas09 +sossos +sleeper +kacper1 +spongebob6 +dumbbitch1 +cayden +loser23 +200587 +austin07 +hunter8 +19877891 +purplerain +stardoll +purple +261186 +l1nk3d1n +120784 +mymom1 +freedom10 +cortina +football40 +lukasz1 +230190 +lucy11 +treysongz +vic +partytime +198621 +skiffy +10101983 +20101986 +w1974a +monkey666 +nikko +ooooooo +t1nkerbell +jaishiv +20081991 +psyche +honda400 +splinter1 +olufemi +marina12 +tracie +tyler6 +revolucion +mateo1 +jasmine08 +robert15 +purple33 +alex2006 +vfiekz +140287 +nicholas3 +hammer12 +nick23 +eagles22 +198422 +nikanika +gentleman +anointed1 +escuela +jakey1 +hester +pony +bebito +sara2000 +systems +ritchie +0123456a +laurentiu +444777 +2dumb2live +sevenof9 +cambridge1 +lafayette +armadillo +muzyka +joshua02 +summer14 +a1234567 +myspace100 +parol123 +jamesb +7777777s +155155 +muskaan +pololo +110008 +laurine +candy6 +1229 + +cool99 +carwash +sexytime1 +dunlop +boobies69 +warehouse +08 +wimbledon +music10 +west13 +987410 +221085 +12051987 +seaweed +cutie22 +blue19 +261188 +wazzup1 +07070707 +zxcvbnm,. +bigboy11 +400705 +booger12 +donna123 +fuckyou18 +misfit1 +13231323 +bookworm1 +19111991 +1pitbull +katie13 +594love168 +zaqxsw123 +357mag +sk8er1 +jason7 +bosslady1 +iddqdidkfa +shadow09 +cocacola2 +251200 +14021990 +motor1 +gjkbyjxrf +toluca +matt01 +antonietta +1stlady +321qaz +tyler22 +sherwood1 +train1 +tmm +laura2 +holmes1 +forever11 +efnesonline +patrick! +sporting1 +soccer94 +141087 +adrian13 +larsson +357magnum +#1princess +1379 +linkedin +vlad1996 +guido +yankees11 +westside5 +dallas09 +grover1 +chaitanya +mikele +902100 +sexpistols +entu6ea64h +ferrarif50 +ammaappa +arman +buckwheat1 +100988 +vertigo1 +lynne +terezka +nini +samsung7 +killer77 +cody13 +angle +images +130788 +789963 +paddington +200988 +bigdog12 +bigshow +dolcevita +dirk41 +angel2010 +1q2w3e4r +schnuffel +uifkjhf522 +maggie4 +1027 +kasey +111990 +producer1 +america9 +ya +money88 +seniors08 +slipknot! +baby90 +140987 +sweetness2 +farrah +wsxqaz +benji123 +glamour1 +trabzon +400068 +220986 +caden1 +rbd123 +styles +150390 +celia +240890 +mansur +cutter1 +pimp16 +sammy10 +hunny +alicia12 +yuriy +qwerzxcv +crazy4 +sanlorenzo +apple01 +kendal +froggy2 +230890 +ilovetom +123456789012 +0707 +anastasija +rajani +steven7 +110285 +babylove12 +youloveme +201086 +201087 +julianna1 +ilovepie +replay +121991 +michelle20 +kitty9 +brasilia +lampshade1 +101987 +zidane1 +whitewolf +thekiller +492529 +22121986 +baddest1 +fuckthis2 +lego123 +chirag +brown12 +starfox +illinois1 +forum +justin9 +giants10 +brunette +anetka +cheesy1 +123sex +taylor9 +sk84ever +guizmo +1402 +432156 +winona +scooter7 +telefoon +bigbutt +memento +070789 +friends10 +dj +batman6 +gasman +diver1 +changeit +++ +oladimeji +oluwaseyi +gutierrez1 +finger11 +200488 +bigbuck +ih8you +120384 +honda600 +school3 +mahal1 +love67 +pampers +shabana +eighteen18 +mystical +xavier123 +2510 +molly13 +d21lwz1zjs +maksim2425 +worldwide +guyver +lakeside1 +030383 +69chevy +parissg +110988 +spike12 +jewelry +240486 +ahmad1 +paraguay +kinky +w1971a +bhaskar +mommy08 +crossroads +haterz1 +dude101 +sierra123 +alexis07 +lover09 +pasion +10071987 +titus +101986 +ready1 +fifa10 +iloveu23 +maman1 +211086 +moto +change123 +queenb +811009 +costello +baby00 +w1972a +mama23 +ryan23 +110027 +fuck21 +downhill +gfdkbr +prophet1 +james9 +a555555 +paperclip1 +201184 +100288 +gj +amber01 +thunder5 +w1ll1am +gerbil +aeroplane +sanctuary +151189 +shriganesh +goarmy1 +hyper1 +florian +bolivar +122222 +media1 +pokemon! +twiggy1 +22021989 +44448888 +chaparra +2202 +michelle9 +pineapple2 +snoopy3 +1478523690 +143jesus +15031988 +salvatore1 +020289 +tasmania +nokia2700 +woodrow +12041988 +llamas1 +douche +16121987 +080890 +141188 +football89 +sweetdreams +teodor +moomoo12 +jujuba +270488 +boneca +14101991 +karel +lilgirl1 +mariners1 +player01 +biotech +fgfgfg +nacho +nolan +gretzky +222777 +winston2 +loshara +shailesh +scooter +nathan7 +12021985 +sasuke13 +zacatecas +130990 +qazwsx123456 +cameron4 +bryanna +mahalko1 +rainbow +2fast4you +gorda1 +jennyfer +tucker01 +bubbie +sooty1 +chicken6 +editor +faith01 +serious1 +laluna +198666 +finance1 +fussball1 +january9 +pla +tigers01 +zachery1 +ilovey0u +kirikou +jordan1234 +brain +12031203 +21031988 +990099 +110689 +rangers123 +princess28 +pickup +head +godslove1 +brandy01 +steeler +goodlord +farscape +raven12 +20052006 +matchbox +jonathan7 +hannah21 +250987 +198520 +sagittarius +springer1 +cowboy123 +tampabay +stud +ttd955audg +161288 +thinkpad +theforce +rampage1 +babydaddy1 +bryan12 +develop +dumdum1 +281 +5201314520 +230590 +sunshine14 +jasmine09 +jupiter2 +240688 +johnny13 +jeannine +ghfdlf +linked2011 +140689 +shawnee +001978 +12101988 +joseph21 +chris88 +121982 +headhunter +lovepink +220486 +2511 +smurfs +lozano +rhjirf +ariadne +lfybkrf +dash920 +fairytail +marky +unicornio +lambofgod +84569280 +fucklove2 +austin14 +lalalala1 +snowdrop +yygjmy1984 +twoboys +tig +560038 +ger +pastel +260690 +240485 +iloveme7 +tbilisi +151287 +kylee1 +poderoso +cupcake11 +cutie! +blondi +sunshine77 +scooby13 +elnene1 +netscape +cc123456 +121980 +sports12 +john316 +greenday3 +pelon1 +1110 +25101987 +1331 +raccoon +231084 +justin1234 +060688 +marybeth +kishan +tylers +851216 +12101987 +purple07 +100189 +heritage1 +thunder3 +boots123 +climbing +andrey1983 +reece +navidad +1957chevy +13121987 +golden12 +220789 +smiley2 +rachel13 +250689 +dragon. +adamek +251289 +bugsy1 +110188 +paxton +tianna1 +14041987 +4angels +brahim +gavin123 +140292 +elizabeth1 +chicken22 +awdawd +what12 +10111990 +150389 +wutang36 +juicy123 +mymail +paramedic1 +nbvjirf +skate101 +beth123 +120883 +200789 +400078 +football78 +patrick13 +north +ravinder +131086 +doberman1 +kristie1 +triple6 +mp3player +wert12 +angels +carino +100787 +angel637 +fraggle +asdfgh7 +thomas08 +dude13 +flipmode +deeppurple +1708 +colegio +bojangles1 +sector9 +biteme123 +baseball +tarkan +sony12 +tobi +danny7 +123qweasd +nigga! +ajcuivd289 +120285 +misty2 +sampoerna +251086 +superstar3 +antigua +mallika +210187 +bibles +booboo01 +joseph5 +levi +usausa +football35 +hennessy +100386 +aa1234561 +airwolf +nautica1 +tekken5 +lauren7 +dragon64 +sassycat +ilovemark +4204life +smokey3 +gerhard +shadow. +gwada971 +barbar +brand0n +hickory +ballin5 +amigos1 +121992 +helmet +kingofkings +chacal +mercer +tmobile1 +mayumi +james06 +sexy89 +julia12 +silver13 +131290 +tigerlily1 +reverse +lovers4 +ashley88 +1q2w3e4r5t +jedi +050690 +iloveyou4e +009900 +121278 +kimber1 +240590 +12361236 +andy11 +alex03 +2w2w2w +gregoire +cerfcerf +ikenna +arlington +2kool4u +gizmo12 +bhbyf +section8 +titus1 +green101 +ttttttt +glorious +alexis22 +20071987 +ulrich +redfred1 +libelula +141186 +mustang11 +samsung01 +gumball +jesusc1 +1313131313 +serafim +10121987 +1alexis +lamborgini +patrick01 +felicity1 +jxsgx2yd87 +smilla +achilles1 +fiatpunto +bananas! +130680 +policy1 +gohan +ilovebrian +drunk1 + +ratman +chandra1 +230486 +654852 +perla +imcute +joebob +bootie +pflybwf +15121986 +aggies1 +101183 +santorini +firebolt +22121989 +warthog +gunjan +charlie69 +nathan06 +ultra +150588 +sweety2 +bone +vanessa +kikiriki +boomer +130389 +vale +angel0 +crazy14 +w00tw00t +unhappy +prince11 +taylor06 +5t6y7u8i +mexicana1 +facile +lovely6 +oyster +shadow101 +sai +summer03 +king24 +mayang +waswas1 +q123q123 +joshua16 +210486 +781227 +prince +z: +redsox2004 +pimpin5 +hottie08 +toxic +13031991 +04041988 +sarah7 +024680 +140988 +rabbit12 +120282 +cutie08 +takamine +fleming +babyboy08 +ilovekyle +doritos +251290 +12061990 +pinkey +dude22 +checker +qeqeqe +vfpfafrf +meganfox +heart2 +230586 +socom2 +maggie5 +hotness1 +coco10 +fghfgh +1100 +wowwow1 +kamlesh +obama1 +john15 +dallas23 +amigo1 +091 +nike11 +redsox33 +furious +brittany10 +bridge1 +sammy6 +karla123 +159357852 +popular1 +19521952 +vicki1 +donuts1 +wiccan1 +present +melbourne1 +ralphie1 +2255 +p@$$w0rd +181088 +cody1234 +121080 +zxcvbnm2 +111287 +vinny +destiny08 +300688 +mygirls1 +thesims3 +rocketmail +ilikeit +green1234 +hoochie +ulysses +198719 +110685 +241190 +chicago +qwerqwer1 +honey22 +elizabeth. +england123 +qg9543bh7 +totti +jinjin +hugo123 +999666333 +zack12 +marwan +sk8er4life +williams +austin06 +privat +654321m +merlin01 +staind +mellow1 +246824 +260488 +alexis14 +brutal +anarchy99 +modem +jorden +alex04 +havefaith +sydney +wayne2 +guitar! +down4life +3003 +newbaby +231285 +cet333333 +david09 +fishin +shredder +14121987 +150888 +links123 +specialk1 +10121988 +deeznuts1 +120884 +12345aaa +1dontknow +alanna1 +lolwut +barbie13 +199119 +jeanluc +iamtheman +luke12 +dog101 +rayane +barbie11 +happyboy +sissi +non +210191 +hamham +angel98 +horse2 +tratata +autocad +bisounours +dantes +mowgli +alex1991 +blessings1 +leslie123 +14041988 +des +100685 +exercise +19761968serg +03 +king101 +pfchfytw +lovelove2 +vick07 +pakito +benidorm +1117 +sol123 +allison2 +marilu +560047 +daisies +danielle13 +400054 +aaabbbccc +1912 +zaq!2wsx +ajtdmw +bigapple +dj123456 +fujitvpass +yellow6 +binbin +sandwich1 +150788 +thankgod1 +120289 +pdq4rv +raiders3 +sandal +vip123 +250584 +101191 +3amigos +airjordan +emily7 +mcnabb5 +100286 +owens81 +kazuya +211188 +g1234567 +vfhrbpf +optiplex +aerobics +crusader1 +bigcock1 +a13579 +1tinkerbel +regional +cupcake! +olaitan +rules +dicembre +pussys1 +terri1 +210386 +bucks1 +jayvee +221177 +cagliari +zooyork +jirka +admin2010 +denzel1 +villegas +chrisbln +mommys +angel96 +antonello +amarillo1 +horses! +220686 +scott12 +jordan69 +kittycat2 +nicole99 +fuck.you +redbird1 +christ +lucy01 +studmuffin +carroll1 +govols1 +elamor +destination +cocolino +cashmere +artista +abfkrf +14071987 +palomita +mari12 +blue92 +12345678g +qaywsxedc +yuyuyu +23041987 +blah11 +560016 +tyler23 +brooke11 +02061986 +246890 +zackary1 +110110jp +02021984 +dolphin13 +mary1234 +hawkins1 +lucile +hottie#1 +beatle +taylor16 +210989 +kernel +signal +kookoo +151086 +198555 +mullen +rose22 +emilia1 +murphy12 +teenager +motor +dreamer13 +qwertyuiop +skate4 +123123w +casper +almeria +koala1 +140285 +elmo13 +cordelia +liebling +erickson +hunters +iloveweed +polpol11 +121082 +22121987 +michell +harini +abidjan +americana +ceaser +pitcher +lily12 +sandra2 +glasgow1 +cokolada +midnight3 +conejita +kilimanjaro +_ +tiffany7 +harley22 +dumbass2 +tiger14 +101077 +honey5 +choupinette +rowing +130888 +pretty +1009 +anonymous1 +11111111111111111111 +cocaina +wolfwolf +carlos +josette +nymets1 +tweety22 +1941 +hawk1020 +12345asdf +assfuck1 +horse12 +14021992 +ginette +131289 +25121986 +speakes +kaushik +federico1 +hamsters +231185 +523523 +jedimaster +pelangi +201190 +skibum +diamond9 +bandido +22041987 +rocking +doritos1 +hollister4 +270790 +130587 +buddydog1 +samantha8 +tweety16 +buford +8989 +rebecca12 +fatass123 +babydoll2 +raiders14 +darlin +tagged +ferrari123 +bubble12 +140286 +zezette +johnmark +tank123 +iloveme13 +shazia +251287 +trevon1 +01011976 +jessica07 +racheal +11121985 +ab123456 +110684 +password96 +p3avbwjw +brandon17 +jonathan +donny1 +slacker1 +victoria7 +48624862 +chad123 +myspacesuc +clockwork +westwest +syracuse1 +1nternet +jackie +housemusic +austin23 +connor2 +celebrity +demola +serge +alex1997 +music09 +ghjghj +lost4815162342 +eight +jackie11 +vjhjpjdf +kosovo +11021987 +fifi +fastcars +rrrrrr1 +120984 +13121312 +220990 +imtheman +141287 +andrea10 +summerlove +willie2 +1112131415 +bettis36 +261184 +kenny2 +120393 +250888 +haider +makelove +280688 +shadow24 +beer30 +110385 +271088 +andrew24 +trish +player7 +forbidden +lokita1 +01031980 +jasmine! +12121983 +02061987 +carmelita +satelite +loverboy2 +++++ +james101 +19071988 +ndacebx2wx +lifetime1 +monkey89 +120782 +111090 +chingon +lost123 +baylor +think1 +bigtime1 +skaterboy +bluenose +midnight +400005 +cj1234 +100990 +1410 +1234554321q +25051990 +cute13 +101185 +developer +bachelor +260188 +iceman12 +samantha10 +dredre +kucing1 +homeless +250989 +manutd99 +piston +123a456b +monet +090987 +pink25 +latrice +aeropostal +poptarts +trading +tink11 +turion64 +susan123 +marley123 +dollars1 +bubbles22 +dildo +headache +220485 +tookie1 +fifa07 +godisgood +sfring31 +auto +coffee2 +madison05 +naveed +110190 +wholefoo +dragon17 +starfire1 +santacruz1 +tigerlilly +shadow18 +030405 +basketball +sensizim +geegee +jasmin123 +07 +mammoth +arsenal2 +1qazxcvbnm +pen +qwsxza +mickey21 +210685 +20061986 +michael20 +verito +chaos666 +player5 +261288 +14021987 +maries +12101986 +spades +green88 +alibaba1 +iloveyou27 +popo12 +mina +charles12 +wannabe +chewbacca1 +dr +17ciao72 +1elephant +oskar1 +14921492 +hondacrx +lottery +maria7 +101078 +kane123 +karol1 +4seasons +goofy123 +pretty13 +258654 +lyndon +comfort1 +12101990 +hamish1 +napalm +linkedin.com +karizma +green01 +na +130687 +justin19 +cristovive +100788 +nettie +666111 +coincoin +emily5 +star77 +espanol +honey11 +i234i234i234 +veteran +binky +10121991 +020890 +3blindmice +govind +dragon66 +winfield +230686 +230788 +famous123 +king09 +danielle! +peace101 +labrador1 +1130 +colby +gothic666 +101292 +jonah1 +130189 +madcat +chitown +mandarinka +trout +tijger +maria22 +edith1 +color1 +joseph08 +shimano +guccimane +20021986 +1lakers +clueless1 +kalimera +commandos +nieves +karthika +conan1 +mario66 +seraphim +101098 +babygurl11 +current +escaflowne +freddy12 +bigboy23 +jackson10 +201089 +saibaba1 +mouse2 +110583 +joshua8 +damola +yourface1 +burbuja +elephant12 +juan316 +110584 +family +sweetie12 +251185 +danger123 +120291 +vsijyjr +0404 +shit11 +kamikaze1 +bigtruck +110691 +ileana +katka +bongo1 +215487 +sammi +buster21 +oscar22 +2kitties +12321232 +azerbaycan +myspace007 +200990 +geology +tony22 +10031987 +ryan21 +10121986 +deepfrequency +161188 +13051986 +kelli1 +121006 +daniel05 +chobits1 +guitarra1 +freeatlast +samsung11 +loveme10 +ciaoo +halo33 +nanny +nana13 +121182 +sexything1 +mu +fuckitall +140488 +loser69 +horses11 +ilovemydog +271288 +arsenal +120681 +yellowstone +andre3000 +michelle15 +250890 +ganpati +lovem3 +macedonia +delldell1 +me4ever +daniel25 +crazy! +invalid +bella1234 +andrew05 +winner123 +izzy +qawsed12 +zaqqaz +.ktxrf +khushboo +310000 +d12345678 +171285 +maria3 +201005 +puppy101 +martial +sk8sk8 +exclusive +020689 +please12 +qaz123qaz +naenae +perla1 +cena12 +jesusrocks +12081988 +stlouis +mortalkombat +ranetka +100101 +brandie +25121989 +novikov +20051986 +dominican +sexgod +12332112 +jonny123 +annmarie1 +mathias1 +doorknob +june08 +spiderman6 +banan +02041987 +230289 +love85 +220386 +radhaswami +locker +smile7 +warrior2 +strength1 +rap123 +ellabella +shorty16 +superman09 +star88 ++++: +onions +arsenal7 +jasmin12 +yoyoyo123 +futura +124 +brandon18 +musician1 +mike09 +twilight4 +ferrari360 +shay12 +echo +yourmama1 +woofwoof1 +mami +3kings +211289 +holyghost +horacio +naked1 +complex +stella +danielle11 +myspace19 +bud123 +chicken13 +ghbdtn +bruna +treetop +iskandar +america +kev123 +espinoza +sesso +yoohoo +live4ever +morning1 +shinji +12011987 +laxman +daddy10 +kaiden +great123 +isabella12 +chepalle +piscis +13121988 +clock1 +oscar01 +0cdh0v99ue +greyhound1 +serg +cassie11 +100785 +smalls +seamus1 +mounir +milosc +456789a +140690 +jazzman1 +peacelove1 +mary13 +samael +iloveangel +paint +shorty4 +pingping +19091990 +pinklady1 +fly123 +151088 +final +football36 +bella7 +171189 +number15 +211290 +110484 +12031987 +ranger123 +renee12 +buttsex1 +shyanne +constant +170589 +cf +123asd123asd +alyssa13 +dave12 +maximum1 +pompey1 +diamond01 +australia +salmo23 +211186 +241187 +parveen +jagoda +jackson4 +alexa123 +bladerunner +1cherry +vivere +u6e6r9hwix +20021987 +cheer10 +snoopy22 +deputy +waleed +albania1 +wind +vfy.yz +smokey7 +kiwi123 +hereford +redfred +fuckbitche +pippopippo +andrew09 +tiberius +560085 +family06 +sathish +stargirl1 +keyblade1 +21121987 +ganjaman +ashley101 +korea +katlyn +flower +tyler08 +sanfrancisco +cupcake13 +mediawire +callisto +123jesus +reeves +yfcnz123 +panties1 +bianca123 +rhubarb +raiders18 +newports1 +cookie +qqqqqqqqq +iloveme. +a333444 +140788 +210185 +lizzard +pink77 +meriem +13121984 +230690 +l0veme +cyber123 +12121982 +hospital1 +1tunde +motion +browndog +speedy12 +life12 +345 +130985 +ijeoma +shizzle1 +magellan +buster! +n1gger +manuel13 +230889 +gulnara +porto +matt69 +baby99 +sarah3 +hsm123 +271 +11121986 +emoemo +luna12 +gumby1 +92702689 +12081987 +purple +grandam +111182 +tropicana +1killa +ihatelove +boat +basement +undefined +01011993 +shadow08 +poker21 +flowergirl +steelers2 +120983 +summit1 +dave1234 +jose01 +mymother1 +любимая +testqa1 +aviator +por +peaches7 +w1968a +koleso +dimon +karissa1 +blade55 +summer11 +любимый +licker +green! +sailboat1 +fast +nick101 +1dallas +bennie1 +alana +911111 +selena123 +jabroni +rubens +rfkbyf +foxhound +vfrfrf +ilovedaddy +money77 +mustang89 +131285 +d85lwz0zjs +morelia +momdad12 +lady01 +amanda4 +230288 +rrrrr +playing +carmine1 +twilight09 +181188 +02021990 +ttt +prowler +shree420 +lianne +funfunfun +angel29 +au +301188 +murphy01 +zachary12 +butt123 +mariah12 +1scooter +mas123 +vivienne +rolex +211286 +natedogg +trinity +261286 +hoops +splendor +carlie +789456123q +coffee12 +ren +ladybird1 +freakshow +23101987 +block +jobseeker +15101986 +jamison +12031991 +100485 +20021985 +sanya +bigbob +jordan04 +600040 +008008 +lover16 +shortcake1 +roc +141086 +varanasi +147789 +23021989 +violeta1 +240388 +fuckyou17 +blessed3 +fiat500 +urlaub +amiret2015 +sonora +striper +110683 +princess77 +210788 +kenneth123 +spooner +225225 +mingus +sasuke2 +10011989 +alphabeta +twilight7 +joe1234 +pasadena1 +rhythm +hillcrest +shirin +ckjybr +fifteen +durham +thinking1 +united99 +mouche +131188 +trustgod +badgers1 +archangel1 +jacqui +bluedevils +bogey1 +qwerty87 +fuckyou00 +angelus1 +saywhat +videos +brandon +504boy +281281 +101181 +broken2 +sac916 +240988 +230787 +11922960 +190788 +charlie23 +september +maracaibo +rachele +dopey1 +mustang06 +juanma +lucknow +josemaria +260388 +joshua6 +opennow +klingon +narnia1 +120692 +220786 +starwars11 +daisymae1 +0147 +computer01 +1newyork +150987 +spliff +bitch4life +bullsh1t +beauty123 +reddevils +14021989 +jakester +newera +7e9lnk3fco +chelsea5 +william23 +greatman +junior +101095 +elite +ballin07 +dildo1 +mariaa +240489 +03031988 +avangard +pongo1 +rosamaria +19031987 +ilovejess1 +profesional +z123456z +daisy7 +hewitt ++ +226001 +shawn12 +246801 +acoustic1 +pushok +100287 +franko +lin123 +krusty +walnut1 +america3 +barclay +sheba123 +lssy123 +pookie3 +beauty2 +bigbucks +priora +matmat +210787 +honeykoh +13031990 +spectrum1 +hot101 +chicken8 +vsjasnel12 +punk77 +yfcnzyfcnz +232629 +bully1 +antonov +clint +12151215 +jasmine23 +111110 +191288 +gendut +ja +700007 +141285 +paola123 +gabriel3 +dealer +tucker +wishes +888555 +camprock +050590 +poohead1 +garima +america +mmm111 +carolina2 +kisska +pink99 +1stunner +02031987 +105105 +bigboy13 +glock17 +46709394 +planner +110191 +natedog +fruits +maria14 +lake +311288 +monteiro +goodjob +mum +151190 +198325 +197200 +clown +azerty1234 +skulls1 +christian8 +mercedes2 +hot2trot +barnaby +green55 +crown1 +fla +bigguy1 +271190 +250688 +gio123 +monkies +warhammer40k +steveo +170288 +0911 +sohail +10051987 +daddy6 +10041991 +freedom01 +klootzak +indochine +dimension1 +kyle11 +alesana1 +mutiara +chauncey +model +hentai1 +kids1234 +antonio3 +150188 +250790 +alex2007 +joaquim +byron +131190 +berlingo +beamer1 +kaleigh +spiral +mahogany +101182 +22051991 +10111987 +highlife1 +ganeshji +rockin1 +toblerone +jahjah +soccer95 +candy! +justin88 +211190 +221282 +camero +171188 +passed +julien1 +111284 +masha123 +marvin123 +100887 +1ck75iflga +nayeli +bellevue +baseball00 +joshua04 +200689 +cowboys5 +swingers +yogibear1 +something2 +options +tony23 +241090 +janna +willow12 +badboy13 +171171 +12101989 +garret +andr3w +shawn2 +moremoney1 +joan123 +charmaine1 +100100100 +jakers +morgen +230488 +original21 +kelsey123 +qpqpqpqp +destiny9 +sinbad1 +ilya +moon12 +death101 +rotten1 +271189 +10101982 +20121988 +fuckyou15 +kostas +deaths +luciano1 +stratford +130488 +shayna1 +letsplay +blackcat13 +johnwayne +drake123 +roy123 +120185 +poi +baller32 +elmer +lucylu +290688 +221284 +shadow07 +chowder1 +10251025 +aq1sw2 +zildjian1 +grapefruit +trailer +pravin +fuckit123 +mini123 +18021988 +wiktor +yfcn.irf +jennifer! +teamobebe +checco +policy +legends +5201314a +twilight11 +fontaine +iam +train +pelikan +babymama +volvov70 +050290 +hackers1 +rewq4321 +gizzmo1 +luckycharm +let +retarded +tanechka +jimmys +12031992 +moustache +kolade +dogpound +753951456 +4getmenot +monica13 +ilovejake +aceracer +framboise +crazyfrog +130684 +yzerman +steph12 +10051991 +apples3 +angel111 +sunbeam +douchebag +killall +epiphone1 +anal +gitrdone1 +horsey +120591 +football65 +10051988 +phoenix602 +trustme1 +carmella +monet1 +green99 +twinkles +melancia +southpaw +ilovejb +2104 +210889 +goo +bigdawg +auction +horney1 +starshine +160486 +150889 +music23 +geography +purple101 +100185 +bru +lilly12 +june07 +28091992 +tony01 +bushra +jumoke +babyg1rl +240589 +03031987 +01470258 +bolton1 +loreal +220989 +marlena +taetae1 +yyxthh8j9k +wicket +crazy6 +peralta +010182 +sridevi +corncake21 +gossip1 +star99 +paradigm +bigpapa1 +noaccess +bridgette +221184 +kingofking +vfrcbvec +mensuck +hao123 +1patrick +20031990 +151289 +southeast1 +danny11 +glock40 +massacre +fucklov3 +enfant +190588 +imcool2 +111086 +nomar5 +concordia +arsenal01 +lbhtrnjh +coldbeer +m1m2m3m4 +201188 +good12345 +fil +figueroa +movingon +1pretty +021090 +flanker +drama +superior1 +130489 +little2 +nba123 +quimica +fuckoff13 +infernal +eric11 +softail +becca123 +gohan1 +120184 +221100 +220787 +rachida +gfhjkm12 +wenwen +yahoo11 +gorila +quest +heather11 +makaveli7 +peter2 +katie01 +keeley +23121988 +soccergirl +aaaaa6 +240990 +5thward +180889 +140787 +p@55w0rd +cookie6 +loveme14 +vlad1995 +samoht +passwordd +02081988 +master666 +150586 +cinders +smoke123 +198112 +saw123 +jodete +pasword123 +smile5 +lietuva +venere +abudhabi +inessa +fire911 +virago +2013 +fred11 +pinkpink1 +oneway +makenna1 +1father +14101985 +240689 +natali +molotok +21121989 +bertie1 +sammie123 +rayray2 +berries +272829 +holla123 +smile11 +kuba +malang +100587 +brandon69 +celestine +basile +chloe01 +garnett21 +poopies +250787 +superbowl +yecgaa +12071990 +nonstop +max2000 +d2itsr81jo +puppy7 +fifty50 +maggie08 +tunisia +mustang68 +skiing1 +skate5 +chasity +shrimp1 +james19 +bear13 +kira123 +michael99 +sistemas +mandie +dorado +700700 +rockies +210790 +fxzz75$yer +sinner1 +69chevelle +pantera666 +cutie07 +bogoss +hahahahaha +alhambra +mental1 +baby2006 +10121989 +147852369a +taratara +121184 +aa1111 +1qazaq1 +assunta +02071987 +211189 +mike88 +zoosk123 +ramrod +holger +lover9 +lokesh +124816 +tigers7 +lilly2 +220584 +tamanna +220685 +sxuaiehatp +azucena +choose +ghbdtnbrb +daywalker +zoey123 +tigger99 +famiglia +pimpster1 +princess33 +cutie6 +sonny123 +111190 +160288 +123456789aaa +arigato +thinkpink +marimari +sexy28 +steven3 +mizzou +15121987 +hitomi +toluca1 +jannah +hidden1 +110485 +cookie9 +870621345 +love247 +mahmood +303303 +afrique +261185 +irock2 +suckit123 +flower6 +buttmunch1 +britta +951236 +joan +joker23 +daycare +05 +1234512 +21051987 +mylove01 +tigers13 +01041988 +fling123 +cioccolato +koolkat +gordo123 +banana7 +19101990 +tbone +brooke01 +punky +yomama12 +198777 +12331233 +01021985 +josefine +gators15 +pierce34 +bradshaw +prout +toilatoi +125 +1person +240986 +24091991 +17121987 +photos1 +bulls +ghana123 +320320 +dreamteam +fetish +chien +johnson48 +hockey24 +kayla01 +derecho +tiger101 +2310 +tiffany3 +bigboy7 +carter12 +mustang95 +qwertyasdf +filipek +sashok +chichi123 +alicja +flanders +121979 +35353535 +pretty5 +bergen +brown2 +kosova1 +130790 +040488 +10071991 +development +juliane +136136 +miamiheat3 +2boobs +planb1 +shantel +newbaby1 +farzana +smokey69 +19051987 +qwerty24 +killa5 +cowboys08 +sinister1 +gfhreh +kevin14 +aaa222 +joshua03 +jordan20 +fairytale +abcxyz123 +abegail +robinhood1 +herrera1 +120893 +letter1 +dontcare +171286 +houdini1 +natusik +111978 +310191 +vova123 +syzygy +laila1 +george22 +wizards +3216732167 +wxcvbn123 +160389 +20041987 +mani +lister +ipod +tanner2 +120581 +dylan01 +killer15 +smile22 +wendys +valdemar +racer +150986 +gansta +mama2010 +game12 +20101989 +davinci1 +suzie +gamble +110044 +kissmoko +220886 +manalo +tigers +111285 +ryanryan +00000p +karl +whitehorse +011 +22101987 +light123 +moondog +odessa1 +201285 +130289 +121981 +12031986 +03031990 +analsex1 +princess00 +bnmbnm +210390 +nikenike +finalfanta +william9 +fslhggi +fight +www333 +hotmail12 +190988 +brittany3 +kiana1 +261187 +johnny3 +виктория +ranger2 +janicka +1914 +200586 +apple6 +daycare1 +cipolla +hotstuff12 +natalie3 +monica +1q2 +2morrow +240790 +211287 +bailee +mommy! +toystory +sexxy +m123123 +1peaches +ashley1234 +zach12 +thedude1 +01061988 +mexico100 +ykvpoia569 +sexy32 +password86 +monkey20 +111111d +17081945 +1daughter +boomer11 +sweeney +lakers13 +221185 +140588 +171088 +23452345 +godis +guillaume +200686 +juarez +filimon +22121992 +tangerine1 +dollie +danny01 +20031987 +wodemima +nathan07 +sammie12 +123pro +140585 +11051987 +myheart1 +moimoimoi +angel100 +mexico21 +austin4 +bluebell1 +230985 +power3 +124563 +tivogliobene +abdul +xbox123 +250990 +younes +lagarto +aquiles +tomika +number123 +fruit +switch1 +160590 +15041987 +bobobo1 +shrek2 +punk101 +annapurna +money12345 +suckdick +collingwood +chocolat1 +madden06 +fylhtq +claudio1 +13041987 +chrissie +misty12 +ducati999 +reefer420 +130685 +25051987 +alliance1 +jimmy7 +10121985 +220889 +marykay1 +fortress +jamar1 +sunshine07 +pokemon4 +marykate +nevermore1 +romans12 +vfrfhjdf +paradox1 +26842684 +juventus10 +good123654 +cfvjktn +250386 +240789 +23121987 +fabio1 +pavement +mark23 +william22 +pogiako123 +vbhjckfdf +monster23 +010390 +221089 +240586 +theman2 +whatthehell +sweetpea2 +bluegrass1 +suchka +jaroslav +amine +dakota3 +alberta1 +peabody +qwerty12345 +dustin12 +7153 +bratz12 +15051990 +linkedin12 +azzurra +mon123 +redsox2 +peluchin +vincent123 +candelaria +10061986 +198521 +121191 +eminem +560095 +le +rabbit2 +karapuz +escalade1 +visitor +laylay1 +angelochek +reginald1 +zappa1 +johnlennon +23091989 +mexican12 +lelewa123 +chuck123 +fucker3 +505505 +270988 +jeter +michael25 +colts +www123456 +paris2 +jake10 +cowboys3 +manju +cutie9 +tyler07 +frederico +hoops1 +200002 +casio +perkins1 +booboo5 +18081988 +741123 +chris89 +6acaxa54be +flower23 +260988 +patricia +passions1 +181187 +shop ++ +doughnut +loop1206ssdsff +pavithra +frankie12 +sameera +220887 +sadiedog +130890 +charlie99 +anette +mustang9 +221285 +punkie +2m66xf2ajt +1й2ц3у +akanksha +barca1 +bidemi +gertrude1 +100885 +barney01 +liljon +fckgwrhqq2 +motorbike1 +2happy +harley09 +bandit13 +dingle +kailey1 +tanner123 +vincent2 +bounce1 +alialiali +workshop +platano +199111 +coelho +jimbeam1 +norma +bigblock +black14 +1danielle +asshole23 +higher +13031987 +newyorkcity +mimi13 +orochimaru +satchmo +patton1 +active1 +sliver +easton1 +gamecocks +sixers1 +140889 +jeepers +bitch06 +michelle16 +sesamo +cygnusx1 +fakefake +dragons2 +kurwa1 +zaq!2wsx +guitarman1 +ritter +fir +milk123 +amir123 +milomilo +281288 +veronika1 +070790 +14121988 +bambino1 +zaza +241288 +joseph23 +hank +trinity123 +sunshine24 +notreal1 +polaroid +zujlrf +whore! +animal12 +endurance +shower +111184 +klaudia1 +thebest123 +fyutkjr +22121988 +joshie +batman4 +jockey +100883 +freedom07 +cfifcfif +140586 +12111987 +myshit +myspace20 +terran +sanford +elenka +trivium +maravilla +victor +cheche1 +10121992 +ivanivan +people3 +p0p0p0 +taylor +kanika +1357246 +candyshop +tayson +natedog1 +130188 +meg +louise2 +judoka +michelle6 +almendra +toolman +meryem +301088 ++ +dragon09 +pokemon8 +apricot +8balls +1budlight +baby91 +havefun1 +120680 +bourbon +funny2 +309309 +chachacha +bobby3 +health1 +willow123 +02071986 +ragdoll +bobby7 +zaqwer +11qqaazz +230485 +kapow +11121990 +openme +angelo123 +jacob10 +0987poiu +waterloo1 +mathilda +280588 +sil +14101988 +2501 +230187 +moinmoin +yamamoto +qwert2 +market1 +fruitcake1 +karamelka +surrender +laredo +anhtuan +itsme123 +butterbean +superman88 +broadband +primera +240488 +230387 +anibal +godawgs +mashenka +250686 +victor01 +karting +crfprf +parakeet +nikitina +retro1 +palomo +monkeys3 +521521521 +savage2 +11021989 +200288 +freunde +zoe101 +250586 +010889 +seo12345 +789qwe +krystian +diamond13 +e1234567 +christian4 +harvey123 +130190 +bionicle1 +21031986 +240787 +lilli +030390 +fy.njxrf +sexyred +w1966a +fuckyou07 +li123456 +22071986 +198822 +lovebird1 +2ealtd3y4y +beatrix +rrrrrrrrrr +princess26 +puffy1 +dutch +taytay2 +turbo123 +asia123 +pimp#1 +steven22 +asddsa123 +pimp420 +flowers3 +eeeeeeee +hatebreed +pad +love1996 +15051985 +amber3 +boycrazy1 +1904 +asd123456789 +240687 +amorcito1 +lovesong +marie6 +250288 +manpower +tweety08 +121092 +080889 +blue02 +artur1 +puppies123 +olidata +jobjob +jaja123 +jellybean2 +101985 +joshua17 +260687 +600020 +mark13 +11031990 +12051205 +bigmomma +400071 +antonio7 +741 +101984 +250488 +280690 +180288 +wentworth +w1967a +toast1 +ali12345 +241290 +15091987 +panasonik +linnea +liverpoo +04041991 +iloveyou* +22362236 +0147258 +fiddle +123456sa +chance01 +caramelo1 +celina1 +261190 +1jonathan +player21 +rugby123 +thomas15 +exotic +n1234567 +02051987 +brooklyn +... +gravity1 +nikolaus +esperance +traviesa +21121990 +110189 +15051991 +elnino +lovely13 +maria +78945 +oliver13 +maintain +elisabet +201012 +reeses1 +chaplin +11091986 +hostmaster +ilovemama +tiana1 +cheer4 +gabriel01 +456123a +123777 +ggggg1 +tonto +tulipano +redredred +tiamat +geirby +rainbow11 +dancer22 +star33 +311286 +destiny +mexico#1 +13121991 +garage1 +claude1 +02031988 +001983 +redcat +mick +kaylie +4711 +camila123 +1908 +291189 +25051985 +longhair +elijah12 +wetter +mattmatt +240985 +toocool1 +duffer +170686 +hunter02 +howell +220220 +scoubidou +bonzai +092124 +25061987 +cornflakes +150990 +12061987 +20051988 +lollie +lucky15 +11041990 +200986 +171090 +02031989 +munich +301089 +1skater +skyrim +230790 +gerardway +101192 +daisymay1 +coco22 +sara11 +love1990 +sincity +22021991 +grillo +psalm139 +alexis06 +miguel2 +waseem +31121986 +melanie2 +hansolo1 +aiden123 +king69 +420time +kimba1 +14021986 +beejay +02101987 +cookie8 +fatass2 +sexy99 +cc1234 +records1 +fuzzball +600001 +jarrod1 +vindiesel +010690 +170890 +123smile +mommy09 +miranda2 +100786 +babyboy5 +111111111a +spiderman123 +hotties1 +110885 +161086 +123123e +tyler! +r2d2c3p0 +steam +w1964a +spanien +coke12 +15975321 +stephie +maxim1 +eliska +squeaky1 +198619 +125689 +katherine2 +ozzy123 +rocketman1 +balls2 +vaseline +andree +140686 +cabernet +311088 +cameron10 +topper1 +andrews1 +15051986 +kittys1 +rider +darian1 +secure1 +princess96 +kbcbxrf +brooklyn7 +lionel1 +nastya123 +michelle18 +yankees26 +james! +quique +23021987 +binladen +240685 +bluewater +crawford1 +10000000 +291188 +130984 +22041988 +skull +yamaha123 +fuckoff7 +andrew8 +nnnnnnn +asterix1 +cheergirl1 +porsche911 +226016 +cliff +morgan7 +allie123 +frank2 +karola +kitten11 +daisy5 +megumi +weeman1 +23101991 +name +150487 +oliver +10051990 +231183 +seventy7 +kathrin +mbtvibranike +311089 +indian123 +commercial +jay1234 +winter2 +liljay1 +intern +01041987 +heretic +ufhvjybz +good1234 +prozac +230188 +sprout +hunter9 +nolimits +knockout1 +greenwood1 +radio123 +ruger1 +kestrel +robert18 +cyril +001980 +carlsberg +030688 +dbityrf +evgenii +20041988 +asdfjkl:1 +#1love +channing1 +3006 +toby1234 +borussia09 +tanguy +gustavo123 +luckystrike +thomas18 +310789 +legendary1 +charlton1 +19021988 +150689 +blitzkrieg +maulana +theshit +26031998m +ilove5 +jumpjet +diddle +ranger11 +blue27 +kozlova +townsend +moreira +angelika1 +mulberry +250487 +juvenile +ribbit +iloveyou06 +volvos40 +tanja +pepepe +ppp123 +victor +black8 +bella07 +tyler15 +cool14 +dietpepsi +loveyou13 +william6 +100187 +lucky16 +babygirl95 +2512 +helen123 +maryjane69 +200787 +25121990 +198525 +250986 +anathema +sweetie123 +240889 +ruslan +austin21 +ilovesarah +bubbles101 +fastcar +christmas +dagger1 +70chevelle +sasha1996 +ivan12 +aircraft +271087 +111191 +antonin +200690 +250486 +16061987 +lolek +none123 +badboy11 +nameless +donkey12 +rus +16101987 +superman08 +estella +140283 +cazzo1001 +biscuits1 +10061988 +luana +chamonix +sixers3 +fromage +pallmall1 +290990 +112288 +beaker +270788 +breast +nokia6303 +kelsie1 +medic1 +234561 +yourname +susanne1 +mimi11 +kurosaki +vvvvvvv +198625 +080886 +eeeee +purpl3 +presidente +bigjohn +panzer1 +goldorak +kingkhan +iamlegend +raven2 +brasile +jackie13 +wordup1 +qazwsx2 +11111986 +babyd1 +pulcino +slayer6 +belier +robert6 +canary +booker1 +h-town +50cent1 +jeremy11 +11121991 +josh15 +reymysterio +guesswhat +030393 +raisin +10031988 +penguin7 +jackie3 +chocolate12 +mark01 +trebor1 +happyface1 +mapleleafs +zapato +cabezon +leahcim +zxcvbn123456 +123456000 +qazwsxedc12 +agent47 +star18 +34 +barkada +dark12 +cluster +charms +kantot +stephani +kraken +111975 +281088 +raptors +yourmother +gattina +19021991 +shelton1 +yaya123 +ilovefood +roxy101 +rasengan1 +dinosaurio +tyler06 +100290 +optima +grass1 +jerkoff +140890 +20061988 +01021990 +1111111111a +271185 +default_password +pooh11 +sundar +20031989 +lexie +blue66 +abcdefg +terra1 +tree12 +carbon1 +rockband2 +271289 +taylorgang +300888 +hollister8 +zamzam +woowoo1 +181286 +145300 +cyrus +princess#1 +140388 +1marine +money17 +12345678n +demonio +dragster +281287 +110286 +crazyman1 +cheese23 +1lovegod +201085 +lucero1 +america5 +cheese01 +freelove +neverdie +meaghan +pokerface1 +eagles7 +joh +kelsey2 +310189 +pants +edward22 +dawkins20 +90909 +tink101 +122987 +dinmamma +123bitch +annaba +paparazzi +killer55 +fake1234 +darkness2 +010388 +250988 +12081990 +130986 +mark22 +123456777 +bongo +griffith +plokijuh +tijuana +20121990 +honeyb +25101989 +hello15 +boomer01 +justin03 +bullseye1 +changeme123 +barbosa +260586 +sophia123 +jollibee +a88888888 +baggio10 +2pac4life +brenna1 +cyrille +120392 +erik123 +231181 +110063 +130187 +23051991 +tweety15 +mustang13 +workout1 +110892 +sexi123 +clear +ubnfhf +softball18 +playboy! +princess91 +chateau +marcella1 +nokia3210 +mercedes12 +iloveallah +220292 +123321qw +150988 +blandine +123usa +1019 +281190 +porn69 +1qwerty1 +20061987 +1love4me +orioles1 +110383 +hello55 +joanie +monte +dbrnjhbz +funny12 +nokia3230 +im2cool +green24 +jimmy3 +roshni +tottigol +150787 +121293 +020788 +gears2 +rose14 +mybuddy +carrots1 +140590 +160589 +260588 +cucumber1 +02031986 +02041991 +rachel! +angels +starstruck +wuschel +checkmate1 +vlad1998 +stamford +110785 +megan11 +daiana +310310 +200989 +eagles01 +130887 +rfnthbyrf +151183 +soccerstar +characters +caterham7 +12061988 +wilma1 +heckfyxbr +icecream3 +rosey1 +11061987 +sergiu +peanut08 +ballers1 +vero +ranger +010183 +windstar +140886 +brotherhood +experience +050689 +boycrazy +lefty1 +brooke3 +mahalcoh +willie123 +aristotle +golden123 +loveyou22 +nyc123 +098765432 +17071987 +alphabet1 +skater15 +1beautiful +skyline34 +4christ +shades +4040 +matthew07 +aniolek +xavier2 +lullaby +drifter1 +yahoomail1 +aftermath +230285 +heather! +insight +sultana +jasmine07 +rosa12 +mamont +moneyy +charisse +wilson12 +laurel1 +lighter1 +password03 +barbie3 +200788 +arsch +bolinha +scofield +nicholas7 +161286 +alisa1 +andresito +pass_word +casamento +fujifilm +150288 +alex1987 +30041991 +candie1 +500018 +kevin +persia +steelers6 +imgay123 +hecnfv +thegirls +11081988 +14785236 +joker7 +candies1 +westbrom +130787 +roxy1234 +scandal +444555666 +mustang08 +saphir +grape +color +01031988 +12081991 +gotigers +19101987 +chelsea9 +money18 +matt23 +werwolf +мамочка +nigga4life +25051988 +orange99 +kimchi +usmc +gunbound +grandma5 +loser14 +ashl3y +julian +ricky12 +portos +dancer4 +198519 +1115 +161085 +cocoliso +destino +10041987 +rocker123 +051288 +bigbaby +daddy22 +jeff1234 +kirby123 +constance1 +120882 +saniya +tinhyeu +chapman1 +angellove +salame +a1234 +vodoley +locos13 +198322 +23021990 +poobear1 +super3 +crazy22 +greenbay4 +000888 +needjob +1tiffany +10041990 +ilona +18811881 +vbktyf ++ +481516 +151087 +230287 +08154711 +040985 +singles +lauras +200389 +170590 +nicole1234 +jerald +020686 +calculus +12071988 +cloud7 +undertaker1 +121294 +zxcvbnm +never4get +bailey08 +dixiedog +dashadasha +johnny11 +jk1234 ++++ +nicaragua1 +1iloveu +wilhelm +harley02 +noone1 +120683 +truman1 +130486 +celeron1 +stephany +toledo1 +jump +your +austin02 +flaco1 +fallout2 +blunt +23031991 +bluegreen +natalia123 +jessica20 +blazers1 +merchant +170585 +baptist +pimpin! +andyandy +saraswathi +aaron11 +10081987 +danmark +thomas07 +ninjas1 +sam123456 +wakeboard1 +22031991 +mircea +11031991 +jacob7 +mega +20041990 +250190 +malossi +little12 +09091987 +sananelan +chicago7 +10011992 +shane12 +popcorn5 +porsche944 +michael05 +angelica12 +110029 +110591 +nekoneko +anya +killer. +manumanu +olayemi +250189 +luismiguel +signup +cookie. +131185 +baller33 +4babies +05081988 +harley! +dora12 +alvaro1 +fatima123 +120580 +21041992 +pastis +elgato +12345678w +fel +onizuka +tictac1 +nathan22 +kamal123 +ugly123 +bharath +sebring +diamond10 +myspace27 +nelson123 +barbie7 +120480 +220385 +123rf +140589 +princess03 +210189 +2015 +force +fuckyou77 +jessica19 +02071988 +lessthan3 +loveangel +damian12 +150289 +laika +220885 +061 +scooter5 +honest1 +underwear +199100 +elenita +monica01 +forever8 +mindfreak +11111987 +niewiem +ss1234 +goku123 +vjflkig522 +justin20 +twokids +popcorn11 +050587 +a789456123 +1passion +140587 +14011987 +444666 +13121990 +15081990 +billbill +littleman2 +vatoloco +content +guccimane1 +180590 +mak +qqwweerr +link1234 +290488 +single! +yfnecbr +david! +nietzsche +choclate1 +14021985 +diablo11 +leah123 +caro +100492 +bobby11 +foreverlov +qweras +blackdragon +22091991 +booboo69 +pazaway +yellow9 +twitter +adelka +demetrius +woodward +internacional +170688 +sheree +170488 +star07 +ranita +tanger +mysecret1 +120283 +simba2 +isaiah2 +titou +bless +w1963a +201080 +cricket123 +10041004 +3ehd1ixi1y +malayalam +101011 +ktm125 +maggot1 +siegheil ++ +12041986 +hello09 +100884 +angel2007 +sharky1 +16101988 +caribou +197575 +9988776655 +07071988 +cherry22 +250489 +all4him +alice12 +400004 +snooker1 +141089 +saab9000 +wanadoo +gizmos +140990 +super11 +wargames +cthuttdyf +models +q1w2e3r +lampshade +111979 +przemek +hooper1 +23121986 +bilbao +19051992 +sexy66 +200685 +smirnoff1 +asd123asd123 +vette +mko09ijn +bigpapa +static1 +cfytxrf +thuggin1 +fish11 +gfhjkzytn +abc789 +12021991 +getrich +samarth +drew12 +1311 +money55 +yazmin +test11 +benton +skazka +goldmine +albastru +66778899 +201000 +caroline12 +capa +parker12 +manolo1 +justice2 +12081986 +myspace45 +781001 +kassidy +sweetie3 +1kitten +davidd +15121989 +termite +poop90 +evolution8 +brewster1 +18061991 +140188 +241085 +catherine2 +12031988 +june2008 +chino123 +020290 +131090 +20081990 +medium +kikimora +fuckyou89 +diablo +funeral +sad +sexisgood +billyjoe +nokia6120 +spring09 +281189 +10021990 +123456789012345 +bubba5 +mary11 +grease1 +ginuwine +garcia123 +chocolate +mitch123 +play2win +sector +greedy +priya123 +april04 +5858 +mynigga1 +coglione +bigboy69 +bitchface1 +angels4 +ilovehim. +killzone1 +21436587 +anne123 +25101990 +quantum1 +230684 +iceman2 +201290 +6string +gospel1 +essendon +coniglio +ashlynn +johndeer +15051987 +looking123 +rafa123 +consultant +shygirl +metallica9 +lizbeth1 +100790 +daryl +dagobert +maharaja +sasha1995 +triplex +twentyone +170586 +marduk +mickie +lashay +nike13 +sancho1 +rjnzhf +241286 +estrella12 +heidi123 +picachu +valentina +adelante +reckless +221183 +shivers +130592 +190586 +fiocco +onmyown +21021986 +summer77 +aaa12345 +cherry14 +mydog1 +255255 +download1 +raul +leadership +john3:16 +23021988 +david24 +cellulare +11qq22ww +adrian11 +mustang98 +02061988 +amante +cousins +lolman +swordfish2 +angelangel +a102030 +elisha1 +141290 +3112 +hadley +impala64 +200589 +iamhere +251284 +150687 +jody +madame +justinb +10011986 +mariam1 +brandon06 +alternative +261087 +rainbow13 +pickles123 +pimpin13 +tomasito +030389 +14111987 +hannah16 +171086 +tobydog1 +12041991 +11061991 +andres12 +vjq +05050505 +matthew08 +241087 +gutentag +october +ihatelife1 +grandkids3 +13121986 +199512 +300588 +laloca1 +stephanie3 +admin123 +five +carlos18 +150486 +walking +potter7 +120592 +120791 +gfhkfvtyn +hjvjxrf +angel91 +punkass +vfhecmrf +197911 +lynne1 +asshole9 +contessa +diehard1 +taz +carla123 +150789 +oneluv +duranduran +rangersfc +ivanna +150686 +wild +friendofarriane +100591 +ballin13 +mckinley +delores +liljon1 +anna88 +410206 +carter123 +redwood1 +goforit1 +marysia +abhijeet +s7777777 +muffin01 +bigdawg1 +bucky +171290 +19121991 +hejhej1 +jayhawk1 +dropdead1 +210686 +mandi1 +melissa +securite +otis +27101987 +az1234 +edalwin12 +12051986 +thomas09 +jack23 +sirius1 +kamila1 +mommy1234 +reaper666 +woodlands +spot +paulinha +741852963a +babygirl99 +niconico +23051987 +bubbles14 +02021982 +tantra +121183 +mike33 +140389 +20101984 +giada +sergeev +spain +myhouse1 +alfabeta +170388 +cahaya +15041988 +destiny10 +browning1 +230290 +bigdog123 +160890 +rodion +061288 +aqwxsz +grandma4 +star08 +free11 +1crystal +mail123 +100186 +seniors09 +kurwa +210684 +19121986 +claudia123 +pimpin01 +oreo11 +wildone +110592 +quest1 +22552255 +17121990 +asdlkj +lovesucks2 +caccola +shaved +commando1 +vredina +miyuki +blacklab +jiefang998 +mimmo +130590 +moymoy +olivia3 +020389 +finish +fitzgerald +qwerty101 +bowwow123 +100188 +lampard1 +zippo +lovey +11041991 +lazio +040490 +rocky10 +bossboss +cutiepie13 +larousse +jose21 +hunnie +210985 +10121984 +1254 +terrier +sports2 +serafina +banana5 +jacques1 +bienvenue +janeman +170289 +310590 +polopolo1 +badass69 +teodio +chicago123 +ali123456 +deicide +mariela1 +zazazaza +loveee +turtoise +dragon0 +140489 +221084 +javon1 +13021990 +soccer28 +221290 +police12 +18041991 +blackice +270989 +alex1998 +milanisti +mariko +bailey07 +bimbo1 +112212 +golf1234 +56835683 +hallelujah +xyzxyz +artem123 +petey +197676 +cod12qw75rqyi59n +1fatboy +murdock +13041988 +crystal3 +11031987 +987654321m +chopper2 +angels01 +stephen2 +grass +ducati1 +13061986 +20061991 +andone +snicket +cochise +rosemarie1 +pamplona +130891 +hetfield +scooby3 +prince7 +sarita1 +winifred +hopkins1 +confident +justina1 +13101987 +careers +bearcat1 +q1w2q1w2 +020688 +110784 +eunice1 +13371337 +babalu +vfvektxrf +oscar11 +10051989 +dannie +11092001 +rocio +chinky +alex92 +hotbabe1 +skinner1 +dolphin3 +cou +250685 +181186 +240788 +sawyer1 +jess1234 +asdjkl +thecat1 +marites +ma1234 +twins123 +271089 +alex007 +1candy +dasha1 +сџ +101295 +anelka +sunmoon +bustamante +dogboy +160688 +diploma +lakers09 +10031989 +010192 +ripcurl1 +katenok +180690 +220187 +jazzy2 +20021991 +steelers10 +jayden3 +1lovejesus +july4th +olemiss +tori123 +healing +nikeair +gennaio +121978 +assclown1 +scooter1 +getmoney3 +johnny01 +kellys +a22222 +numbers1 +260490 +nalini +240686 +221187 +25121985 +sunshine20 +hockey +zalina +hollaback +taylormade +stefany +berry123 +samantha5 +salazar1 +skillet1 +guitar69 +31121990 +120186 +rehman +04 +aaron13 +gaucho +jesusis#1 +george7 +alf +kallie +rhinos +120383 +walik007 +lemuel +breaker1 +husky1 +rogue1 +alex2001 +scarface13 +11021988 +210984 +mike25 +alex1 +tuktuk +kevin07 +nikko1 +maharani +baby45 +winnipeg +archery +kay +iloveyousomuch +dreamon +bently +gucci123 +dizzy +scissors +touchdown1 +212121a +1234567890123456 +keykey +magyar +roldan +manga1 +12091989 +qwerasd +130286 +malawi +sheridan1 +peaches +ilike69 +alicia2 +helpme123 +lahore123 +allahabad +281290 +regenbogen +23061990 +cheer06 +150790 +mexican2 +sp1derman +tigger09 +198421 +babygirl88 +prague +principal +illmatic +444888 +rafiki +230587 +200887 +nokia3110 +sabado +ventura1 +antony1 +straight +monkey05 +cheer3 +lapo4ka +asdfgh2 +180388 +intel1 +prancer +fuckl0ve +bringiton +boston +171287 +mailkuliev +sequoia +nicolas +kingjames2 +baby55 +anaconda1 +hero123 +polini +gui +edelweiss +donkey2 +fifteen15 +tiffani +reyrey +shuffle +deep +danil +jaylin1 +nigga13 +choppers1 +m654321 +alexis23 +asdasd11 +des123 +fidodido +copper123 +210589 +210886 +aleksey +liverpool12 +milagros1 +millerlite +140484 +basura +wicked13 +horses101 +700001 +74185296 +diana13 +20062007 +110391 +scroll +baseball69 +20021989 +130886 +03041991 +footba11 +kartik +23051990 +peewee2 +mogwai +tucker11 +mariah2 +segun1 +black4 +droopy1 +maybe +candy21 +nata123 +47474747 +260590 +super6 +77887788 +dungeon +mirinda +w +monika123 +123007 +07071986 +mememe3 +playa123 +231092 +nokias +bluegirl +19511951 +nana01 +111183 +301190 +whiteout +gabriel13 +scorpio7 +july04 +171186 +harvard1 +austin8 +02041988 +1dolphin +wwe12345 +lovebug12 +powerade1 +21011991 +galicia +colombia12 +stewart14 +snuggle +tequilla +020282 +starwars1 +301286 +060788 +020590 +allday +02051986 +19071989 +cartier +lamborghin +15061987 +element3 +wilfredo +rfhjkbyf +261090 +cheer7 +belleza +dingbat +1steven +flawless +17121991 +internet123 +130288 +181089 +cosita1 +josh21 +emolove1 +bubbas1 +0001 +1sexylady +icarly +mona123 +12031985 +220186 +hammy1 +adidas11 +251190 +rainbow4 +grandkids4 +aka123 +vendetta1 +13121985 +20051985 +230785 +21051991 +taratata + +azerty123456 +sunshine88 +pasta +v +thickness1 +bigmomma1 +160588 +tweety23 +hearty +april08 +25101988 +abcdef123456 +joker11 +20081987 +alexis +cecelia +260589 +mariane +babyblue12 +joker666 +ryan14 +qwerty25 +joel12 +rubina +hockey01 +passion8 +multisync +bismilla +tomandjerry +lucky18 +int +breakfast +matthews1 +da +loveme6 +mustang6 +jijiji +02031991 +19031993 +261083 +charlie09 +pokemon23 +251182 +fuck1t +bobdylan1 +smoke20 +15071987 +agostino +cuba +williams2 +tigger15 +lelouch +nokia6500 +122003 +310585 +pepper4 +teachers +southpole +friends101 +roxygirl1 +mikolaj +duckduck +a147258 +southside4 +jasmine15 +123456tt +2410 +spaces +gethigh420 +dadsgirl1 +jessika1 +come2me +konoha +metallica8 +dreamer2 +ruben123 +riddle +chrissi +jonathan10 +girl11 +stupidass1 +monkey95 +10111011 +150190 +element13 +nevershout +salavat +050586 +eddie2 +250690 +28121987 +football64 +midnight7 +suckme69 +babe101 +rocklee1 +mankind1 +200390 +199412 +basic +nikitin +hunter04 +uekmyfhf +as0620 +estupido +180587 +dakota10 +egypt1 +winner12 +cioccolata +050788 +250886 +jerrey232x +tallulah +301285 +dawidek +almera +winniepooh +verde +220290 +020287 +1brittany +solnze +deb +hamster123 +sbc123 +f1f2f3 +virgule +12051992 +cardinals5 +198321 +jigger +antiques +000222 +lucky007 +thanh123 +katerina1 +webkinz +hannah04 +22031990 +vfkbyrf +fresh2def +sony1234 +sammy22 +edouard +tigertiger +ralphy +12051990 +henriette +10041986 +loser1234 +taztaz +x60zay0468 +sharan +10091990 +honney +mickey14 +150386 +culture +120991 +iloveu14 +250286 +namrata +234567890 +athome +11121989 +powerhouse +january4 +vaz2106 +@elit-centr.com.ua +georgia2 +mischief1 +hubbabubba +withlove +2014 +300687 +koteczek +pimp06 +fuckyeah +kid1412 +111282 +murda1 +novell +210786 +290788 +robert08 +forward1 +gracie +mangoes +lakers34 +montes +brock +fastball +15101985 +gmail +051289 +freedom13 +character1 +babygurl! +house2 +123888 +love6969 +yellowrose +babyboy01 +froggies +kashmir1 +pebble +wlafiga +erick123 +charis +rhianna +01011994 +fullmoon1 +beepbeep +jack111 +24688642 +getout1 +glamur +darby1 +130390 +ribeiro +bandito +qazxswedc1 +11081987 +sexytime +happy123 +norbert1 +events +deacon1 +11061986 +123456789- +23101985 +maggie +2505 +love36 +15101990 +debra1 +6cxd2x986x +sandra01 +1bubbles +honey23 +makedonija +ladiesman +juegos +06061987 +k12345678 +catalyst +230292 +24041991 +keenan1 +26061989 +1turtle +180588 +puma +friends8 +584131420 +toptop +password98 +nnnn +frazier +liquid1 +pussy! +tiger8 +honda99 +nicki +bieberfeve +animelover +fyabcf +korn123 +311086 +lolek1 +melissa5 +tormenta +monster22 +acquario +raiders11 +zangetsu +juanes +myspace44 +mothers +kasumi +21031991 +arcade +nutmeg1 +rubicon +bonnie01 +geo +600004 +dawg +0311 +211087 +olivier1 +class2012 +22061987 +07071984 +carmencita +11071989 +151187 +100783 +260986 +10061987 +qfcfgda3zx +333000 +babygurl08 +der +ok123456 +dany +22071987 +laylay +flirty +jackass69 +tanner01 +notagain +queen23 +pickle123 +airjordan2 +26101987 +220282 +robert16 +smoke2 +1119 +utyyflbq +gocubs +280689 +stirling +25051989 +mayday1 +pinokio +300690 +buster99 +karaganda +tinker11 +redsox5 +janessa1 +layouts! +timati +030588 +aa000000 +hollister0 +210190 +200187 +prime1 +02081989 +lovelife2 +oluwatoyin +peanut4 +cookie15 +11071987 +willi +hockey27 +sammy14 +240690 +roswell1 +agadir +password29 +s123123 +state1 +alexis05 +badabing +bebe13 +johnny! +caraculo +erotica +memories1 +365365 +sasquatch +18091991 +raffles +spring07 +aminat +hrithik +kilkenny +roxette +ce +141189 +110491 +20031991 +stickman +altoids +1smile +fenix +260989 +123456jj +oliwia +dragonslayer +271090 +25101991 +anhyeuem1 +170685 +faerie +killer24 +shannon7 +abigail2 +1green +hogan1 +carrillo +booboo10 +klklkl +elliemae +rockon123 +240987 +avatar123 +190589 +paulinka +13031985 +genesis11 +softball07 +jesus9 +nathan5 +110882 +loopy1 +muslim1 +father12 +s111111 +carlos69 +anonelbe +egorova +player22 +rodger +261289 +lollypop12 +sa1234 +101094 +14031991 +richard01 +monsters1 +160490 +adenike +ally123 +web +caballo1 +sydney11 +monster8 +pussy22 +furball1 +190789 +13061990 +lalaine +fuckyou24 +yourmom3 +cool21 +kilroy +bluejay1 +281289 +80sbaby +270688 +huihui +stephy1 +13121989 +banjo +jakarta1 +3535 +020687 +pooh14 +allgood +josie123 +stupid11 +mates +te +260691 +morgan5 +quick1 +kanker +12071991 +251285 +bobbys +alkaline +23081990 +seo123456 +renee2 +198723 +lordlord +pedrinho +14041992 +11021985 +240989 +100984 +lucass +ilovehim3 +repmvf +yeahright +im2sexy +aezakmi1 +loveyou5 +souleater +23061987 +lekkerding +ani +120120120 +050988 +underoath7 +double07 +23041986 +smile4u +timberwolf +190488 +chevalier +chelsea08 +dilligaf1 +hjvfyjdf +150886 +160587 +moc.oohay +25031988 +function +300590 +w1962a +love1989 +23051988 +carsten +kin +111177 +bee123 +next +301288 +jsbach +iggypop +barcelona +shabba +21031990 +1eminem +15987 +lucky24 +260190 +green25 +yingying +dustydog +nantucket +tijuana1 +jm1234 +monkeylove +cody01 +iamsexy1 +claudia +celica1 +cock69 +666666s +110582 +screamo +milwaukee +mailbox1 +456asd +crips1 +jordan00 +abc123xyz +181290 +nathan05 +raymond2 +june09 +250490 +schwein +tissot +1943 +paupau +111087 +pisolo +emmarose +xxkk01234 +7u8i9o0p +foxylady1 +carmen2 +domain +kitkit +01021988 +islam1 +ghbhjlf +lilwayne23 +fishtank1 +coocoo +grandmother +setembro +harshita +30031988 +15021987 +puppy3 +asd789 +051 +matrix +02061989 +mario3 +130490 +crispy +100882 +22041986 +05051988 +soul +230891 +198010 +josh16 +13051987 +woe45byzry +diablo3 +p0pc0rn +b1lkeb6711 +12051989 +shit69 +22061989 +guitar5 +kaleigh1 +iloveeric +06061988 +sochi2014 +peoples1 +romeo2 +11111985 +marquez1 +juan1234 +emin3m +hireme +greywolf +millertime +pumpkin12 +football84 +lyubov +kitty23 +ambika +21031987 +thecure1 +tomcruise +12061986 +14051987 +gogators1 +jackson11 +zappa +210785 +junior16 +agenda +mother +qwerty18 +310888 +paulinho +rusty12 +230386 +looking4 +135795 +bammargera +deepblue +wakeboard +upload1 +andreeva +110692 +100985 +juniper1 +colors1 +banana3 +tigers07 +verbatim1 +120880 +131425 +butterfly +madhu +12111211 +merlin12 +spider3 +ole4ka +dukeduke +11011991 +nirvana7 +angels13 +angel. +20071988 +никита +iopiop +30061987 +austin6 +tigers09 +jiujitsu +fatbitch1 +dfcmrf +291 +240487 +asshole6 +10011985 +watch +skateboarding +quinn +oldsmobile +101988 +mirabelle +010788 +cash12 +12081208 +123456ma +buffett1 +chase12 +maruska +13101988 +7788250 +11101991 +jigsaw1 +liza123 +spectre +fvthbrf +sound1 +13111987 +common1 +timoha +19051988 +shorty6 +280188 +baby27 +bitch88 +chinatown +ilovesteve +280882 +12121212a +13101986 +matthew14 +00000000a +baseball32 +bondarenko +twilight +220692 +16041987 +210186 +? +chapstick +18121991 +060789 +liverpool4 +bayarea1 +carolann +zinaida +bulldog12 +adebowale +280889 +slayer2 +1223456 +alireza +superman18 +668899 +wzf2sme498 +24111987 +love1991 +12061991 +20061989 +harley04 +mizuno +270587 +roxy13 +titilayo +hemmelig +ender +12021202 +121081 +10011991 +000000000000000 +cameron11 +renata1 +150785 +yellow8 +1happy +dasani1 +football00 +booger123 +mariah123 +cyber1 +142536789 +adedeji +bella23 +11251125 +maria21 +120191 +12071989 +pochacco +198319 +alex95 +daddy101 +livelaughl +penny2 +boytoy1 +12101992 +cybershot +allahisgreat +jadakiss1 +161190 +albert12 +grace7 +jack24 +napoli1 +folgore +error +hotsex69 +20081988 +02051988 +06061990 +summer9 +hillside1 +161287 +150786 +07071989 +rovers1 +201283 +1shithead +kingjames1 +schools +minhavida +young123 +gtkmvtym +vaz2107 +school5 +andrea. +lilman12 +patty123 +titina + +010688 +welkom01 +tigger24 +pollon +live4love +augusta1 +greek1 +20121985 +170790 +220285 +fredrik +yellow99 +sexy67 +mi +oluwatobi +valenzuela +16061986 +bananas123 +saphire1 +chouette +bleach123 +clotilde +120682 +hawaii +rotary +martin10 +12071987 +210687 +4455 +tabbycat +16021990 +freaks1 +gfgekz +samira1 +tatatata +butcher1 +robert24 +49ers +160989 +199212 +120582 +gam +betina +1midnight +lucky88 +12101985 +bungle +21121988 +tigers3 +198910 +fuckedup1 +100682 +12121980 +vikings28 +tigerman +resident1 +dizzle1 +221091 +mario5 +161187 +250889 +rayray123 +silicon +noname1 +deniss +10021989 +05061987 +271286 +m111111 +horatio +500038 +pleasant +20051991 +sable +241285 +anabelle +modesto +heart12 +avenged7 +240490 +piazza31 +micmic +king99 +2412 +225566 +yomamma +17021991 +frankie3 +claudette +111192 +clarkkent +sensitive +vip +200487 +alan12 +nathan! +161090 +ktjybl +140487 +saisai +090986 +030987 +tamika1 +yanina +shushu +sasuke11 +princess98 +basket12 +manpreet +honda01 +24101988 +160290 +perfecto +daria +google. +070786 +160985 +katie5 +paralelepipedo +maxwell +myspace55 +jayden05 +beau +iliana +070890 +bailey24 +sunshin3 +160888 +19091985 +qwertyuio0 +211285 +nostradamus +deer +caruso +tiger1234 +babygirl02 +twenty4 +thewall +muyiwa +10041989 +pumkin1 +lifeguard +01031989 +camryn +17031987 +sou +bolabola +sensor +myszka1 +101520 +maktub +immaculate +crissy1 +123asd456 +mclaren1 +lifegoeson +shelby13 +cheeks1 +chucha +inlinked +020888 +elpaso +crazyboy1 +shyshy +sos123 +poohbear11 +mystique +khalsa +signin +1234567a +joker3 +email1 +comein +majiajun +homie +161189 +sophie +chicken69 +series +hello +missingyou +pawpaw1 +godawgs1 +kiran123 +pipipi +fonzie +inuyasha +shipping +17101987 +diamond21 +wolverines +leonora +22061988 +271186 +alistair +bullrider +nin +surendra +pennylane +friends01 +feyenoord1 +japanese1 +bottom1 +silencio +andrew. +17121985 +170389 +tigger77 +eureka7 +nessa123 +magaly +espada +isaias +110291 +alpina +piepie1 +papamaman +terremoto +13061989 +vasilek +lilboy1 +crappy +280488 +110290 +sweden1 +888000 +110682 +david8 +sandra11 +15031990 +raulito +18101988 +17051988 +11091989 +dasani +15031991 +4vgyvq46aj +stars2 +humble1 +invictus +quick +159357159357 +rerfhfxf +131085 +11bravo +xoxo +apple21 +12011988 +luis15 +samuel11 +10111988 +delano +sasha11 +corporation +santos123 +melissa1 +annabell1 +5841314520 +1234567890s +twin +13081989 +310586 +jacobo +kisses4u +22041991 +13971397 +frida +virus1 +11021992 +ashley99 +prison1 +bmwm3gtr +dragon07 +230990 +family101 +leslie12 +crusty +devilmaycry4 +141190 +130987 +1number +121181 +andre12 +naruto4 +q1w2e3r4t5y6u7i8 +121295 +260684 +esqueci +mausi +25121991 +19051989 +minniemouse +tulip +canada +pinkgirl1 +harpreet +260290 +nena13 +finlay +jessica24 +lucydog1 +22061991 +4209211 +261285 +pizza5 +01061987 +manuella +251084 +alex94 +wangwei +13051988 +121221 +130683 +errereer +mario10 +futbol10 +football74 +260685 +clouds1 +06 +angelie +quaker +chicken9 +littleone1 +weed11 +love2u +ryan10 +30101987 +trabzon61 +201083 +4everyoung +654321j +phoenix13 +l0vely +kisses! +031286 +a!515253 +1597532486 +icecream7 +trigun1 +hanna123 +kissme! +hockey! +jennifer19 +habana +jack07 +gifted +160487 +valiant +ilovemyson +vangie +eumesmo +peanut69 +snoopy +classical +shinigami1 +hey1234 +computer4 +kiki13 +johnny23 +crazy23 +hearts123 +lan +13081991 +juliette1 +260688 +gen +mayfield +16061988 +april07 +hellow1 +mahavir +automobile +dfcbktr +peepers +pink89 +kenneth2 +sarahs +10101993 +alyssa10 +daddy09 +george10 +28101991 +formule1 +lalalalala +250582 +02051989 +maryjane2 +231290 +channing +abby1234 +001979 +boxster +26061991 +270990 +penguin12 +nicolette +jumping +123456bb +290388 +pants1 +kiki1234 +david9 +softball00 +25031987 +smartass1 +10021988 +20091991 +rochester1 +bitches3 +mamanpapa +tazmanian +nnnnnnnnnn +cuteboy +hallie1 +121192 +20021990 +dirtbikes1 +11041986 +ballin22 +celibataire +washburn1 +fungus +p6264758 +ichbins +fhntv1998 +stupid3 +198110 +7us20 +jesusjesus +beebee1 +bailey5 +777444 +outback1 +231282 +numberone1 +198419 +23091986 +198423 +kostyan +hangover +luis14 +160987 +junior18 +jerkoff1 +jackass! +monster +atlantic1 +sophia12 +holly2 +hyper +limewire +123321fvfv +hombre +auntie +tweety6 +tiger99 +123a321 +dinky1 +blahblah12 +16081988 +micha +141085 +apple123 +290987 +home12345 +klaus +kadett +brody +nachito +1chelsea +315920 +lambo1 +19031990 +mikaela1 +10031992 +johndeer1 +gulnaz +241091 +fuckyou16 +031187 +mymummy +sudhir +buckley1 +vovavova +music1234 +190888 +199012 +oswaldo +amiga +persoff +hallo +040489 +eminem69 +123569 +260789 +100691 +rarara +edcvfr +100991 +thundercat +buddy14 +sabina1 +lakeland +katten +112234 +honza +pink06 +critical +envision +honey21 +goodness1 +morgan22 +05051991 +atlas +tru +badboy3 +swim +getalife1 +12061989 +sureno +gateway12 +atomic1 +jimmy5 +454647 +270873_ +21041988 +21091987 +bigjoe +sarang +05051986 +scott2 +02041986 +11041987 +amoroso +bubba69 +edwin123 + +11031985 +271187 +purple89 +chivas15 +daftpunk +zombie13 +lalo123 +annie12 +21121985 +live2love +faith777 +adidas69 +magic7 +crazylove +maldito +198720 +21061990 +10021991 +lateralus +canaille +forgetful1 +fubar1 +marcus01 +101293 +14021988 +161285 +1118 +appleapple +a1s2d3f4g5h6 +pokemon +happybirthday +kakarot +d54q7xjmhx +fuckmenow +african +cloud123 +210585 +mybabies2 +andrea21 +151283 +kayla10 +holahola1 +13071987 +pizza3 +16101986 +pray4me +juggalo69 +markie1 +kailash +love35 +gangsta101 +tyler09 +pink00 +01021986 +turtle13 +23021985 +020388 +peanut07 +170786 +angel90 +corner +pizza11 +irina123 +a1b1c1d1 +230489 +lvbnhbq +cfrehf +2020327 +lapin +chewy123 +monster6 +louisville +210490 +babygirl27 +17121986 +pepper23 +21011987 +faith3 +c00per +robles +11051990 +1234qwerasdfzxcv +newlife4me +ford250 +freebie +sargent +240186 +78963 +victoria3 +kamera +mautauaja +coc +1smokey +010488 +thibaut +zoozoo +cheap +blood3 +example +gerson +ganesh123 +asd123 +ayden1 +ineedmoney +130385 +offshore +kampret +a23456789 +babyboy11 +101202 +ballin21 +hollywood7 +funtime1 +261290 +sexkitten1 +jennifer21 +23091991 +amber14 +cde34rfv +qwe123rty +alex1999 +01071986 +poohbear5 +100891 +leicester1 +baby94 +croatia +151290 +motylek +coccinelle +130784 +micheal2 +15021991 +turk182 +whatever69 +orbital +280886 +tortilla +hawks +website1 +261189 +231182 +soccer96 +vicelord5 +eleonore +class2008 +111111qq +11081989 +pookie11 +moonchild +100684 +spiderman! +afolabi +toilet1 +jennifer23 +medico +sridhar +tatyana1 +tin +100692 +chelsea4 +210683 +afroman1 +30031992 +speech +maggiemay1 +140291 +basset +brain1 +scoobie +tttttttttt +021089 +cheyenne12 +missie1 +220391 +arisha +include +220489 +321meins +220284 +bitch#1 +1sweetie +volgograd +141187 +cippalippa +shemale +021088 +1nicholas +s1s2s3 +24689 +zxc1234 +04041986 +100390 +stephens +beauty12 +asnaeb +rhino +22111989 +191188 +fkm: +cnhtrjpf +пїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕ +antelope +vfvfbgfgf +packer1 +lechat +tweety07 +babalola +421201 +bailey99 +face +sonu +bianca12 +violator +wendell1 +pecker +190590 +charlot +cantor +280388 +000012 +20121986 +30121986 +226010 +lambada +12031989 +book123 +123212 +dragon33 +fairview +hammerfall +morgan! +booboo! +married2 +alex1989 +iloveyouu +summer +dewey1 +nittany +pimp99 +joey13 +zoey +cookie17 +241084 +110384 +irvine +vegas123 +270984 +rockband +161084 +innovation +jonesy +300589 +icp123 +aniyah1 +bubbles23 +15021985 +1234567i +henry2 +amit123 +jeevan +sunnyday1 +10011990 +treble +kimkim1 +njkcnsq +tasneem +cheesey1 +yagami +candy15 +living1 +strasbourg +sin +core2duo +anonim +dulcinea +271188 +mylove11 +12021992 +panda13 +dunkin +321321a +snowman2 +25021988 +12561256 +198424 +accept +fuckuall +swetlana +19031985 +kickboxing +01101987 +eatshit2 +081 +26041988 +ccccc +01021987 +mujeres +fartface +2pac +doubled +momdad2 +bmw2002 +agusia +melissa01 +les +heineken1 +21guns +love2you +schubert +iloveamy +carnival1 +sure +shogun1 +mickey07 +jacksparrow +jenny11 +travolta +callaway1 +mariska +crockett +291088 +happy99 +toolbox +pumpkin3 +18041987 +senate +230185 +ifeoma +nate12 +18121989 +dancer5 +100191 +notnow +ac +password* +fylhtqrf +babita +140390 +21021991 +nathan +250687 +imabitch +19071991 +margareta +11021990 +gauthier +ionela +albert +hazelnut +031089 +25101985 +290689 +01011974 +sex12345 +mynewlife +austen +roosevelt1 +irlanda +patrick4 +28041987 +godrules +03031986 +prometheus +140790 +sexiest1 +pittbull1 +z12345678 +160889 +matt21 +220684 +pcwac33gb9 +18021991 +14061988 +bella4 +13061987 +010102 +cerber +georgette +andrea22 +19041988 +satan6 +marie! +football85 +785612 +lulu889jdddd +05061986 +alexis02 +dol +jojo22 +ride4life +121004 +comida +270789 +gjvbljh +223355 +automatic +cyrus1 +sea +30secondstomars +deadhead1 +school10 +171085 +bradley2 +daniel00 +09091989 +nyyankees +rollie +bobby5 +140385 +iloveher! +kate12 +cassey +luis1234 +510510 +buldog +sabian +punjabi1 +alexander123 +candles1 +875421 +kl098709 +members +100491 +rocker12 +251280 +11121984 +281185 +bigboy5 +steelers36 +bobbyjack1 +slovakia +dodge1500 +170988 +epson +denton +believer +devendra +davedave +10021986 +cielo +18051990 +140985 +17021990 +blbntyf +shygirl1 +12091991 +ibrahimovic +98769876 +yourmum1 +ibelieve +herewego +123qweqwe +geforce +monserrat +jonathan11 +sierra01 +dynamite1 +071188 +oliver22 +adedoyin +190587 +152152 +abcde1234 +caliente1 +orange. +124567 +channel1 +02051991 +lilfizz +pussy21 +edward7 +bastos +andrea3 +tampa1 +11071991 +09091990 +padrepio +radiation +yan +ralph123 +150592 +parsons +04041989 +021286 +jaipur +500029 +elwood1 +198765 +polkmn +pochta +marzia +12021986 +10011987 +weed4life +jennifer69 +benben1 +20071990 +220785 +130388 +lumber +snow12 +leon12 +123qwe321 +200285 +torito +110891 +thelord +plopplop +marker1 +cherry! +jodie +tiamaria +january30 +524645 +154154 +13071988 +brianna7 +1234we +scooby01 +keller1 +gabbie1 +wilder +justin. +140986 +301085 +01071987 +hyphy1 +260489 +pookie01 +01071985 +houston2 +jacko +marley12 +iloveme11 +22111991 +12041987 +140984 +020987 +calista +diedie +myson1 +120284 +lilfizz1 +bullshit69 +turtle11 +clever1 +nokia12 +brooklyn3 +terrapin +salute +county +10011984 +marjorie1 +abuelita +sexy44 +23101990 +systemofadown +letsfuck +happydog +1q1q1q1q1q +sachin123 +emoemo1 +gjgeufq +11061988 +luis10 +airport1 +matrix01 +06061985 +29710455d +musics +10031991 +sarah22 +pokemon0 +superman07 +101280 +270188 +girasol +runaway1 +mickey69 +06061989 +wellcome1 +loveher1 +wojiushiwo +snoopy! +23031987 +010108 +271284 +juggle +180490 +fender2 +a147258369 +semper +jammin1 +blue34 +pomme +desert1 +050595 +10051986 +214 +seb +babygirl123 +260288 +stalingrad +231091 +uhf9qdh +vicente1 +santi +angie12 +x1x2x3 +120482 +100989 +madzia1 +abdulla +chicas +hailey01 +21061987 +alex2002 +riviera +101093 +29121987 +200386 +19051990 +coklat +metroid1 +aquafina +111977 +falcon7 +1122331 +mickey4 +longhorns2 +boysoverfl +gretel +28051991 +mila +jrcfyjxrf +240187 +131191 +mir +mustang8 +millicent +123123d +davidb +lovess +army123 +owner +200800 +22051990 +sudhakar +mariaelena +pompom1 +malatya44 +asa +160388 +chijioke +loveyou11 +151184 +201084 +movement +betito +01041986 +victor11 +pluton +gogreen +daniel89 +heartagram +lea +120281 +anastasia +cutiepie11 +12111991 +15081987 +ilovejacob +doc +tuscany +140486 +170785 +brianna5 +1234567qw +webcam1 +bugaboo1 +1303 +12001200 +11111989 +25041987 +heynow +bedroom +aaa777 +120183 +lego +mohsin +letters +cowboys01 +watkins +kalani +271184 +lovegame +210289 +poop10 +keerthi +money +qwertyui2p +020488 +urmom123 +eagles09 +130186 +candyshop1 +nosmoking +gemini69 +4815162342lost +2110 +bulldogs12 +mamica +paris12 +melon1 +crappy1 +greenday13 +521000 +jus +performance +250185 +montrose +please2 +dolphins2 +12041989 +luckyme1 +england +eric13 +everquest1 +132 +zorro123 +john1010 +270487 +01081988 +ashley93 +really1 +trey123 +olivia13 +kassidy1 +ruslana +melon +zindagi +piranha +vfhctkm +ppp +gb15kv99 +101210 +260486 +wasd123 +200290 +paulpaul +skaters +r1chard +200882 +outlaws +281286 +101193 +kevin15 +vince15 +amaya1 +291287 +eminem13 +051290 +tyrese1 +123456.. +tanusha +061290 +310787 +metallica! +13031992 +brooke13 +rock&roll +260790 +mommy07 +nippon +311285 +hardcore69 +allo +18121990 +michael0 +happy4u +160585 +condom1 +21041987 +viola1 +jojo23 +riley2 +111976 +turtle7 +poohbear7 +soccer32 +1405 +leavemealo +money33 +nicki1 +crazy10 +290687 +samsung1 +charlee +bianco +160390 +budda1 +16071987 +taco12 +matthias1 +star67 +kitty8 +godfirst1 +jayhawks1 +03041987 +11071988 +1charles +sulaiman +171187 +alright +01091987 +mickey +energia +manman123 +agustin1 +250887 +brasil10 +pasta1 +18021987 +23011985 +gta123 +freshstart +mustang03 +fruit1 +willard1 +annie2 +11061990 +sowmya +sopranos +optical +pepepepe +18121987 +170484 +cassy1 +2204 +andrew9 +marmaris +arsenal4 +180990 +tigger16 +bus +111991 +phish +meme11 +majestic1 +hometown +laura13 +1nathan +304050 +03061986 +demonic1 +1310 +211089 +lalola +rose23 +654321s +67676767 +525525 +waterford +tempest1 +dthjxrf +alexis6 +tracy123 +carmela1 +revival +mickey! +190985 +romulus +junkyard +zxcvbnm8 +211085 +charlie. +10061989 +allthebest +yannis +ilov3u +15011987 +piesek +ocampo +dean123 +310388 +loveme8 +1308 +sumerki +gjyxbr +twinboys +040888 +190288 +170987 +199011 +babyboy09 +redwing1 +vaughn1 +rommel1 +glass1 +050686 +silver3 +hooch1 +20031986 +nassim +goodfellas +03041986 +iloveyou02 +alyssa +chester7 +francine1 +haruka +bliss +more +santaclaus +niranjan +april01 +stevens1 +loser21 +311090 +123йцу +falling +010888 +02081986 +informatio +300388 +azer1234 +freeze1 +fxnocp14 +9876541 +whoops +160689 +22021990 +takeshi +13081988 +01041985 +chooch +19061987 +clancy1 +percy +bolanle +bailey! +portvale +luckyman +irock12 +199312 +1200 +19091988 +lthtdj +plmokn +banger +24101986 +sarah5 +backpack +mine12 +11111991 +rendezvous +hotmail. +13051991 +landen +teardrop +240585 +211283 +laloca +hitesh +hardcore12 +skater10 +220286 +amber5 +17051990 +210484 +julito +20051992 +firetruck1 +19041991 +adrian01 +monella +260788 +david +canadian1 +fakefake1 +130591 +130885 +gamefreak1 +space2 +beerman +lexington1 +denya2531914 +karina +tinker01 +findme +tomboy1 +transporter +221281 +16051988 +a3eilm2s2y +020588 +bluestar1 +beezer +130287 +sayang2 +casamia +260390 +240389 +bambie +300686 +220185 +sham69 +201092 +200591 +classy +peanut23 +smile4 +jesus12345 +jennifer10 +rideordie1 +zoomer +welcome11 +oriental +junk +16897168 +sammy4 +13011987 +austin09 +iddqd +gcb +250785 +250683 +polish1 +selim2010 +311289 +360360 +200289 +280988 +tigers22 +547896321 +david06 +10061985 +joseph4 +yogi +one4all +129129 +ducky123 +loca12 +chiken +161089 +daman1 +pokemon101 +ritesh +020286 +monique12 +sananto210 +love234 +lovelove12 +20071989 +cricket2 +sweety +03031983 +19091986 +160787 +jose22 +001981 +jeniffer +310190 +sexy02 +24101987 +xyzzy +11021991 +fresh2 +marcopolo1 +vostok +fakeass1 +05051990 +shanny +traveller +skillz +pianoforte +271086 +140888 +143445 +amira +q2w3e4r +trackstar +198620 +babycat +babyboo12 +marihuana1 +montana2 +pikachu2 +madison13 +utility +10081985 +4everyours +22061985 +051186 +jamison1 +duke22 +kulangot +killer00 +subtitle +forklift +barefoot1 +voltage +iceage +bokbok +shannon3 +charm +cards +love2shop +1234567o +bouchon +sab +madhouse +caution1 +010589 +opel +princess45 +14041989 +199511 +20121991 +24121987 +firestar +diabolika +fire11 +nicole03 +02588520 +threeboys +150887 +3210 +king07 +beefcake1 +star09 +08081986 +junior4 +michelle17 +william08 +football82 +sorriso +15041991 +long123 +21121991 +210887 +190490 +010588 +rakker +11011987 +allahallah +12121993 +301184 +23101989 +willie12 +lakers01 +manoj +27051988 +andrei1 +bunny13 +someday1 + +sophie13 +tujheirf +teagan +wormwood +160488 +0711 +28101987 +franziska +stlouis1 +afrodite +golf12 +199612 +zachary1 +norwood +23081988 +doodie +26061990 +kelinci +baobab +130387 +ily1234 +mou +official +13111990 +deidara +micro1 +elmejor1 +ilovetim +10051985 +filefront +nithya +dobermann +300488 +bunghole1 +radcliffe +01061990 +imsocool1 +110283 +yanochka +mylove13 +20121987 +robert. +papi123 +cristianoronaldo +180589 +capricorne +240289 +ter +181086 +ducati916 +damn +nando +aloysius +lulululu +antigone +1qqqqqq +daniel27 +manman2 +lockdown1 +231082 +samantha21 +jkjkjk1 +luisa1 +kayla7 +1antonio +824655 +1fishing +remedios +haleigh1 +ella123 +direito +28081991 +dodo123 +midland +170985 +snooky +mariola +140989 +170789 +elemental +live2die +alysha +hell123 +fucku7 +free1234 +chevys +4141 +180687 +hailey2 +lover1234 +101281 +600018 +panget1 +poppies +bayern1 +passion123 +mickey08 +230490 +paco123 +magazin +annisa +rimini +261086 +clement1 +spanky123 +mike +turquoise +cali13 +eminem3 +andalucia +shannon +04041990 +charl1e +230885 +sales1 +wilkinson +110392 +annarita +zaqwsx12 +compton310 +153246 +14121989 +texas11 +cute14 +shareaza +kirill +belmont1 +conquest +sisisi +bread1 +melons +031 +melanie123 +dance11 +smithers +justin02 +anaclara +i97wb6sxq7 +asshole21 +myspace111 +bestia +tyler8 +screwyou1 +123321qweewq +blondes +bigballer1 +badoo123 +hannah1234 +1910 +170486 +firehouse +nessuna +220191 +catania46 +poop1 +edith +17111986 +13061988 +az147258 +030990 +johnson123 +20091989 +sophie10 +allen12 +270588 +linus +1234qwer +dragon20 +20121989 +duke1234 +240288 +020789 +253545 +2205 +13021987 +cupcake7 +jacko1 +170485 +tazman1 +16121986 +maddog2020 +treetree +raja123 +crystal13 +josh69 +301086 +111180 +ghbphfr +lesbian69 +princess97 +7410852963 +kitten7 +chloe3 +110492 +shaggy2 +031189 +reddy +cookie09 +01071988 +outlawz +tatina +100584 +vfnhbwf +coleen +ch1cken +19071987 +251083 +jetta +angel45 +hotboy12 +aguila1 +cereal +shortstop +brazil10 +sports123 +marusia +moogle +wsx123456 +kacenka +h97e7ijwwb +lionlion +busdriver +wsxzaq +primetime1 +boston11 +volkan +pam +28021992 +110884 +240386 +babyboy07 +asdfasdfasdf +christian1 +dance13 +onetreehill +130290 +010590 +280800 +010389 +12041992 +marinella +alex89 +130485 +miami3 +swapnil +180886 +matt14 +dragonlord +cap +nokian +1906 +peanut21 +a123 +021188 +17101991 +alligator1 +lopas123 +smooches +180887 +arshad +pete123 +11101986 +moi123 +sassy01 +281087 +21101987 +230591 +temporary1 +whiplash +11051988 +iloveyou26 +131287 +18031988 +riverrat +25111986 +yahooo1 +cowboys#1 +shakes +197811 +pointblank +250691 +#1girl +marinela +110791 +samdog +cherry01 +03031989 +ania +jessie13 +semenova +04041987 +versus +311087 +091190 +thelove +311085 +flawless1 ++ +12011985 +231284 +thuglife2 +andrew02 +5236 +300587 +zxczxc123 +chaussette +220983 +mitchel +austin05 +pink20 +240390 +270689 +dakine +rashida +sasori +elizabeth +indica +110883 +justin25 +cintia +a0000000 +16101991 +gareth1 +20081985 +swagga1 +140887 +manda +gatito1 +wally123 +200687 +hannah. +puerto +yuanyuan +26121990 +pamelita +salam123 +thedoctor +180986 +spence +crkurrp954 +john16 +diamond23 +bobafett1 +adonis1 +a7654321 +120992 +747747 +isabell1 +24121990 +181191 +18121986 +22101986 +10qpalzm +love43 +jennifer22 +google! +181090 +rocket12 +246135 +13021991 +250583 +sambuca +marriott +201185 +mashamasha +tommy3 +160786 +pacino +junior24 +freedom69 +biologie +e3w2q1 +12111986 +fucku22 +cunningham +primax +rush +lacika +acting +31031987 +15071986 +alex93 +lalakers1 +azerty31 +14101986 +madison9 +podolski +200188 +alex2004 +11241124 +vipers1 +december +b33m6yghef +131183 +210485 +dmb2010 +jackson +salma +connections +270589 +16101990 +holas +mathys +potter12 +060685 +love4god +hiphop101 +080989 +cheese101 +12061985 +pro123 +victor10 +zaq1@wsx +22031984 +hornet1 +anthony05 +lbyfvj +nicole26 +puerto1 +12021989 +alex1988 +sanjuan1 +honey13 +04041985 +13061991 +martusia +password@123 +cinta1 +random12 +leanna1 +200485 +02101986 +200886 +mexico18 +intel123 +a1b2c3d4e5f6 +morpheus1 +motors +aekara21 +121180 +2111 +07071990 +soylamejor +halley +heaven77 +j654321 +wsydcig761 +140187 +26061987 +wordlife1 +tilly123 +11051989 +cassie13 +sprinkles +20011987 +21071987 +21101988 +ca +181289 +271290 +heidelberg +lildee1 +secret69 +231191 +150285 +exeter +friendz +260485 +fakegirl1 +monkey45 +600000 +251184 +ratchet1 +moonpie +parker2 +198326 +deportivo +cowboys10 +gabe +cosmos1 +amirah +ian +ethan01 +200592 +nikki11 +skittle1 +07071977 +queeny +london +15051989 +cement +kinglove5 +tigger6 +muscle1 +1305 +miley101 +william. +230685 +andrea23 +submit +050591 +badazz +paramount +diank123 +babyphat12 +pinky7 +charter1 +kolibri +climber +heyman +05071986 +27121989 +ryder1 +alexis03 +gattino +cherry101 +nigel +skate7 +batman99 +thomas06 +bigbang1 +24041990 +24121986 +200885 +160687 +citibank +veronica2 +hotlips1 +anthony19 +omomom +mylove +way2cool +rainman1 +reyna1 +maggot666 +sunshine33 +danica1 +12roses +bogart1 +hanswurst +terence1 +festina +loveme101 +kalender +saranghae +blair1 +230886 +24051988 +brandon. +espiritu +yamaha12 +cvtifhbrb +cassie3 +mcabdaw2vx +e6fc37 +sherif +rudy123 +lordgod +archibald +121977 +22111986 +170989 +strannik +pakistan +novita +16111987 +212 +111181 +yahoocom +chulo1 +16121991 +291085 +laughing +fairway +280585 +merrill +cascada +1qazxcv +baby28 +130393 +koalas +barbie10 +lisa11 +blanket +scamper1 +250285 +120479 +14121991 +boston34 +austin98 +12051991 +25101986 +kittens2 +chatting +heyhey2 +290590 +311290 +momma2 +19021990 +230392 +walters +02011986 +ladder +31101991 +hunter15 +baseball06 +fakename1 +griselda +sallie +191088 +24061986 +dominic2 +1234567aa +14021984 +dell11 +010489 +math123 +< +chichi12 +matvei +ferrer +snyder +julian01 +hilfiger +aggie1 +brat +21081987 +landlord +catdaddy +frankie +edward23 +thienthan +thisisme1 +newhope +flygirl1 +12051985 +020490 +elvira1 +280390 +motley1 +iloveyou28 +aa123456789 +200484 +030589 +daniel04 +olivia10 +yashar +hummerh3 +ab69432 +redblue +210288 +ericsson1 +denny1 +purchase +140209 +130892 +wwwaaabbb +barcelona9 +marianita +mireya +dashawn1 +sherbert +21232123 +danny3 +myspace34 +thomas6 +strawberry1 +misiaczek1 +kalleanka +strike3 +pimousse +150685 +sister3 +ovidiu +xm55xexbzs +19111987 +02071985 +holeinone +yusuke +mohammad1 +cherry6 +271285 +lorenita +blind +160788 +23041991 +250684 +300689 +obsidian +luck +solotime +hendra +buster08 +gogirl1 +fashion123 +michelle123 +marquise1 +godis#1 +gremlins +barcelona7 +ghtktcnm +02021980 +prinsesa +030890 +phoenix123 +koolkid +manuel2 +221283 +geheim1 +04061991 +wysiwyg +avatar12 +golova +undead1 +asmara +victoria11 +jaime123 +navajo +02071984 +chivas23 +yankee13 +17891789 +mafia123 +224455 +netgear +ljubav +1230321 +kyle1234 +mehdi +d54p7xjkha +20031988 +thomas. +21021987 +horses3 +17041986 +iskander +flakes +mason2 +teamo15 +02091988 +sas123 +130391 +180685 +300585 +misael +cruise1 +sammys +treehouse1 +141090 +halloo +230883 +stefano1 +brenda2 +197474 +gwendoline +glory2god +171289 +xoxoxo1 +monster10 +30061988 +beautiful8 +karlitos +14101989 +25121988 +t5r4e3w2q1 +ifeoluwa +fische +281089 +pre +chyna1 +duckies +love2005 +crips13 +22021985 +baikal +01021989 +17101990 +130386 +washere +wilson2 +polina +caramail +201284 +010689 +shutup! +sahara1 +killa3 +141182 +okok +fremont +109876 +310890 +bottle1 +cool12345 +lokito +11031988 +stop123 +jakedog +deneme +deepali +nuts +061089 +14031990 +170490 +summer15 +armystrong +151186 +25091987 +10101981 +4mutdfgvtp +22081990 +dork123 +thebitch1 +14121990 +a1a2a3a4a5a6 +yolande +vecmrf +130785 +101214 +olamide1 +ranjana +nana10 +236236 +playtime1 +bettyboo1 +200891 +whores +0987654321a +101980 +230191 +whitetail1 +heyy +10071986 +takethat +270490 +molly10 +fluffy +adidas2 +200387 +kickme +duckman +black15 +26031991 +290190 +babygirl05 +151282 +mutabor +12081992 +250595 +me&you +1edward +jeter1 +17111987 +marchelle27 +1505 +cinthia +101989 +10031990 +superjunior +nick21 +sugarplum1 +ugly +deedee12 +trabant +charter +azalea +taylor02 +100683 +258369147 +cvb123 +060691 +ipodnano +cheers1 +carnation +123111 +040690 +justin101 +cakes1 +aa123456789 +rodrigo123 +lovely4 +blood23 +heaven01 +ytpyf. +rockey1 +tophat +taylor18 +220884 +davenport +p00pie +170888 +woodman +190990 +sniper123 +310591 +avenue +ww123456 +131291 +likeme +19101988 +freaky69 +18101987 +mexico22 +8uxzd1b3bd +76543210 +wartune +lostlove1 +roberto123 +aosamples +110783 +soccer89 +160189 +210584 +14051991 +hello90 +010687 +will12 +cellphone2 +revathi +abby11 +oldskool +170984 +1512 +whatever13 +21091990 +pooky +15121990 +191289 +superstar7 +100583 +versailles +241281 +waterart +230791 +newports +hyundai1 +bismillah +16021987 +flight1 +samuel10 +banane1 +183461 +5t4r3e2w1q +lisa01 +fenster +bagheera +1709 +harrypotter1 +hamza123 +soroka +ayanna1 +moving +2sweet4u +dickies1 +02021992 +4music +15111988 +bloodz5 +14061989 +250784 +monamona +magister +12345. +hector123 +230584 +final1 +221191 +311284 +44556677 +guido1 +280489 +w1961a +macika +123456ll +100383 +cocopops +sexman +joseantonio +football53 +10011988 +rosco +blueskies +123123abc +031288 +20101990 +100284 +imfree +daddy08 +crafty +my2angels +scout123 +bball34 +iloveeric1 +robert17 +4567891 +12345676 +polkadot +280590 +fhntvbq +tiburon1 +99 +netball1 +mommyof4 +301186 +natasha2 +270785 +170487 +screamer +joshua24 +14111986 +500001 +hotrod69 +crazy01 +sunflower7 +krasavica +02101985 +mason12 +15081988 +bubbles10 +kierra +ilovelife1 +zanoza +a123456789a +fuckthis! +220291 +rickjames +12456 +james25 +mimi1234 +02021991 +tobiloba +14101984 +bobdole1 +slipper +rebecca1 +101982 +pooh23 +smiler +loser10 +gabby2 +ahmet +343536 +footbal +cabinet +sonne1 +12354 +140786 +changed1 +100283 +manowar1 +11031983 +neversaynever +100184 +football0 +220491 +240190 +proview1 +moose2 +19021987 +j8675309 +costanza +jonathan01 +qwertyu7 +survival +darkness12 +cutiepie3 +wwwaaabbb + +22051986 +251282 +22061990 +magomed +200590 +251987 +699669 +plane +nanette +123alex +22101985 +19481948 +steven10 +marmelad +34567890 +kazeem +280486 +210290 +court +23101986 +09091986 +s3cr3t +q12we34r +15101988 +rfnhby +13101989 +muffin! +laranja +shi +4wdaxq642f +12101984 +kusanagi +tinker3 +ilovedanny +110067 +cstrike +r12345678 +toejam +ballerina1 +bergkamp10 +devonte1 +250985 +baghdad +lieben +engel +mendes +hellos1 +151185 +monkey02 +210387 +beluga +anilkumar +210691 +160988 +millie12 +1234q +cuisine +bears123 +vfhcbr +babylove2 +freelance +macdonald +delores1 +okocha +15101991 +onetwo34 +12091987 +followme +humility +rfcgth +pieman +insert1 +naruto6 +daydreamer +tempo +hernandez2 +maine +dan1el +sexiest +delete2 +11111111q +doggie2 +rivers1 +charlie14 +02091987 +gandalf +jesus6 +asaasa +famous12 +12345 +john117 +shadow0 +24101989 +22011987 +george! +marcel +hockey44 +031086 +051287 +iphone4 +6969696969 +tony21 +3uc9xn53xh +jesus2009 +ilovemum +kaliber44 +3rdward +leila1 +love84 +240786 +cometa +ashash +saddie +pass2word +21011988 +12101991 +gunit123 +soccer93 +pimpin11 +wan0425 +hamburg +110483 +19121988 +andreev +philadelphia +right +cool15 +marine +gosia +limone +insurance1 +jesus777 +230385 +boris123 +prosper1 +ginger4 +june01 +nicole87 +bsxxbgs322 +twitch +cobra11 +pocholo +saab900 +10121983 +bootycall +chris12345 +zachary3 +5213344 +job4me +241183 +tweety09 +20091985 +jack21 +uqa9ebw445 +wutangclan +florida7 +scooby7 +260990 +dallas10 +sayang +13101992 +100384 +baberuth +bebo123 +tobias +021087 +rocket123 +chance11 +hairball +matrix11 +isabel123 +140685 +198524 +fabiano +mastercard +pizzapie +technical +shay +puffetta +261085 +salomon1 +4horsemen +11011986 +cannavaro +nnamdi +31121985 +nicole94 +fanatic +hedgehog1 +170683 +salaam +130786 +teixeira +1victoria +flower8 +prunelle +music21 +rodolfo1 +270489 +gtnhjd +gangsta4 +blackwidow +110020 +18051988 +lakers3 +nike90 +parkour1 +ansari +windows +22021987 +laurette +cooper3 +session +bubblez1 +kompages4u +mojito +19041990 +bommel +vanessa3 +120481 +c12345678 +carlos1234 +shaquille +jesus17 +030386 +computer10 +godloves +sexy00 +chouchou1 +denise01 +hailee +happy2008 +mcgrady +emily10 +25111987 +bob111 +231192 +overlord1 +12041204 +skunk +020586 +lavalamp1 +maryjane13 +johanne +papasito +babygirl92 +fubar +831012 +hothothot +collette +02051985 +520 +46494649 +twenty3 +quake +24031990 +marko1 +sexythang1 +luv2dance +house12 +sexyboy12 +01081985 +wilmer +ramone +steven69 +26031987 +babygurl21 +vanessa7 +compaq11 +babouche +oakwood +1cheater +natas666 +020589 +joemama1 +ignacio1 +zero1234 +star45 +tigger88 +peace5 +sexsexsex1 +130383 +34567 +victoria1 +281191 +kt +banana69 +vivi +monique123 +muttley +triple3 +10081990 +080885 +din +cretin +171087 +geordie +195 +taliban +bobert +loop +25262526 +ferguson1 +bernhard +232323a +panchita +masaya +sheffield1 +anggandako +catfood +180686 +061289 +bridgette1 +live4god +frogfrog +dothedew +justindrew +sept23 +daytek +15121985 +21021989 +23111988 +hottie17 +1407 +marie8 +puteri +lunatica +river123 +131282 +jimmy11 +160190 +cassie +jkmuf +qaz321 +godisone +nikolaeva +kerouac +111qqq111 +vfylfhbyrf +mickey6 +azqswx +deedee123 +22111987 +310587 +301187 +halamadrid +cherry10 +11071985 +01041990 +21061991 +131084 +sfgiants +161289 +neverever +130291 +emo101 +annushka +290589 +william21 +bengal +q123456q +kenya +phoenix1 +layla123 +skidoo1 +141185 +junior06 +elijah01 +brothers2 +iloveyou2 +10061991 +200490 +lesbians +humberto1 +hitman123 +021187 +briggs +161088 +heartbroken +zapper +a:sldkfj +22091987 +130582 +geo123 +12111990 +lilangel1 +jakob1 +fuck01 +ilikeu123 +jeremy13 +99998888 +malatya +iloveweed1 +alex2003 +kam +andrea7 +heslo123 +kombat +qwerttrewq +audirs4 +sunshine17 +moneybags +210384 +25101984 +miamiheat1 +clowns1 +ovechkin8 +helpme! +necromancer +19081988 +imsocool +26061986 +buster23 +jd1234 +never123 +shaman1 +20111987 +170489 +20061990 +dogface1 +wayne12 +03031991 +key123 +boiler +200889 +octavian +loulou +cualquiera +patryk1 +awesome11 +nightwolf +cocopuff1 +anh123 +050790 +maksimus +scorpio11 +jasmine21 +marie24 +yousef +cayden1 +simple12 +mexico! +tony10 +adam13 +only1love +what3v3r +farrell +sherri1 +020690 +anyone +23011990 +24041987 +thequeen +0102 +hangar18 +110095 +liverpool10 +120578 +110284 +banana13 +15081989 +650829yjm +26051987 +vef6g55frz +jake23 +traffic1 +william07 +130691 +24081988 +rockstar21 +17071985 +luis23 +17101988 +pentagram +discover1 +31121991 +17041987 +10111989 +wannabe1 +100292 +95368452 +recruit +halloween2 +310786 +everton123 +010787 +doggydog +blobby +family9 +01011971 +manger +benjamin +jianfei000 +sam101 +fedorov +anselmo +monster9 +jaylin +130285 +250389 +kitty14 +tunder +marjan +220387 +ilovejesse +trash1 +william69 +peanut6 +13021989 +20101985 +rachel3 +291286 +jerry12 +yellow25 +selena12 +151084 +swinger1 +kelli +vf +1bunny +230286 +piggie +hotness +02081990 +texans +18091987 +250385 +louise01 +paoletta +amazon1 +lina123 +allstars1 +natividad +lyndsey +igor123 +ladder49 +bball7 +babycake +220490 +23031985 +20121983 +sunil +blessed +breizh +railroad1 +advantage +phish1 +outcast +bubbles. +ar +130783 +23071991 +121275 +251087 +kingtut +cinco5 +mullet1 +maxim1935 +101180 +14091990 +ray619 +ethan12 +120881 +1cupcake +170889 +sistema +260587 +jamal123 +020485 +300486 +greetings +bhavana +26031990 +050989 +mahalqoh +197812 +janet123 +235235 +koffie +job123 +310187 +maverik +smile101 +198920 +winners1 +kensington +29662012 +1cameron +lakers10 +hotstuff2 +evan123 +02041985 +bronco2 +christia +46464646 +18041990 +eagles21 +florida1 +sandia +a131313 +bebe11 +19091989 +270289 +durban +21021990 +melissa22 +arashi +thomas88 +assword1 +andy13 +110120119 +longman +101279 +13041990 +poptarts1 +nelson12 +120981 +marius1 +24061987 +barbie! +198819 +jimmy69 +11101985 +bolita +warwar +pedro12 +miller +bear22 +ily4ever +paulo123 +supper +221092 +diego12 +copeland +sierra2 +andrew1234 +nas +paisley1 +buckaroo +qwasqwas +160885 +vampire2 +solnyshko +100592 +180688 +camper1 +nicol +29071986 +porky1 +pamela123 +17101989 +jasmine16 +daddy21 +19081991 +kissme11 +230384 +forlife +schlumpf +280884 +georgi +1muffin +vierge +ginger +310788 +21051988 +010585 +051188 +safeway +19091991 +joseph14 +20031992 +01051986 +24101990 +leonardo +charger69 +040486 +ruthless1 +291087 +schlange +smokeweed4 +hotpants +spi +volvo240 +nathan21 +zackery +13111986 +852000 +151091 +jaxson +ronaldo09 +020285 +281085 +16031987 +mybaby12 +pooh22 +irina1 +jackson6 +babe11 +260888 +purple27 +ghjkju +meister1 +11091990 +porn123 +021085 +001976 +maestra +cheeto +7894 +021021 +04051990 +198323 +01031984 +21111986 +internatio +fuckass1 +seether +qwerty1234567 +paquita +steven! +291086 +jerrylee +23101992 +30031990 +rock69 +010890 +cleaning +2103 +hunter24 +itdxtyrj +marauder +amstel +country2 +180890 +terri +700019 +router +godofwar3 +i84avh9lti +nikolaj +knoxville +lotlot +scorpion +280887 +15041990 +211282 +ozzie +demon13 +14121985 +balder +quasar +jasmine22 +constanza +000008 +halflife1 +hotmomma1 +fucker11 +link12 +moonstone +monika +01031987 +141184 +blank1 +kingkong12 +051190 +tobytoby +panhead +why +wasser1 +megapolis +rutgers +drummer2 +bitch25 +mymoney1 +110030 +zoom +110185 +++ +city +20132013 +februari +030686 +concord1 +02051984 +280280 +lakota1 +jessica88 +conejito +260385 +leandra +skater! +77889900 +booboo9 +201011 +invader +freakout +22121991 +simba12 +400051 +ala +87878787 +210591 +fakeone1 +trident1 +genesis2 +nicole92 +destiny07 +301185 +18051987 +301189 +cheaters1 +chachi1 +benzema +89216279708a +310790 +19121989 +dolphin +28061991 +candida +123456789u +newday1 +heyman1 +sabine1 +spiderpig1 +myboys1 +24031987 +nadine +test123 +21051990 +231988 +liam123 +1honey +250591 +120780 +040590 +boosie +sarasota +tennis +mustang10 +avocado +220383 +taylor05 +09091985 +steph2 +160289 +sapito +clutch +lolypop +22101988 +241289 +grandson1 +1231231234 +grinder +dev +angela11 +170990 +48484848 +monica11 +10041992 +mayaki +fairlane +peace4 +15021989 +180389 +abcdefghijk +hansel +sharon123 +king08 +iluvmlml +123478 +partyboy1 +peewee12 +daniela +javelin +joseph15 +290188 +ari123 +jonathan5 +grundig +david12345 +dreamz +musik1 +mustang04 +31051991 +12345678909 +120492 +rohit +maple +27041988 +14091987 +but +babygurl5 +22011991 +05061989 +poohpooh1 +passwerd1 +stacie1 +25061985 +11121988 +slipknot8 +stubby1 +madison04 +bones123 +123456789q +lilmike1 +highway1 +stefan123 +fdfnfh +maksim +zxc321 +25091986 +963210 +bitches12 +310188 +chewie1 +mamata +babygurl69 +gamecock +amanda07 +everlast1 +margret +03031992 +bobb +110593 +madden10 +25081994 +sandi +17061986 +sleep +jukebox +biagio +dance5 +100392 +anna2010 +150983 +22051989 +balling1 +050688 +261284 +dolphin5 +logitech12 +123!@# +taison +hello321 +johnny69 +201002 +02091986 +200189 +monday01 +paredes +4given +02081985 +30061986 +p51mustang +passpass1 +130889 +loveone1 +cheyenne2 +jason10 +010289 +thomas17 +20041985 +orange14 +1232 +141286 +badboy7 +chill1 +sabres1 +090690 +29041991 +15111986 +deeznutz1 +10021992 +21041989 +3110 +gringo1 +arunkumar +killing1 +150884 +130884 +22041992 +michelle07 +lucinda1 +11021986 +000002 +3qvn5k4qgv +bball25 +130484 +imhot1 +cachito +030590 +171183 +yankees22 +speedy2 +11091985 +be +200790 +passera +060692 +25011991 +a999999 +burner +snuffles +parisien +160287 +luvyou +7fxf3jba8t +cristopher +13111985 +celinedion +4myself +198626 +banks1 +111123 +lizeth +lovekoto +171190 +beautiful0 +oscar3 +longer +skittles! +nortex4 +ms1234 +12041985 +silverstar +tadpole1 +15081991 +22081991 +charlote +170287 +060990 +robert07 +spurs123 +198624 +140284 +18101985 +270290 +151182 +25081988 +doitnow +wes +robert09 +251283 +mirian +230884 +pokemon6 +whatisit +nicholas11 +lkj65b6666 +260692 +211090 +jobsearch1 +020990 +number1mom +looker +research1 +yoyoma +mommy8 +cingular +iuliana +shitshit1 +rocket88 +harley5 +300990 +prescott +paranoid1 +creeper1 +23071985 +24041985 +clint1 +080891 +111091 +patrick8 +lobo +glover +kabal +326326 +nineteen19 +220683 +020486 +figaro1 +15091989 +oreo1234 +240991 +eight888 +400016 +pumpkin7 +bimbim +mariangela +28081990 +01061989 +25061991 +20081986 +gemini13 +fuck10 +ramsey1 +panthers12 +fivekids +230186 +2208 +26021990 +steelers +10031986 +110393 +kingkong2 +29041987 +01031985 +12091986 +kitkat12 +110052 +acoustic +barbie01 +testament +240189 +123123r +amanda24 +viceroy +100784 +findajob +charlie06 +20041986 +19071990 +northwest +rawr +punkass1 +13011989 +problem +guiness1 +526282 +060687 +sveta123 +montse +100680 +nutty1 +capecod1 +nikeair1 +penpen +03111987 +jennifer4 +10071990 +aloha123 +roosters1 +1408 +wwwww1 +19051986 +10061992 +fiammalex1@hotmail.it +23021991 +13031986 +theiigd4x2 +021287 +rocky22 +1066 +15121984 +nononono +01081990 +alex96 +copper2 +210286 +not_needed +djdxbr +hottie. +23061988 +170583 +frontera +juggalo17 +02081987 +alexis99 +willsmith1 +cazador +alex27 +241287 +10311031 +10111985 +ipswich1 +24101991 +cabrio +octavia1 +24061988 +rfhfvtkm +010490 +anna01 +woman1 +010587 +silver69 +27071991 +190688 +11011989 +josecarlos +hate12 +takashi +lover8 +banking +gracie11 +23051986 +152207 +shante1 +texas5 +22031989 +fluffy11 +30121987 +11111qqqqq +01061986 +br549 +antani +20051989 +25041988 +skinhead1 +cheer14 +21121986 +word123 +140189 +academy1 +hibernian +katarina1 +vicki +ipodnano1 +holybible +t12345678 +padrino +natalie7 +john18 +rabbits1 +amorsito +22091988 +happy9 +141284 +greenpeace +15061988 +rug +left4dead2 +8562835 +steven21 +23051989 +sithlord1 +18061987 +290587 +love#1 +mike06 +sully1 +010290 +mike20 +school01 +rocawear +mandeep +sweetp +190388 +sugipula +lkjlkj +sister12 +xcvbnm + +amyamy +playbill +donut1 +25041991 +dawn123 +04051987 +fgjrfkbgcbc +tangkay +27071987 +33445566 +nascar12 +290585 +240784 +howard12 +hammond1 +heaven777 +116116 +saxon +11061992 +belette +bubbles69 +melissa! +katerinka +talita +cammello +urgay1 +thesaint +baboy +lithium1 +15121982 +steve12 +121994 +xep624 +26011990 +lovinglife +280288 +andreina +walter123 +spiders1 +danni1 +steelhead +green45 +20011989 +snoopy69 +dragonforce +040487 +wildcard +01051985 +haleigh +am1234 +1234456 +amisha +26041991 +playboy11 +intelligent +01091985 +10091986 +lola11 +alexis! +240286 +bam +totally +eagles08 +sincity1 +198444 +rocklee +22101990 +7410852 +pussy01 +motown +19121987 +real123 +chestnut1 +130284 +14061991 +nodoubt1 +++ +ronny +osprey +311282 +alexandro +bunny11 +140386 +260387 +jumbo +080690 +eyeball1 +painless +angel97 +170190 +ciprian +trevor12 +drpepper12 +julian2 +20091987 +nepal123 +020986 +marta123 +ethan2 +irish123 +280386 +240785 +setter +280290 +21071986 +280890 +charles7 +197666 +140387 +13041991 +20021988 +dickface +jacobblack +123456- +ilovejon +nasa +11061985 +haggard +corazones +tiger88 +dora +dionisio +teens +ilovejose1 +youth1 +30041987 +230984 +alexis21 +thug +swansea1 +regent +18091985 +blake12 +191087 +cad +12091988 +him123 +030789 +scooter11 +pratik +15121988 +tess +venice1 +jada123 +josh10 +111085 +9inchnails +24121989 +canarias +08522580 +topogigio +curly +chairs +pocitac +hardcore! +boobies123 +eastwood1 +maxwell123 +maddie11 +aero87 +sandra13 +nightshade +mayhem1 +shockwave +fordtruck1 +chris33 +lala10 +14071986 +a232323 +belldandy +31 +963963963 +110681 +13011988 +01091986 +steven23 +hailey12 +codegeass +material +anointed +552255 +berkut +hailey123 +090390 +alaina1 +wasd1234 +vfhbif +tellme +pretty! +beast12 +nnnnn +mamaliga +yc6abqsfjo +laugh1 +18101986 +alino4ka +140983 +05061990 +lala23 +cardiff1 +29091987 +mexico4 +vendredi +littlefoot +newport2 +19051993 +041 +dam +mother7 +mushrooms +marble1 +bingbong +16021989 +21041990 +madison! +770880 +10071989 +marmite1 +150490 +towers +pikachu123 +vfrfhjys +orlando +01041983 +budlight2 +james12345 +19001900 +paris11 +unlimited1 +050888 +alvarito +arlette +vaughan +19051991 +gabika +19933991 +catcher1 +051088 +rjdfktyrj +loveislove +ravi123 +30031991 +11031993 +11201120 +laverne +fucklove69 +mousepad +210885 +melo123 +230683 +brian13 +150891 +cavaliers +rockon2 +lastochka +sunnyside +wyoming1 +haircut +30101986 +160986 +jayanthi +jablay +cottoncandy +271828 +greta1 +210888 +alex1985 +ammananna +fishy123 +chilly1 +5.254.105.20:test +quilter +160387 +giallo +12011990 +kruger +501501 +180788 +270189 +rainyday +04041984 +orange69 +16121989 +ilovejay +22031988 +dakota7 +ritika +bereza +jarule1 +frieda +cd123456 +thomas16 +sc00byd00 +dimanche +wiggle +556644 +connor11 +281186 +7777777q +060684 +gizzy1 +america. +mothermary +hunt +25962596 +150291 +teddybear3 +121993 +hellohi +jordans +vjzctvmz +smitha +02101984 +14121992 +betsy +070784 +mylove! +magneto +110983 +wwe +badboyz +death69 +рїр°сђрѕр»сњ +sterne +dylan13 +852741963 +mariee +220790 +thechosen1 +blood14 +111283 +samsamsam +08081991 +211185 +heyhey12 +dev123 +131182 +plumbing +171284 +loquita +imissyou2 +brianna4 +angel87 +21051986 +travis01 +aisyah +marissa2 +sunshine16 +tandem +iloveyou93 +sassy7 +lauren5 +12071992 +obsession +partygirl +ciaociao1 +201082 +kimmy123 +23isback +26101989 +sayuri +261287 +zse45rdx +terrible1 +davidvilla +251192 +yflt:lf +180585 +punk13 +catnip1 +junior69 +begood +player14 +ronaldo +amanda08 +ilovekim +150384 +20061985 +password11 +mandolin +040491 +17121988 +coolio123 +starwars6 +macbook1 +12081985 +fro +indianalib +270386 +geronto +windows2 +babygirl89 +iphone1 +041188 +jeffgordon +23081991 +150783 +rain123 +888888a +theclash +sage +30051989 +engine1 +time2go +magenta1 +15031989 +tinky1 +tigran +cashflow1 +samuraix +231291 +1w2w3w +hello88 +adidas10 +alfons +admin +170885 +dentist1 +091091 +sweetthing +frankies +vfrcbr +11021102 +bundy1 +snoopy10 +29091988 +yassin +fernan +nermal +beto123 +graduation +rosalind +dreamboy +11081992 +123money +mydreams +051089 +cordova +werthrf +gangsta! +170185 +miranda123 +karachi1 +cindy12 +block1 +09091988 +maria1234 +111100 +23031989 +canario +84268426 +king55 +therion +honeypot +turbo2 +23011991 +26101988 +02071991 +151284 +16121988 +flyhigh +aeiou1 +dashboard +thunderbolt +gillette +jamiroquai +lucky08 +171185 +dexter +matthew06 +17041991 +sergio12 +moss18 +560040 +560094 +farah +grisou +piper123 +adi123 +mattman +17051991 +dogbone +lotion +trx450r +220682 +nicole93 +killerbee +rachel7 +snookie1 +291290 +junior17 +ravikumar +callme1 +renault1 +nicole02 +anamaria1 +eveline +kiko123 +hannah00 +katiebug1 +yukon1 +brandy11 +blue00 +280686 +85200258 +27041990 +elijah123 +031285 +zoe +belly1 +afroman +newark +lilmomma1 +megan13 +010487 +worinima +300586 +11041989 +batman09 +mustang02 +a1314520 +redsox13 +lolpop +150684 +richard5 +zkl858 +alma +thekillers +210982 +suzie1 +01101991 +ginger69 +redneck12 +20031984 +0110 +tacos +blazedup42 +belochka +15071991 +1puppy +welldone +love&hate +rick123 +len +martina +lickme2 +250984 +29041992 +cobra427 +canada11 +10081988 +audis4 +kwiatuszek +kai123 +230887 +charito +abogado +babby1 +howie1 +5t6y7u +fatina +nascar2 +chinadoll1 +lander +1404 +life101 +100391 +ivette +marvelous +281086 +030690 +jorge12 +170491 +hunter101 +whores1 +061285 +jerson +600600 +23041992 +danny22 +2305 +hydro1 +vanessa11 +hotgirl2 +escobar1 +sweetypie1 +r123098 +nascimento +cobra123 +ciaran +switzerland +gusgus1 +ballin11 +200385 +katze +girls12 +31121992 +131284 +xavier01 +jose18 +florida3 +141083 +success2 +27101989 +winslow +270986 +athlon64 +orologio +30041985 +++++++ +011088 +11121112 +dustin123 +harhar +nala +hockey20 +ciccina +april09 +adgjmptw +omolara +victoria10 +23031993 +outlook +topcat1 +1302 +280989 +andrey123 +16081991 +1power +cohiba +rockme +nicole00 +290389 +danny5 +020487 +11111984 +geoffrey1 +131082 +luckie1 +110032 +komando +lovechild +youyou1 +15021988 +sushi123 +weedweed +abudfv +14121986 +iloveyou92 +homo123 +bitch33 +fuckher +17021987 +09091991 +kikker +fabio123 +babygirl26 +nan +number20 +11031989 +150885 +music4ever +23041990 +hjlbyf +inlove! +22081987 +maranda1 +kiskis +starwars +27101986 +pawelek +2411 +sammy21 +260889 +budget +bubby +89mustang +wolf13 +pakistan1 +samson01 +joann1 +230491 +xswqaz +killme2 +220891 +austin9 +urmila +tia123 +qpwoei +27061988 +happyy +chess1 +14231423 +321abc +30051985 +honda3 +thunder11 +7894561231 +micheline +butterfly. +vovchik +sexme1 +123456xx +berliner +061088 +pokhara +pookie13 +31011990 +dylan3 +qy5togr996 +dec +18071991 +bearcats1 +17051987 +chrystal +220190 +15051984 +hoebag1 +coquine +pooh15 +123-123 +rustem +22021992 +madera +010486 +paulie1 +limpopo +210583 +nosey1 +shanta +bohemia +murmur +06061991 +love1986 +caribe +forbes +romeo12 +orange88 +flower. +princess32 +zxczxc1 +12091990 +barney2 +00001 +kusuma +yankees21 +iloveyouma +qwert123456 +green08 +210991 +namita +riddick1 +220883 +160485 +libertad1 +3yixda15hr +periwinkle +cjrjkjdf +typewriter +canton +kyle13 +glenwood +airmax +010786 +180789 +110014 +24071987 +underwood +192021 +300986 +sandydog +130681 +devil6 +looking4u +sister123 +1598753a +031188 +morrow +231280 +050584 +yfafyz +cowboy11 +111291 +chivas3 +19960309 +22011992 +mansfield +29101991 +04051988 +simonsays +disney2 +soeusei +superhero1 +16061992 +mumtaz +ranger99 +a111111111 +pig +181288 +7474 +22121990 +15031985 +191185 +2929 +moody1 +javiera +20101992 +199019 +buster14 +24041992 +23061991 +jonah +shark123 +291186 +15031987 +bonsoir +13101990 +master00 +26121988 +18101991 +10091987 +helpme12 +eminem. +220984 +chacho +guyguy +210491 +escorpion1 +22101984 +17101986 +hhhhh1 +cracker2 +051185 +dd1234 +roxy01 +13091988 +23091987 +golfnut +30031987 +w1992a +jitterbug +gheorghe +11101990 +slbenfica +z28camaro +jejeje +gamefreak +dumb +gblfhfc +hotmomma +yniqnmk733 +master88 +25041990 +raven13 +020585 +12365 +a2345678 +zaza123 +chivas101 +susanita +watashi +hollywood3 +shawnee1 +20101991 +ground +tennis01 +mouloudia +chris99 +01081984 +lauren21 +emilka +198810 +stamps +report +missyou1 +2508 +limewire1 +rohan +daniel02 +291185 +cascades +topaz +110881 +libras +haha22 +01051990 +people11 +hereiam +cherry15 +rajasthan +babygirl94 +rainier +rapido +bestrong +01051987 +pimpin21 +gunter +210391 +pretty10 +animal2 +blueman +24051991 +160187 +poohbear4 +bailey4 +10041985 +200388 +devdas +ytyfdb +180387 +winter00 +caliber +wizzard +troubles +hunter88 +palace1 +cortney1 +frontline +toby11 +210181 +shrek1 +159951159 +jackiechan +batman14 +121093 +jesuscrist +mythology +asteroid +dreamgirl1 +240982 +fatality +160790 +120381 +241284 +ozzy666 +250186 +150584 +1415926 +duffy +159753456852 +damaris1 +150591 +coco01 +ateneo +250592 +mariana123 +251180 +190690 +kierra1 +ms123456 +140783 +134134 +dallas5 +281283 +hamster2 +31031988 +281182 +bubbles21 +amador +jer +superman77 +stellar1 +success7 +151085 +finalfantasy7 +budman1 +22051988 +123124 +fosters1 +parker01 +kfylsi +peggysue +reeree +qwertyu +toast +luis11 +240185 +301289 +natation +180188 +lucylou +samantha4 +benedikt +angels5 +kissass1 +02081991 +asdfghjkl:' +backup +ou8124me +14081988 +fake101 +amber7 +dickdick +180190 +a2a2a2 +220691 +sept22 +280490 +amanda6 +190188 +7so2ekbc6r +ramadhan +ham123 +ihatethis1 +personnel +luminita +231080 +bramble1 +stepanova +oliveoil +nora +pelon13 +megan01 +02021993 +raymond123 +2504 +15081986 +23121985 +280487 +310785 +comrade +dating1 +cbrown1 +florina +carousel +chico12 +03061988 +hacking +300785 +ryan15 +181085 +imtheman1 +jenny01 +ghjnjrjk +161091 +orange +zoolander +14041986 +yoshi123 +290486 +12fuckyou +mercedez +three333 +welcome5 +elias123 +araceli1 +narut0 +20000 +dreaming1 +nessa +26021988 +kumasi +140687 +justin00 +lbvekz +.kzirf +fuckin1 +150187 +12041984 +nigger11 +jesusteamo +norfolk +25051991 +joejonas12 +beautiful9 +19121990 +makayla2 +141091 +13031989 +28121988 +booboo4 +nathan4 +fatgirl +130583 +diamond22 +overdose +290185 +bitch99 +samantha14 +123456ty +kelly7 +olaniyi +8inches +soccer34 +ownage1 +mocha123 +school9 +28021985 +30101985 +freenet +291289 +02011987 +specialized +kaylie1 +1243 +garten +chivas5 +changed +250484 +02021983 +109109 +nuggets15 +killzone2 +2304 +useless +sokolik +miller31 +707707 +170689 +fresh23 +12061992 +foofighters +230284 +busayo +loveth +02071983 +121193 +180489 +happy77 +codmw2 +444444444 +100293 +strekoza +220985 +putri +110495 +henrietta +jenny7 +23031988 +jake14 +summer88 +sal123 +rufus123 +18031987 +191286 +030685 +gjgjdf +taylor17 +rylee1 +field +chuckles1 +mychemical +020284 +amor15 +24041989 +31051990 +chidori1 +janaki +jordan97 +money111 +199222 +santafe1 +iloveyouto +tavares +redcar1 +donte1 +511511 +leedsutd1 +goducks +jesus333 +darcy1 +fishfood +spencer123 +andrew88 +020279 +02101988 +24011991 +anytime +baller69 +01081987 +manuel +iloveben1 +jesus18 +120982 +monkeyface +15121992 +210184 +16101989 +zxcvfdsa +dominika1 +smokey22 +thrice +alex98 +smartguy +zaratustra +jordan19 +seniseviyoru +bulldog123 +250184 +tigger8 +blondie! +mandragora +14041990 +123456789 +15061990 +oliver3 +110010 +ran +23111987 +butter11 +rancho +thinkpink1 +25011988 +290690 +samsung3 +qwerty16 +140186 +18061985 +coffee11 +240682 +bugaga +telefone +raleigh1 +shayne1 +czarina +omotayo +katalina +533656 +27071989 +12071984 +hottie24 +ballin7 +22111990 +beertje +15051992 +sarah10 +photograph +luisito1 +13021986 +xyz12345 +anthony02 +richter +141282 +280389 +yellow77 +nikki7 +11081986 +dogger +shrek +cortney +201192 +water3 +fynjif +jeffrey2 +salzburg +gangsta23 +29051990 +baby-girl +dick11 +booty2 +10081991 +100285 +09051985 +fuckme. +loveme16 +ytyfdbcnm +zxcvb12 +fucker4 +justin04 +18061984 +zxcasdqwe1 +12081989 +soccer92 +josef +mw0501 +fuckmyspac +10041984 +sigma1 +kingking1 +music07 +139139 +14121982 +analiza +140583 +homersimpson +sembarang +20021984 +250885 +dakota99 +battery1 +300989 +10081989 +marlins1 +dodododo +fidget +muscles +24091986 +miles123 +enternow +21031985 +zackery1 +marcus11 +chris77 +20071986 +bonnie2 +150492 +25021987 +300390 +dancer14 +batman8 +picolo +may2008 +220591 +15081985 +floriane +famous2 +device +chi123 +nuevavida +180691 +passione +memorial +15121983 +vkontakte.ru +5254143 +allen2 +summer16 +9852a9 +280586 +svetlanka +196900 +hunger +sidorov +3edcvfr4 +coolman123 +mami12 +kalle +makassar +rodrigue +221182 +mememe2 +rebelde123 +montserrat +metallica0 +snickers3 +eminem7 +heather5 +157359 +100385 +naseem +cocacola123 +100892 +trina +25051986 +hardstyle1 +24111989 +18061990 +audia8 +pep +semaj1 +deepthi +sexy29 +iluvme! +fuck3r +26121987 +o123456789 +888168 +yellow33 +200890 +koshechka +crazy4you +rjpthju +1234562 +roadkill1 +1sweet +14051990 +shooting +4071505 +alberto123 +blanco1 +mitzi1 +lakers +251292 +est +kelsey11 +diamonds2 +23061989 +nadezda +booty123 +blueballs +bowwow3 +hameed +j111111 +2468101214 +bailey06 +28051990 +love1987 +womble +daddygirl +mandy12 +krystle +peewee123 +aaazzz +hjkl +falcon12 +finest1 +buttfuck +010988 +buster4 +hellspawn +rosette +heath +22051992 +13081987 +taureau +lorien +melrose1 +blackburn1 +chevy01 +112000 +embassy +cowboy01 +billkaulitz +madeleine1 +motogp +10121993 +22071991 +lunchbox1 +pelican1 +pregnant +supermom1 +wraith +210986 +ellis1 +corolla1 +secret3 +281282 +120879 +13121983 +8ba9klw1ce +iloveny +1909 +willow01 +0okmnji9 +15071988 +10121982 +031289 +22021986 +291184 +isidora +fullhouse1 +teddys +corporate +kookie1 +water11 +baloncesto +pitufina +karisma +17031992 +kashish +onetime1 +mamulya +clearwater +20111986 +230482 +marion +gfnhbjn +25091989 +241185 +123zxcv +25091990 +dudes +drpepper2 +23121991 +mae123 +birtanem +01031986 +091286 +love41 +110480 +11081990 +400614 +12345678e +11111112 +jesus2008 +nokia5700 +century1 +iceberg1 +786123 +bullets +fishman1 +christiana +gigigi +hydro420 +monster21 +261082 +astoria +iloveaaron +madhav +dancer08 +crazy21 +babilonia +smegma +18061988 +buller +ricky2 +friendsforever +trevon +aisha1 +vatoloco1 +cameron6 +150186 +20091984 +pretty6 +fred01 +mirror1 ++ +1596357 +1spiderman +18011987 +log +245245 +300987 +pepper +artem1999 +kalimero +080887 +14081991 +friends08 +america#1 +m1garand +bemine +biteme12 +killacam1 +makina +guessit +111111j +h1234567 +03031984 +161184 +071290 +carebear12 +21061988 +220783 +cheer01 +27071988 +kristal1 +lll +241192 +18081990 +15091990 +lucky +06081991 +190290 +kimbo1 +17041989 +songbird1 +husky +brick1 +12061984 +pascha +nevets +taylor03 +020587 +22121985 +picnic +kumar1 +qaz123123 +198821 +prettywoman +10091985 +bassplayer +melissa69 +kirara +babyboy23 +stumpy1 +maggie07 +100482 +24121991 +gramma +28121990 +nikki3 +bobby13 +password81 +marc123 +02071989 +abnormal +david19 +debil +maemae1 +27051986 +121208 +the1andonl +ripken +1510 +guitar01 +slippery +190689 +cuteangel +03061985 +loveme24 +21081991 +22081986 +emprego +lifelife +fire1234 +smellycat +heath1 +2101 +106106 +112113 +19061991 +001988 +hotman1 +123432 +ryan07 +030988 +13love +eggman +200985 +24051990 +111084 +yoyo11 +tiger15 +jazzmine +150000 +mario11 +241184 +041187 +lucky99 +26031988 +23102310 +16041991 +01051988 +10111983 +hhh123 +270690 +251094 +andrea14 +courtney +30121988 +26021985 +mobil +ericeric +cheese69 +bil +geelong +footbal1 +littleboy +14081989 +newone1 +170189 +pastis51 +100192 +comeback +23242526 +050990 +hotshit +16061989 +210892 +madrigal +satisfaction +080988 +psalms91 +mansour +redondo +02051990 +iloveme5 +deeven +130584 +imcool123 +28101988 +19031991 +23071986 +lagwagon +261084 +farouk +hockey69 +180292 +260785 +rockys +menina +barbie +carefree +131181 +friends9 +burnout1 +852456a +lovejesus1 +sept16 +buddy07 +1life1love +lealea +11101987 +240888 +sandy11 +uf +ripazha +myhusband +31121988 +luvu4ever +270784 +230792 +281091 +15987532 +mystuff +tigger18 +301287 +thought +chauhan +120980 +24071990 +150385 +23041985 +joyjoy1 +01101984 +2303 +yyz59gtp100 +meadow1 +jimmy13 +genuine +passat1 +27121991 +600028 +lakers21 +11031986 +07071992 +889988 +baldwin1 +boulot +password85 +01081989 +volvos60 +180391 +carlson +tgbyhn +citrus +talgat +19121992 +lenusik +iamtheking +14081986 +funstuff +250485 +thedon1 +cutify +ujnbrf +letsgo1 +cow +silver21 +aznpride +191089 +single01 +solo123 +240188 +met +spaghetti1 +yayang +amazonka +tinkerbell +bears23 +stick +sarah! +hiroshi +beer69 +gy3yt2rgls +shreeganesh +24021990 +leaves +111www +advokat +27091991 +not +7794422 +caseydog +220484 +301084 +fonseca +donny +987456123 +29061990 +hysteria +wade +230784 +28101986 +ooo +modelo +12345678h +150984 +sharik +catscats +1.23457e +sexygirls +azerty01 +josefina1 +june2006 +1234567890m +freeme1 +211091 +pearl123 +glorioso +11051991 +1234321q +llcoolj1 +6d2-24e5r +emm +1truth +dominique2 +aptiva +14061986 +cutie21 +23111989 +250287 +bridges +150286 +mikel +jackman +300490 +161087 +hair +slugger1 +21061986 +29101990 +babyboo123 +190285 +250491 +eagles13 +f1234567 +1937 +orwell +houses1 +snuggle1 +421301 +sophie3 +slammer +crocodil +papi +110991 +peaches! +11051984 +hippo123 +tebow15 +101178 +25051984 +chaingang1 +100582 +sashenka +218540 +03061987 +210383 +215215 +14061987 +coors1 +icecold1 +1westside +22101991 +betty21 +vfkmdbyf +02041990 +larsson7 +cole12 +sasasa1 +07061985nina +steven5 +gattuso +repytwjd +google1234 +11071986 +univers +sassy11 +halo3rocks +raw123 +rodeo +17121984 +shorty09 +matthew09 +28051987 +8520456 +baller01 +pinocho +197611 +keykey1 +110382 +24081991 +280790 +shortstuff +21101991 +130792 +superman16 +bestfriend1 +gfhfif +shyshy1 +coolie +moveon +101213 +laptop123 +ashley05 +22041990 +081288 +051092 +cousin1 +300190 +09876543211 +camaro68 +15071985 +class11 +jp1234 +born2win +goth666 +transcend +riodejaneiro +planes +06011982 +darlington +17041992 +161282 +132001 +bluefish1 +salinas831 +patricia12 +chicken23 +mistake +shekhar +28101985 +darrin +19471947 +123123l +1900 +22081988 +.adgj +manamana +snatch1 +sasha13 +yamaha2 +091288 +chill +200580 +cardoso +macho +21101989 +270389 +poilkj +omen666 +shahzad +iluvchris1 +120382 +awerty +stampede +ottobre +onlylove +198601 +gender +tyler21 +120678 +25071987 +hill +654654654 +weird1 +290588 +emil +dragonz +process +300485 +vavilon +21011986 +17081988 +colombe +ramakrishna +babygirl93 +poubelle +kumkum +181185 +060988 +290487 +pfqxjyjr +04021987 +p2ssw0rd +18081987 +aileen1 +apollo12 +aserzx1 +olympic +020989 +demian +mechanic1 +1357642 +ilovemark1 +27011988 +aardvark1 +keke +180987 +christian! +6666667 +140891 +pocket1 +konami +milly123 +sentra +ministry1 +kiersten +sample1 +angel2000 +27021990 +myebiz123 +happy14 +070990 +why123 +anicka +240591 +grandkids1 +zzzzzz +welcom +roflmao1 +civilwar +wallst +johny +border +duck12 +maggie21 +snoopy5 +cookie08 +divorced +parker123 +500028 +iloveno1 +15111987 +link2011 +21041986 +05091984 +2106 +090588 +imperium +hotpussy +barone +21021988 +shadow89 +babygirl96 +star25 +08081987 +tweety +300788 +bipbip +17071990 +29061988 +040890 +irule +puppies12 +aaaaaa12 +cock123 +20011988 +230991 +211284 +nikita12 +291090 +calabaza +lucky1 +honda7 +mermaids +janeiro +dominica +massimo1 +antman +juventus +shells +sutherland +franco123 +beavers1 +tigger17 +nexus +canine +13101984 +blue06 +adebola +wagner1 +pumpkin123 +tygrys +loveu12 +missy01 +140490 +03071987 +george5 +gamma +catering +281082 +mustang23 +16101985 +10021984 +2597758 +mongo1 +bauhaus +1hotmomma +220287 +mae +champ24 +030490 +lashawn +pelumi +221987 +kimerald +ashtray +10071988 +shannon1 +199300 +hellboy2 +agatka +30081988 +05031987 +ohbaby1 +asasasasas +wtpfhm +carebear2 +kelly11 +billion +110021 +rolltide12 +mommydaddy +apollon +260386 +kaylin +januar +samsung5 +anna22 +lol321 +hearts12 +kakawka +260391 +jack +snowhite +badboy23 +ciocolata +230391 +david25 +mike19 +170386 +abc12345 +280289 +alisson +radmila5 +arthur123 +ripley1 +231283 +jacob22 +blue456 +021086 +cleo123 +camaro67 +260187 +01021984 +inzaghi +24021986 +maradona1 +pressure +29031988 +asdfdsa +110981 +191186 +atx512 +tugboat +040485 +1forgot +29011987 +awesome3 +110186 +19061990 +brit +crystal +tommy7 +football76 +cucaracha +iron +030689 +sweetboy +143441 +reggie12 +okokokok +150383 +12111985 +270985 +bigone1 +mansoor +cacahuete +cerulean +ocean123 +matt17 +prince3 +midnight13 +090985 +250883 +20041991 +gaby12 +michael27 +23031986 +luanda +copito +matrix23 +alfalfa +holloway +david88 +gemini +hubby1 +puppy5 +11101988 +sexxxx +darkmoon +211184 +02031984 +kill3r +23121990 +aaaaaa2 +bang +28091987 +020785 +morgan99 +080892 +01021992 +sweet4 +131092 +ladydog +rajarani +12071985 +pennywise1 +b1tches +gunner12 +05051992 +281092 +310387 +winning +vfvfgfgfz +bionda +passes +jesse3 +mykids5 +gjkbyrf +13071990 +19101986 +ronnel +anime12 +kkk111 +ducati996 +lilian1 +290390 +kelly13 +dominicana +gfhnbpfy +azteca +elvispresley +korea1 +09080706 +kaiden1 +daughters2 +15091986 +united7 +jolina +sambo +shorty18 +moonwalk +airjordan1 +8iiw4ct9rq +manzanita +stephanie7 +100791 +310784 +170387 +sierra11 +131192 +kayla14 +favorite1 +rainbow22 +popeyes +torero +piggies +laura11 +13031988 +161283 +easy1234 +pooh1234 +090991 +wildones +10221022 +moremore +050789 +cubswin1 +catalan +27031990 +bubbles9 +gilgamesh +nisha123 +medieval +timmy12 +16041988 +25041989 +200884 +marlee +25021986 +04071988 +qweqwe12 +irochka +class05 +fickdich1 +dallas7 +28021988 +george23 +pw2012yr +vergara +dicker +ugochukwu +shelbygt500 +aliens1 +faceoff +19061986 +buddy8 +220483 +conor1 +ira +belgium +robbie123 +311091 +20061984 +pedersen +hayden123 +01041991 +omar13 +samwise +blank +phantom2 +250991 +minion +wal +rahmat +pimpin09 +10091991 +angel2006 +30071987 +heather01 +daniel98 +zagreb +football58 +vfufpby +boondocks1 +yeshua1 +expedition +17101985 +iloveamy1 +eagles3 +020390 +lover24 +01121986 +zippo1 +240691 +fudge123 +smeagol +live2ride +1928 +joey01 +20051990 +flower21 +22031987 +butthead2 +26101983 +tigger06 +martin23 +151089 +pantek +helpdesk +a1234a +codelyoko +28031991 +amandeep +011086 +181182 +201287 +tata12 +qq123456 +261182 +muffy +130983 +crazy15 +14081987 +estefany +joseph! +17041990 +amanda09 +mike101 +arina +gambler1 +chandana +060890 +200892 +iaminlove +kikina +198123 +yankees5 +aaron3 +1q2w3e1q2w3e +19866891 +021289 +sparkey1 +buggy +nena +16101984 +230583 +petter +270890 +18101989 +170784 +tiger77 +cutie8 +bulldog3 +mustang21 +hannah18 +17021988 +15101992 +11091991 +audrey +pernille +grace01 +21091991 +010288 +grandkids5 +29121986 +171089 +280987 +halo13 +sarah69 +26121986 +26101984 +peoria +tigers! +poopie! +buddys1 +panatha13 +mexico17 +hollis +froglegs +190785 +seth123 +raiders1 +nicholas5 +flygirl +170887 +25091991 +14101992 +magic13 +170390 +lebedeva +27071990 +2horses +hallo12345 +jonathan123 +170286 +steelers1 +mom12345 +milan123 +tonyromo9 +halo360 +cook +bailey05 +bulldog7 +lemans +10081984 +access123 +tho +billabong2 +maddox1 +antonio10 +140885 +oneone1 +170186 +lbvfcbr +trevor123 +tunde1 +24041988 +brittany14 +antosha +210483 +150692 +semenov +69eyes +player10 +dipset3 +221083 +lfc123 +mustang4 +sadhana +cool01 +bulldozer +nick69 +hatice +17031991 +25071989 +airwalk +dozer +25071991 +inside1 +amaury +280891 +jr123456 +834001 +ellis +dnstuff +12011991 +cherry4 +a1b2c3d4 +certified +love_me +mamaku +gwendolyn +cupido +rock10 +241182 +12121981 +021285 +freespirit +musique1 +monkey26 +server1 +diablo13 +mykids03 +ransom +a010203 +kandy1 +superuser +natasha +viktor +040589 +19031988 +lalala. +logan01 +jammer1 +mividaloca +p4vkinrw6x +louloutte +300889 +12041994 +230692 +03030303 +230782 +221984 +daniela12 +160891 +kellen +08031990 +soulmates +patches123 +cristina +mj2345 +fin +suzuki750 +301080 +topaz1 +andrew19 +friday +adrian10 +22051985 +click5 +internet +sultan1 +14071990 +springtime +eagles23 +160491 +victoria13 +asskicker +hardcore2 +bichette +steven +karina13 +anthony25 +pickle2 +lover08 +ballin24 +tyler101 +jenn123 +sexything +chino13 +mashimaro +3100 +hippopo +hanihani +280786 +hotgurl1 +15021983 +031287 +sleep1 +31051988 +yemisi +kimberly +smokey10 +280587 +andy01 +pookey1 +natalia +19141914 +181189 +191090 +delorean +abcdef2 +14051985 +jesus24 +mustang00 +rjnzif +weller +030687 +vampire123 +190891 +14051988 +qwe223 +140492 +john17 +adgjmpt +bug +friend +back2back +memyselfan +toytoy +31101990 +primus1 +gurpreet +jonathan1 +midcont +tiago +toni123 +ferrari2 +maggie23 +ikillyou +18051989 +whatever22 +200287 +alyssa7 +gtkmvtyb +it +21071989 +football60 +020790 +ccc +tinker13 +02041989 +yessir1 +boeing737 +17091985 +sexy2009 +221292 +02101989 +22081985 +lisbeth +31011989 +11111988 +100481 +aman +260593 +sasha1997 +erevan +260189 +yahoo3 +hotdog11 +melmel1 +duke13 +love1997 +03031993 +251091 +261191 +05121985 +290786 +cordero +23101984 +fuckhim1 +010193 +diciembre1 +xchange +cookies5 +151191 +punk666 +01031990 +genocide +arrowhead1 +281184 +arroyo +pinky3 +journal +24051989 +1clen1 +gonzalo1 +daisy22 +mommy21 +261183 +melita +frost1 +generic1 +graves +1gangster +amor10 +03061990 +315023 +02101990 +homehome +120579 +rotimi +21101985 +nikolina +shadow1 +197511 +25051992 +karatekid +411006 +persian +121212w +rollins +nikki01 +player4 +parsifal +yandel +rhfdxtyrj +group +29041988 +newyork13 +football67 +23081989 +westside23 +210000 +intranet +football70 +vbkbwbz +963 +25041986 +eeeeeee +trfnthbyf +20111985 +setiawan +96969696 +26041990 +mariusz1 +princess90 +191187 +liarliar1 +buddy69 +maybe1 +werock +zaq +31121989 +trains1 +supersuper +edward21 +pinky13 +poohbear14 +bama12 +lucy13 +jordan95 +mike77 +segreto +josh18 +grace5 +100483 +zwn6vbdvpj +puppie +23091992 +nigga11 +chris26 +angel1 +221226 +21021984 +07051987 +teamo. +260987 +steve2 +melissa21 +16031990 +taylor. +08081985 +weed101 +dirtbike12 +yummy123 +220380 +gracious +gaara +22071985 +20031985 +shift1 +051286 +190000 +musicmusic +17061991 +11091987 +tj1234 +ane4ka +24031988 +21081990 +raiders5 +godsgrace +15051988 +120595 +saun +hoosier1 +george69 +katlyn1 +22081989 +derrick2 +ghost13 +hotty101 +sosexy +awesome +akolang +11041984 +jenny10 +220881 +24121988 +cantik1 +baxter12 +vasant +yankees02 +ilovetony +pomodoro +270987 +560010 +180386 +040788 +030387 +560102 +london7 +puppet1 +cletus +000000m +lover. +stockton1 +050890 +mybabygirl +22111985 +flowers7 +101983 +241291 +attack1 +honey143 +choochoo1 +1liverpool +jamaica2 +16121990 +23111990 +danny14 +carlin +nafisa +mabel +290789 +grounded1 +hannah98 +18011991 +10021983 +f0rever +joeblow +booyaka619 +201191 +vipergts +sammie2 +250391 +harry7 +satanas666 +thedevil +18081989 +131213 +elegance +gracie3 +one1love +198505 +sexygirl10 +elisabeth +hardy +201183 +parachute +240492 +magick1 +jerome123 +03051990 +johan1 +oscardog +18021989 +mimama +200684 +messi123 +191285 +180786 +135642 +pooface +princess04 +19021992 +missing1 +11071990 +demonic +region +buzzer +ryan16 +andrada +261192 +tasha12 +270586 +ford12 +251080 +19061984 +05061992 +ryan69 +ilovetony1 +31121984 +150883 +cubby1 +alleycat1 +28021986 +181287 +taylor04 +feliks +28021990 +31031986 +23071990 +dalejr1 +28111986 +lucas10 +041088 +basketball12 +chevy1500 +anhnhoem +11111983 +170191 +pimpin07 +dewalt +papa1234 +14081990 +10041988 +15011985 +booboo23 +nathan09 +liverpool3 +mars13 +zaebali +47114711 +onimusha +14061985 +akusayangk +130384 +19011989 +150191 +270388 +macska +001977 +sean1234 +jeffry +daxter +14111985 +maimouna +megamanx +10031993 +rodica +marshal1 +poppy12 +hookup +lordoftherings +class2007 +wertyuiop +19111985 +nokia2 +roadking1 +dearest +rockstar22 +sassy3 +lilman123 +190585 +14111991 +30041992 +buddy08 +tessa123 +16041990 +sasa1234 +vjybnjh +tweety10 +01011 +20071991 +13051985 +meggie1 +thatshot +181285 +seafood +skater01 +120978 +zhangwei +280885 +mnb123 +220192 +severin +heroin +kobe81 +amber69 +pimp00 +andrew04 +lovestinks +200186 +030888 +rangers1 +level42 +joshua9 +21021985 +miamia1 +031088 +xbox360 +0277127298 +rogerio +23101988 +31101988 +laugh +19251925 +mommys1 +feelings +ramarama +stokecity +shamim +mira +25031991 +abc111 +150482 +abuse_123456_abuse +baluga +n1cole +201182 +sammy23 +987654321s +petr +091189 +27051987 +100382 +19091987 +taker1 +190584 +mariano1 +alcohol1 +12341234q +master77 +250383 +michael77 +simon12 +jack69 +alabama12 +18111987 +16091988 +18121984 +myjesus1 +pappy1 +lauren14 +22041989 +snickers +mylove22 +9itz78vufw +d68pyfuh2v +peaches01 +hermano +akomismo +legoman +sahana +minino +colnago +odz1w1rb9t +linkedinpassword +patrick9 +master007 +check1 +22031986 +29031991 +liana +banana22 +120792 +060790 +141191 +300389 +301280 +superman25 +wallace2 +flower9 +pigpen +070792 +chicken10 +051285 +260484 +16051987 +lance123 +babyboy4 +aqaqaq +god4life +ronaldo12 +20081989 +14061990 +breathe1 +shelby10 +011287 +kilokilo +lildevil +03071986 +iloveme23 +26061985 +2107 +27021987 +worlds +sayangku1 +ragnar +pravda +golaso64 +pupkin +sno +2201 +20041989 +rex +10021993 +monster666 +taterbug +rfhfufylf +28121986 +green09 +16021988 +webmaster1 +31101989 +rfvbkkf +210781 +sharmaine +291284 +100881 +134679a +programmer +yellow14 +110581 +291190 +bell123 +cherie1 +fatboy69 +raindrops +100291 +bmw520 +thorsten +jacob4 +rock01 +1rabbit +baxter123 +008hotboy +saints12 +raymundo +gundamwing +redsox7 +271192 +yellow69 +lucas2 +250786 +russia +monkeygirl +rosalie1 +moomin +shadow33 +17091991 +alex666 +nasreen +istanbul1 +destruction +gnbxrf +19121985 +251291 +calvin123 +160785 +roderick1 +173173 +13091986 +dogs101 +black101 +harmon +301182 +19011986 +mercure +killa23 +cameron13 +270187 +20011986 +29091991 +1bitches +snowy123 +198602 +lizzie123 +17071991 +son123 +patches +16061991 +15061985 +sizzle +april05 +40404040 +180488 +alex33 +eskimo1 +damned +040688 +122345 +22101992 +zizou +magic5 +xxxxxx6 +a333333 +forgetit1 +dreamers +tgpw53j3kg +dalida +sweet101 +eric01 +amanda19 +02081984 +derby1 +nonloso +17091986 +jannie +221181 +ramon123 +tony15 +sai123 +henning +freesex +180486 +10291029 +venture1 +joker21 +yakumo +black1234 +181282 +madison09 +031186 +180290 +sucks +sampras +ford01 +flying1 +peridot +fluffy01 +tigers06 +kevin69 +29101987 +10101994 +sexy30 +daniel77 +davidm +asdfgh6 +sounds +aaaaaa123 +gaspard +170687 +hailmary +280286 +kitten3 +mimino +290586 +22061992 +lollollol1 +zxc789 +penny12 +faizal +tristan2 +arvin +151285 +dragonfly2 +alyssa5 +baby95 +180487 +continue1 +hotty12 +iloveu9 +10071985 +310386 +purple19 +prada1 +chobit +220189 +doofus +nestor1 +bunnie1 +tecnico +passord1 +hollyy +123213 +ciao123 +131184 +230682 +subhash +delsol +11101989 +tiffani1 +17111989 +9052950013 +beastie1 +210891 +ybrjkftdyf +mustang22 +christ123 +storms +250000 +ramkumar +paganini +sigmund +forever14 +j11111 +danidani +paakow +myrtille +135798 +27111985 +081289 +290992 +seagulls +weaver1 +luisfigo +0o9i8u7y6t +stephanie0 +emilee1 +blue12345 +conker +22442244 +baseball26 +myboo +03101991 +369874 +gabi123 +love54 +ilove23 +091188 +300886 +sonnenschein +jesus20 +23121989 +197373 +dfczdfcz ++++++++++++++ +maja +monster01 +29091992 +westside7 +280788 +bunnyboo +411411 +30071986 +1504 +valter +antwan1 +27081990 +13041989 +peanut09 +190786 +marito +23091993 +kimono +blbjn007 +31071986 +12stones +june04 +marie9 +aleale +monica +arpita +bugs +02061991 +oneandonly +1bailey +naruto95 +fussball +tanner +15041986 +33 +therese1 +cheeseburger +nikki69 +ciccione +batman9 +020885 +godisgood2 +26061988 +27121990 +dance4 +15253545 +sexy92 +kornkorn +zurich +160484 +footprints +rehana +conquer +2105 +social123 +200987 +loren +joystick +bagels +fsd9shtyut +nfnmzyf +babygirl45 +euskadi +25061989 +imyours +36987412 +carwash1 +general01 +198219 +291183 +sassy13 +21121992 +29051991 +lakers7 +alex1986 +291288 +21051985 +badgirl2 +actress1 +190687 +forever +23011989 +23041988 +#1lover +070888 +1bandit +firestarter +sushil +arthur +280492 +21111991 +stevenson +soyfeliz +zolika +kiwikiwi +dada12 +cutlass1 +198426 +orange44 +bateria +kurniawan +daniel03 +241283 +400057 +like +1301 +pickle12 +craig123 +пїѕпїѕпїѕ +mybabe +251191 +3000 +chicky1 +852 +gino +blast +ami +400002 +jovana +chatter +lidia +12051984 +matthew16 +daisuki +9inches +playground +hehehehe +marbles1 +computer22 +tonya +180592 +adadeh +hayward +310389 +dj12345 +ttr125 +lookin +bigpoppa1 +19011987 +geezer +ibragim +zachary7 +rc.itymrf +yyyyyyyy +23021986 +penis5 +13101991 +dima1994 +201282 +30121985 +18051985 +donald123 +26081987 +19101991 +07091988 +john1 +29061989 +180989 +scooby69 +spacemy1 +fallen123 +allure +021189 +killjoy1 +netnet +saffron1 +131083 +030587 +10061990 +13061985 +28021991 +250382 +160883 +100282 +rachel10 +sharif +orlova +wings1 +chiaretta +852963741 +14011992 +210784 +al1234 +25111985 +hannah101 +biedronka +skater22 +cassano +bulldogs2 +150683 +mc1234 +ilonka +atlanta7 +25081987 +ilovefood1 +otioti +22061986 +money06 +steelers07 +oluchi +brenda13 +parts +191287 +24021989 +patron1 +31071991 +280892 +freed0m +tweety! +321qwe +miami13 +ilovegod! +baseball05 +dulcemaria +streetball +avengers +nichols +shorty07 +delhi123 +120493 +mkmkmk +170692 +120593 +290986 +rusalka +210682 +rat123 +idontno1 +citadel +carl123 +aa123123 +williams12 +12345@ +lztez2xe98 +import +kids04 +270390 +reeree1 +godsgift +2332 +bilbo1 +1511 +dejesus +chanchal +21081986 +160489 +jerick +dimochka +riley12 +240583 +mariachi +02121988 +double1 +210285 +john24 +15021992 +sasha2010 +pepper33 +sarada +pollo123 +151281 +040889 +pedros +sammy1234 +school7 +dragones +patrick10 +27081991 +daniela +ctcnhf +hol +fuckoff11 +240387 +komatsu +raiders01 +chaparra1 +1love2 +21061985 +dragon19 +dididi +shiva1 +heavy1 +memole +onelove12 +solano +14031988 +morgan4 +18101990 +26021991 +burzum +simcity +moonbeam1 +19121984 +241083 +june02 +java +moneybags1 +tan123 +831001 +neo +01011973 +250505 +aaaaa2 +chandru +wendys1 +saloni +pistola +patita +souljaboy2 +spirou +4747 +220693 +199411 +nicholas01 +080990 +18021992 +norte4 +311283 +die666 +longbow +456963 +16031988 +260786 +patrick22 +mariateresa +superman17 +panchito1 +220791 +13091991 +140982 +lilchris1 +nigger7 +murphy11 +macaroni1 +deanne +2stupid +gemini12 +delphin +babigurl1 +four44 +theodora +02041992 +170892 +mcdonald1 +28081985 +bong +ajay +rockstar23 +cool55 +spider11 +cherrycoke +camilo1 +shippo +197100 +170290 +160690 +may2006 +pixiedust +161186 +tyler05 +snooker147 +baileys +daddad +bambush +scrapper +abcdefg2 +sclub7 +221986 +14011991 +wrinkles1 +devika +mamusia1 +yourface +121976 +nani +football87 +140483 +yahoos +29091989 +17091987 +spencer +olegoleg +catcatcat +discount +win123 +2206 +badbad +travis +14111989 +yourmom7 +190485 +scimmia +hawthorne +starsky +shortys +240287 +30031989 +dalmation +fuckoff420 +222221 +17031989 +absolute1 +homies13 +01091992 +sniper12 +01101986 +nicole101 +gardener +yousuck123 +nottelling +sydney2 +260783 +bartlett +a159357 +10091984 +20091986 +17101992 +001 +april06 +slipknot3 +butchie +mazahaka +harder +11223355 +schultz +pooja123 +yugioh123 +warwick1 +jonas101 +lbvf +1123456789 +defiant1 +mariaclara +199315 +gemini22 +naomie +baseball28 +031090 +pierce1 +230484 +210884 +24041986 +scorpio2 +muenchen +magpies1 +majeed +cheeze +settings +100million +aaron01 +scrappy2 +matteo1 +candy16 +24091987 +21081985 +24021991 +boriqua1 +30051990 +cherry23 +polizei +green44 +19111986 +alienware +google7 +301183 +lol666 +loveme9 +linksys +orange9 +turtle22 +hertha +jaimie +22071988 +emoboy1 +orlando123 +thunder1 +jesus16 +17021992 +sokrates +zemfira +170788 +111974 +280990 +rolling1 +black09 +03101989 +cvbncvbn +seymour1 +bl +160284 +skittles3 +310186 +041286 +69love +lovergirl2 +paul11 +23061992 +yoyoyo2 +cherry21 +lenchik +1snoopy +neverland1 +070889 +4343 +190287 +kalle123 +210983 +230184 +delhi +different1 +291187 +sunny7 +skater32 +pinky5 +kotkot +clarion +11111990 +040691 +140582 +070783 +rosado +brian11 +mlqdakf8yt +fuck101 +qwerty86 +75757575 +yusuf1 +lilrob1 +230283 +isabella1 +melly1 +nannie +29051987 +summer2006 +maxie +matt10 +170591 +121079 +lady11 +221082 +mavrick +rita123 +julienne +140684 +tes +shorty17 +fuck88 +141082 +021190 +18021990 +serenity2 +050592 +140282 +myspace89 +12481632 +001002003 +scumbag1 +12071986 +010686 +fontana +kaleb +uncle +jayman +150485 +03061991 +heslo1 +171184 +1vanessa +trythis1 +bichito +organic1 +andrea5 +555123 +molly1234 +fuckoff5 +cuties1 +p00kie +cosanostra +triton1 +qwertasdfgzxcvb +cfiekmrf +fericire +football73 +my1andonly +140494 +1badgirl +25021990 +fevrier +brooke +300385 +traviesa1 +011090 +sophie! +231081 +270885 +welc0me +hello24 +pimp18 +12password +01101988 +roofer +ilovecody +091287 +crown +071287 +nero +style +shoes123 +131281 +adetunji +westside4 +kamilka +110580 +23051983 +140591 +rangers11 +02061990 +3141592653 +160583 +ilovemybaby +ja1234 +keepitreal +123789654 +030786 +carlos17 +kochamcie1 +eagles07 +nepali +giants21 +meemee +broncos24 +15111990 +30031986 +1pumpkin +ppp000 +girls69 +mymommy1 +mervin +01061983 +rickey1 +cathy123 +rennes +310584 +27011987 +ciaobella +my2dogs +1mylove +08021990 +killer07 +airhead +simon2 +elijah3 +agbdlcid +031290 +millos +small +10102020 +220892 +lynnette +zaqxsw1 +25061986 +fgrd58es24 +1304 +mike45 +dude69 +050687 +rose10 +candy1234 +medicine1 +05061985 +wingchun +stella +10051983 +01121990 +071 +198333 +milito +sarah14 +happy08 +balls69 +orange33 +nique1 +chiodos1 +pork +wonderboy +naruto16 +25071985 +16111990 +burgos +raffaello +mamalove +ashlie +240885 +270590 +pomona1 +thebeach +240887 +250290 +020988 +dietpepsi1 +21031989 +babu +rose01 +chambers1 +141283 +250187 +270288 +020787 +hockey25 +041291 +jj +180684 +29041986 +gemini11 +skate! +010107 +20101983 +santino1 +babie1 +imapimp1 +130292 +290985 +piloto +sunshine15 +dos +orquidea +mickey16 +060683 +ilovescott +280789 +badoo1 +angel30 +01021991 +300685 +royboy +khalifa +especial +1258963 +19491949 +21071992 +18121985 +17071986 +spain1 +qq12345 +mclovin +411048 +mojomojo +goodone +garland1 +reptile1 +tyson2 +xzxzxz +apple9 +190686 +myname123 +260887 +01071989 +17011989 +alvin123 +virgos +garfield2 +concon +southampton +041189 +14031987 +4me2no +kidney +alexis9 +aleman +1morgan +27061985 +02061985 +06061992 +1sammy +jeremy7 +pink19 +111292 +31101987 +110293 +fatboy13 +faith11 +tyler16 +normandie +04081987 +red100 +truelove2 +24121984 +anyuta +bismillah786 +vin +230882 +29031990 +21111987 +250191 +james33 +guess123 +23091988 +creation1 +july08 +7788414 +26041989 +babochka +051090 +dmitriy +walkman1 +graphic +aurora32 +esquire +zaq123wsx +111zzz +parabola +basshunter +10021985 +wybe4591 +198918 +111281 +traci +estrelinha +felipe12 +fuckyou2 +25081989 +6children +nouveau +3rjs1la7qe +1116 +kit +waylon +aguilar1 +sept12 +mahadev +monkey28 +091285 +chelsea14 +james +iii +golf18 +scuola +linkinpark1 +13071989 +26081988 +orlandobloom +katekate +12021993 +klubnika +smarties1 +560025 +281083 +poop21 +cassius1 +bosco123 +slayer13 +vidhya +300985 +northern1 +mark21 +alladin +asshole01 +stephen123 +clapton1 +228 +chubbs1 +310889 +11041985 +220583 +pimpen1 +bogus1 +144144 +010586 +priceless +16121985 +james20 +ramadevi +jeepster +anonimo +9898 +polar1 +knives +babygurl07 +21041991 +04061988 +16081990 +nicole77 +amirul +sheckler1 +swift +chicago12 +alpha2 +joshua98 +12081983 +28121989 +10211021 +15101984 +shella +010886 +suisse +spock1 +skippy123 +kindergarten +d1amond +12021981 +donomar1 +198225 +gitrdone +raptor700 +198820 +30051987 +8x2h4fddap +willow2 +rosie2 +08081992 +rock4life +260287 +hibernia +24031986 +greengreen +modupe +monami +babylon1 +iloveu6 +kasey9 +koolkool +gemini +kingcobra +29051986 +18111986 +15061991 +180884 +graeme +pr1nc3ss +saveme1 +fatdog +02011989 +gambia +paterson +berber +30101991 +cookie1234 +11921192 +fantasia1 +trotter +170690 +yankees09 +marlins +loveman +001974 +maggie99 +26121989 +angel44 +241282 +121095 +150287 +220384 +kfvgjxrf +tables +ashley25 +17071989 +5151 +2526 +snoopy21 +natura +130491 +skaters1 +19071985 +thriller1 +15111989 +oldspice +280691 +blahblahbl +231083 +171083 +miramar +lovely8 +2020fb +heather4 +gunman +number17 +alexis15 +23081987 +16061990 +kerri +darkness6 +leones +1593575 +einstein +03121987 +tribal1 +india +040789 +85858585 +1zxcvbn +140391 +27041989 +6363 +tampabay1 +19061989 +milford +swerty +watsup +17061987 +hillsong +celtic1967 +hondas1 +amazonas +26051986 +++ +truand +slipknot11 +daniel26 +wangwang +rainbow8 +010179 +l3tm3in +250390 +lovemama +rockout1 +270786 +mywife1 +ryjgjxrf +170587 +darrel +coco23 +vampire12 +potter123 +cashew +55 +041289 +tyree1 +00009999 +160586 +bigdog69 +bailey09 +jackdog +diamond08 +gussie +trinitron1 +camila12 +password67 +vfhvtkfl +07071985 +revilo +sw0rdfish +munmun +kevin1234 +lenore +23111992 +290386 +211291 +calipso +amoretiamo +ronnie123 +sourire +babygirl +frenzy +ocarina +douglas2 +feeder +041186 +jesus2010 +10051984 +steffi1 +@gmail.com.mx +sue123 +hunter77 +brasil123 +bellas +dallas3 +angels! +nachos1 +sergeevna +230492 +lolipop12 +061286 +140592 +veronica +analaura +199712 +stifler +panthers2 +17061988 +hang10 +mr +elvis2 +grandma12 +carole1 +deathstar +bhushan +zambia +tanga +sanjay123 +parasite +kwabena +doreen1 +emmanuel12 +30051988 +01091988 +smartgirl +pipicaca +princess0 +elloco +15011986 +farhad +seanjohn +kaitlynn +shorty08 +duchesse +26011987 +какашка +030392 +thomas05 +sexy2008 +tomjerry +isaiah12 +danielle5 +anupam +160789 +148888 +argyle +emily4 +temporal +05071990 +shinta +calvary +contreras1 +zachary +160990 +loved +chase2 +zhongguo +ryan06 +29121985 +21111985 +01081986 +freshboy +getfucked +16051991 +sexygirl13 +21011985 +sports11 +myspace777 +goblin1 +fanta1 +130482 +123456me +poiuytrewq1 +291283 +spring12 +04061984 +ange +23021984 +25011987 +23051984 +051191 +bella06 +loveyou8 +27021992 +charles +23041989 +millie01 +11011984 +doggys +21011989 +121296 +06071984 +220482 +250580 +underwear1 +safina +newyear1 +271182 +04061987 +bandit7 +bella21 +68686868 +03091987 +rediska +momo11 +horndog +28071988 +isabella3 +justme123 +lamar +luvbug1 +15111985 +loveme18 +110782 +26091986 +adidas3 +091186 +umesh +01011972 +flowers5 +200584 +nigger4 +vqsablpzla +12345678f +cookies7 +300988 +02071990 +29071987 +arsehole +manuel +zoulou +werwerwer +100681 +291291 +123321m +040588 +26071990 +25031986 +agnese +150691 +01061992 +johnnyboy +030787 +18091986 +abdullah1 +1472580 +love1988 +apple8 +password04 +adrian +kokoko1 +dustin2 +goldfish2 +labyrinth +rainbow9 +halifax1 +grzegorz +ticktock +miumiu +football62 +harman1 +15011990 +12111984 +02091989 +malandi +180191 +agassi +20091990 +270685 +video123 +libby123 +400013 +dancedance +23081986 +chris27 +blacksmith +240884 +agyeman +josue +10111984 +money2009 +11061989 +superstar! +wholesale +16111989 +percival +010990 +22071989 +montevideo +pimpin6 +lowrider13 +180689 +20121992 +calypso1 +sanjo408 +lala14 +justyna1 +22031985 +tanner11 +ou812ic +vette1 +suckmycock +pretty01 +tayler1 +perrine +210287 +101179 +13051992 +zxcvbnmmnbvcxz +alleluia +fuckyou33 +29061987 +joshua20 +05091987 +ubuntu +15031986 +mybuddy1 +17051985 +bracken1 +coucou1 +011289 +160791 +28031990 +14041984 +chico2 +dolphins12 +davion1 +010789 +e65r82kni2 +malin +peaces +toodles1 +jorden1 +beulah +stetson +trauma +tinytim +27061990 +281090 +paige12 +23061986 +ryan08 +evanescenc +yellow15 +sexyboy2 +260984 +21121984 +10091988 +nintend0 +kp9v1ro7lh +polo1234 +1234567654321 +meow12 +diablo22 +1503 +belair +beltran +paparoach1 +berenice1 +antique +25011985 +football71 +jhonatan +caballos +nigga4 +strawberries +pipi +purpose +160591 +310885 +23051985 +darklord1 +08081990 +love1212 +kuba123 +271084 +iamfree +chester1 +020891 +110693 +kenobi +houston123 +dogbert +28011987 +tarantado +213 +allied +danny21 +mitchel1 +jeremiah2 +02121986 +14071988 +03051987 +dakota5 +18021986 +02031983 +malaka1 +andi +ginny1 +harding +kipling +danielle10 +hayden01 +skadden +maria +baddog1 +negrita1 +300186 +candi +honda11 +articolo31 +bathroom1 +sparkie1 +topaze +dylan11 +ghbdtnekmrb +zelda64 +180385 +turtle5 +197346 +q1w +iheartyou +univer +23071988 +14031989 +whore. +ashley89 +sagesse +jessy123 +jesus1 +butter5 +sept20 +23011987 +200500 +diosmio +scrubs +123123b +19371937 +cri +19051985 +sssssssss +hattie1 +10111991 +playboy21 +jerry2 +30041986 +йцукенгшщз +laura01 +13071985 +513513 +emily! +gr33nday +janie1 +11223311 +bird123 +awesomeness +210492 +a12341234 +loubna +goldeneye1 +01041989 +natalie1 +ramiro1 +veggie +01031992 +mouse12 +clothes +gabriel1 +vfktymrfz +davis123 +special2 +040492 +28081992 +25021991 +marcus +170584 +narciso +putain +edward +281285 +fucking69 +theduke +demolition +granger +max007 +raiders21 +24091990 +2wsx2wsx +261283 +14071992 +23031992 +nascar99 +395007 +harvey +nutella1 +danny10 +vining1 +prinzessin +e +welding +170891 +ilovepaul +kaffee +pimp17 +bashir +jingle1 +magic3 +ashton123 +1940 +aq12ws +copycat +fortunato +lexi12 +jackdaniel +haroon +brianna13 +27041987 +bigblack1 +03041990 +google +killer44 +chicka1 +dupa12 +77777771 +cowboys! +blackberry1 +yamakasi +manoj123 +280387 +drive +eyeshield21 +300787 +lavander +lacey123 +hottie18 +05081987 +akinola +bubbles09 +29121990 +omolola +171182 +25021992 +30041988 +orchids +paiste +orange +230681 +200691 +12011989 +010100 +sternchen1 +maxcat +28101989 +02091985 +280191 +050583 +lllll1 +271287 +dallascowboys +lifetec +dragonball1 +joke +200284 +biggles1 +portakal +151083 +1peace +lookout1 +squall1 +211183 +1a2b3c4d5e6f +pimpin08 +carlos16 +26021987 +taylor69 +year2010 +cendrillon +29011990 +06071987 +soleil +554455 +bandgeek1 +rebelde12 +playnow +michael26 +allalone +mamababa +navarro1 +football43 +04081986 +20081984 +23121983 +dexter11 +mather +alyssa07 +meandu +apocalipsis +sparky13 +pass-word +16011987 +140892 +bla123 +18111988 +abba +ponchik +trilly +aqw123 +16051989 +rulez +mexico09 +hockey30 +blackwolf +17081992 +tweety4 +26041987 +loveisgood +fucku5 +1stborn +31101986 +christian6 +blitz +raiders +level1 +isabel12 +ridwan +athletic +17021986 +ramos1 +imran +raihan +130483 +201081 +151151 +marcelina +pass12sa +shruthi +biblia +myangels +babbygirl1 +pink55 +20111984 +121094 +22041983 +money44 +560071 +inuyasha13 +osborne +asdasdas +vincent +tigers23 +rene123 +vasileva +19021985 +logan11 +15011991 +seadog +change12 +music6 +luke1234 +thebitch +pleomax +blackstone +alakazam +guru +150483 +8602229096klo +silver5 +mexico8 +13041986 +sonja +tania123 +vadim1 +ihatelife +hottie1234 +lachlan1 +marieta +1marie +061189 +12431243 +fool +radheradhe +mafia2 +dancer21 +tayl0r +16011990 +toonces +blueberry2 +246813 +05101988 +mama21 +270483 +whatitdo1 +199199 +130184 +teehee +crow +abby01 +football92 +russell +ttt123 +17071992 +14011988 +1blessed +gun +25061988 +199123 +310583 +ilove22 +101990 +justinbeib +301290 +19031983 +fotboll +mylove4 +metallica3 +cookies11 +filip1 +310185 +katyperry +170284 +240886 +221081 +191989 +flakita +101979 +gwapito +vitalina +speedway1 +nightmare2 +985985 +pusspuss +29101985 +180883 +iloveyoumo +bethoven +160584 +161185 +endless1 +270286 +aisling +landen1 +250289 +270591 +28031986 +evans +56785678 +felixx +1redhead +dfkthbq +final7 +lafouine +femmes +superman99 +shiznit +tina1234 +lavanda +240692 +sunshine99 +wangjian +qwer789 +dinheiro +iforgotit +christoph1 +asdasd123123 +241280 +sasha2003 +alamakota +01021982 +miyvarxar +bayside1 +hardc0re +tnt123 +h1992iding +wwewwe1 +ab +280285 +sarah +audioslave +jordan33 +andron +mariobros +lisamarie1 +cali12 +faith56 +180784 +281284 +koko12 +samba +tyler1234 +redwine1 +super13 +catdog11 +bestbuy1 +mollygirl +211083 +version1 +sexycani1 +vtuf36jhufpv +skylinegtr +brianna01 +onegod +260487 +230680 +300786 +france98 +fordgt40 +june05 +bears34 +041290 +poop666 +declan1 +199090 +cupcake5 +25121983 +ashley02 +mummys +tiger +bubba10 +dragon1 +25051983 +orangina +mnbvcxz12 +gordito1 +corine +horses13 +reggie31 +jj12345 +falling1 +samuray +starwars! +bembem +1234567as +michelle24 +warfare +130991 +guardian101 +littlemiss +poppydog +kobe23 +14031986 +260985 +basebal1 +loser45 +thing2 +anneke +040990 +120693 +tolkien1 +song +210183 +avefenix +031291 +12031984 +norwich1 +lor +sunnie +soldado +tink01 +260886 +ghana1 +ghost12 +korean1 +reggina +cookie16 +kinder1 +110982 +124578a +28031989 +fireflies +280190 +323046 +nathan8 +ochoa1 +ball23 +23071989 +dennis2 +iluvu12 +11051992 +tasty1 +19101985 +europe1 +pride +panther7 +melnik +leonleon +march08 +spierdalaj +reckless1 +jailbird +kl123456 +northwest1 +alyssa08 +28071991 +geraldo +dadmom1 +oscar10 +19101984 +121975 +happyone +31011987 +sirisha +181091 +band +21111990 +cordell1 +14011986 +maggie14 +23011986 +live4life +dallas9 +napoli1926 +fireworks1 +13091990 +111083 +310887 +1johnny +dabomb1 +300890 +181291 +041085 +200483 +atchoum +golden +08081984 +stella2 +190889 +101177 +22021983 +yjdbrjdf +fashion101 +200384 +11011985 +11091992 +lisa69 +08021987 +020672 +danny23 +othello1 +chevy4x4 +scooby22 +10011983 +654321b +dakota22 +fercho +nacho123 +men +gosia1 +hektor +18041984 +fly +1406 +12091985 +05071988 +widescreen +jacky123 +13051989 +gr8ful +millonarios +steiner +19011990 +steven14 +click +jamie13 +micaela1 +maxman +katie7 +redlight +softball19 +alexander. +mohawk1 + +almighty5 +courtney3 +catalunya +hershey2 +tigers5 +diavolo +marat +180485 +05071991 +password1234 +28041986 +jobs4me +emmajane +18041988 +godfather2 +contact1 +020283 +24111988 +penelopa +4321rewq +03011987 +miranda12 +elliemay +jessie3 +family22 +bunny3 +inlove123 +labello +money00 +290991 +alex26 +280484 +25091985 +sexy56 +cimbom1905 +29111991 +28061990 +sunshine25 +23071987 +qweasz +110482 +njhygtftb567 +080884 +28121984 +calendario +28081988 +130782 +rfhfrfnbwf +satori +asshole8 +clementina +210580 +7272 +destiny09 +christ12 +400052 +jasmin3 +1234567x +100782 +orchid1 +16101992 +241092 +сергей +22121982 +happy09 +apples22 +wolverin +19071986 +lovers7 +13111991 +frenchy1 +siddiqui +inuyasha! +231292 +hollow1 +220492 +100183 +y +diva09 +shane2 +sasha01 +metallica1 +smash1 +ty1234 +agape1 +moss84 +021282 +xj453cxdxq +bonner +dumass1 +bloodline +01091984 +04071986 +28041989 +190487 +170385 +fruitloop1 +daddyo1 +flyguy1 +donner +mayra +1902 +20011992 +seniors07 +javier13 +270585 +terry26 +cortes +01091990 +300584 +tooter +41414141 +1bowwow +yoville1 +jumpman +dapper +26101991 +guitarist +devilish +vero123 +tasha2 +pal +logical +101075 +galina +270886 +160781 +everyone +yankees24 +springs +kaykay123 +loveme15 +pretty21 +elegant +mother22 +monster1 +061188 +darkness13 +thematrix1 +25121984 +107107 +010178 +barbara123 +29121989 +space12 +230983 +loveno1 +123456789! +170183 +06031987 +forgetful +255225 +01121987 +houston3 +200984 +aezakmi123 +mmklub +fortuna1 +rico123 +shadowman +05051984 +shaikh +13101985 +lissette +exclusive1 +411037 +koolkat1 +stepanov +24101984 +wateva +tryagain1 +fahrenheit +22071992 +gv5235523532 +100982 +jake21 +123abc! +190386 +lausanne +190390 +131081 +250682 +hon +jumbo1 +271283 +skittle +juggalo666 +timothy +loveisblind +12hat93 +30101989 +02011985 +bee +311083 +monkey03 +02041984 +200583 +qwqw1212 +themaster1 +pinkish +100581 +seahorse1 +hubbard +123456abcdef +maranello +dynamic1 +g00dpa$$w0rd +barlow +310390 +24021988 +310588m +taylor24 +alexis8 +panther3 +beasley +turkey2 +js1234 +annina +debbie123 +music40 +antonio11 +15101989 +1a23456 +qwertyu12 +050889 +1478963250 +241080 +120781 +sephora +13021988 +22121984 +anna1987 +stone123 +password!! +010987 +kimber45 +wolves12 +russel1 +iceman123 +sharon12 +ferdie +skooter +logitech123 +money. +poohbear10 +asimov +230992 +sand +tiger45 +mission123 +johnson12 +secret22 +24081990 +horseshoe +puppy11 +juicyfruit +1booger +tuppence +megan3 +29051989 +13081990 +desant +autobus +hunter98 +270683 +26121991 +manusia +masterp1 +22041985 +p3rat54797 +who +crips +sexylady12 +123123k +pacopaco +03041985 +juliano +24061991 +redstone +909909 +solid1 +301091 +bigshow1 +morrissey1 +vovochka +ferrari +12181218 +miguelito1 +13031984 +rockon12 +mtndew +150593 +metalcore +nokia6131 +30091987 +codeman +080898 +16051986 +17081990 +virus123 +robert8 +190187 +020889 +051085 +10z10z +purple20 +mouhamed +noviembre1 +02021981 +bingos +nathan02 +nemo12 +110992 +12011986 +magpie1 +architect1 +naruto8 +noah12 +131283 +070988 +n1cholas +atilla +oluwakemi +26121985 +urban1 +061184 +carolina +24011987 +zombies1 +28051988 +buddy1 +28061989 +hellsbells +05101987 +blueeyes2 +hotguy1 +12021984 +071289 +zxc5555 +shelby3 +26101990 +kisser +27031987 +hotass1 +yesyesyes +27101992 +123z123 +raju +iforget1 +snapon1 +14111988 +granite1 +pau +lililili +teresa12 +lifesux1 +270485 +18031986 +hayden12 +14071985 +041090 +24071991 +amanda88 +qweszxc +221180 +freedom8 +ski +gummybears +devious1 +jayden10 +cameron8 +surveyor +carrasco +altavista +25522552 +30091986 +lemah +bading +31031990 +marie19 +09092009 +wesley123 +cascade1 +546546 +31031989 +julchen +030288 +tycoon1 +161181 +gold12 +a1b2c3 +13081986 +benedicte +puta123 +shy123 +9875321 +tundra1 +kola +16071985 +24121981 +27111989 +trash +taylor98 +19081989 +g86ua5qsn5 +millions1 +oneill +24061985 +14041993 +babygirl98 +220283 +godess +bigboy10 +stunna +parker +240290 +16041986 +monarch1 +27051991 +180491 +150682 +flowerpot +18091992 +a101010 +ilovegod7 +11051985 +pinto +16061985 +170383 +318318 +246810a +emperor1 +08091988 +13051990 +140691 +getmoney7 +sarkar +rororo +peace2u +lawson1 +danman +1233456 +soulja +nickel1 +090688 +412412 +25061990 +14091989 +120677 +crystal11 +goodgod1 +scampi +241191 +laurence1 +16091987 +champagne1 +101277 +200785 +takahiro +gasolina +260389 +25021985 +197912 +100992 +20011991 +megaman2 +tiff123 +24051985 +fucking123 +adrian +keshav +tat +basket23 +filipp +ajajaj +tenshi +chuchu1 +ilovejoey +lemontree +baerchen +bakugan1 +23021993 +16051990 +kevin08 +bomba +monkey94 +gingin +bicycle1 +171084 +28041991 +torrente +03021987 +fuckoff6 +abhi +loving123 +16011986 +1920 +22091990 +skinhead88 +nathan04 +badboy01 +l0vers +maxpower1 +291082 +280483 +16041992 +101296 +lifesucks2 +batman88 +lilyrose +157953 +159753z +iloveu21 +sweetcheeks +23322332 +21091988 +playboy5 +tigger9 +180787 +winnie12 +19111990 +skysky +27071992 +baboune +pooh16 +blackstar1 +hottopic1 +peppy1 +year2000 +greenfield +iloveme22 +04061986 +26051988 +killyou1 +fartface1 +martin22 +887766 +tyler99 +pass123456 +110893 +kitten13 +amber15 +vfcmrf +haircut1 +221080 +250982 +speed2 +280186 +23091990 +karen13 +spark +movie1 +staci +apple! +28041990 +dragon45 +jackass5 +020489 +26031986 +25031992 +password-1 +truong +20051983 +raiders69 +allday1 +1307 +k43a5vztox +password84 +buchanan +iphone3gs +canelo +998899 +monopoli +government +matros +qwqwqw12 +05081989 +181084 +greenday11 +0204 +fuckit12 +250783 +anirudh +adewunmi +soap +allright +lukasek +windex +roudoudou +111280 +fabian123 +toyotamr2 +15081984 +markus +01041984 +chickie +maria18 +m11111 +darek +sieben +231079 +dreamcast1 +autumn12 +1redrose +03101988 +hemalatha +17121992 +dragao +sojdlg123aljg +arquitectura +sprinkles1 +22111984 +amit1234 +kalamazoo +jacob07 +bomberman +12111988 +kaykay12 +techdeck +11love +navy +gladiatore +e10adc3949ba59abbe56 +600010 +chadwick1 +04091986 +04071990 +cheese10 +28071986 +chessie1 +lovers11 +football90 +06021988 +nope +golfpro +260585 +231986 +delarosa +270888 +spring01 +19091992 +passw +011288 +татьяна +arselect +foxyroxy +badgurl +2711 +niceone +rubyred1 +27121988 +27021985 +yamina +shammy +1trinity +cutie#1 +saturn5 +infosys +valentina +amsterdam +cannes +12011201 +coimbatore +amber22 +10031983 +ines +vfhbfyyf +v1234567 +07021987 +popper1 +oscar5 +godisgr8 +mybabies3 +tuffy +snehal +corina1 +derder +spring11 +orlando12 +courtney7 +180390 +honey6 +realdeal +я +raiders#1 +kellyann +20021992 +11101984 +tupacshakur +loser9 +ronnie12 +100693 +blackhorse +magnavox +03041988 +sarajevo1 +18051991 +nicole33 +mylove23 +balogun +241180 +chaingang +02061992 +58666z +eliott +alex97 +280189 +29121988 +concha +honey +andrew25 +pizzapizza +patito1 +302001 +17111988 +07081985 +30111988 +051187 +shit1234 +22021984 +munchies +4yfb2s753c +24011989 +180882 +bestbuy +normal1 +270387 +agent1 +20081992 +sagar +maggie09 +killkill1 +celestina +ktyxbr +260186 +17011988 +2smart4u +matty123 +jessica99 +flintstone +luckey1 +28021989 +fuzzy123 +summers1 + +28061988 +1234555 +alena1 +timothy123 +marshmallow +20111988 +siamese +jackets +030887 +ceecee +06031990 +180790 +mommysgirl +22121983 +150782 +140384 +16021991 +240582 +loxlox +322322 +10031985 +montpellier +20011984 +pitbulls +270686 +mara13 +19081985 +31071985 +bunbury +240491 +anasofia +332233 +02061984 +140485 +leann1 +100983 +211191 +confidential +010509 +22111988 +sexymami1 +heaven3 +seagate +181190 +exodia +osman +23111985 +1qaz0okm +therapy1 +10101995 +110880 +precious +masamune1 +estelle1 +041285 +hihi12 +escada +mccartney +ardilla +plant +040687 +mignon +290787 +jamies +200784 +290888 +22031992 +recruiter +�: +saywhat1 +211212 +bub +121276 +110183 +lovers. +bobbobbob +dima2010 +010177 +flirt1 +090388 +247247 +ester +pokwang +mailmail +gabriel11 +rambo2 +7788 +topnotch1 +3daughters +alex2539 +999555 +hullcity +20051984 +goldstar1 +camcam1 +salado +31081988 +secret13 +auralog +220580 +160386 +10081993 +edu2008 +blood55 +austin15 +rose21 +ingeborg +nbvfnb +120380 +1901 +jason1234 +chester3 +30101984 +6exe3za97v +741963852 +skippy12 +legends1 +grandam1 +liarliar +raheem1 +121995 +110112 +220581 +rachel69 +aaaaaaaa +rascal123 +160692 +240191 +14121983 +cutiepie! +230192 +sexy31 +birdy1 +190583 +10301030 +13111989 +paolo1 +wg8e3wjf +lizzie12 +pastrana +recon1 +110680 +bullit +macmac1 +31011985 +monkey93 +02031985 +john7502gee +191190 +15091988 +twilight01 +06031986 +azsxdc1 +sassas +08091989 +stephen +jacks1 +rubyruby +290187 +richard11 +101096 +150283 +livingston +artur123 +vicecity1 +04121987 +121078 +babygurl22 +smith22 +iloveu69 +reyrey619 +400049 +30101988 +icecream11 +250387 +230691 +inkognito +tiger55 +cronic +27111986 +101991 +2301 +kimbum1 +odyssey1 +220784 +120594 +america1 +fucklove! +16011991 +abbygirl +alexis04 +17011990 +110064 +tinker7 +tw33ty +ufyljy +guildwars1 +18011988 +chaparro +yahooyahoo +cccccccccc +88002000600 +darek1 +lollies +whatisthis +lazio1900 +catita +110980 +iloveyou55 +290983 +130581 +23091985 +hellcat +swift1 +lancelot1 +london08 +rolex1 +eduardo12 +13021992 +17081989 +getmoney23 +18071988 +marlboro +jackson13 +171282 +18071990 +lovepussy +jade1234 +190684 +love.. +bubbles6 +yana123 +12051993 +sampaguita +dasilva +20071984 +110595 +260890 +tyler9 +pratama +123412345 +01031994 +jrock1 +toshiba123 +trilogy +ymhpnmj733 +atybrc +200286 +eve123 +160384 +gio +ishmael +pretty23 +miguel01 +asparagus +235711 +marie69 +buddy! +sasha777 +johnpaul1 +luv4life +180881 +020386 +matthew24 +colossus +nikki5 +adejimi1 +giuseppe1 +loren1 +211292 +22091989 +270385 +money777 +21011990 +sharpay +ngentot +cherry16 +spaniel +talon1 +cirrus +yxcvbn +01071991 +bannono8 +nothing12 +panda11 +upyours1 +kelsey13 +officer1 +30121992 +jason +280685 +bbking +minnie3 +subhanallah +300790 +matthew18 +28041988 +usuck2 +mariposa12 +01091991 +texas3 +20101982 +airhead1 +26101986 +ok +cheeto1 +billy5 +x0x0x0 +blitz1 +25121992 +a456789 +160784 +tiger24 +calvin12 +monkeynuts +260583 +nastyanastya +061187 +161280 +kuldeep +100792 +kids02 +xtvgbjy +18021993 +bullwinkle +111973 +rebel2 +moss81 +zxcvbnm11 +140683 +191085 +233233 +25091988 +stefan +july05 +monique3 +blue321 +live123 +nafnaf +waco254 +140991 +150189 +2207 +270792 +crush1 +honeyq +kourtney +19081992 +10051992 +01love +190991 +scarface7 +100381 +texas22 +090992 +acdc12 +sawsaw +sept15 +121272 +cel +pizza13 +danielle4 +031085 +24051987 +gumby +daniele1 +seabass +260491 +caracola +greenland +hunter17 +120477 +27111990 +17031985 +serpiente +bunso +iloveyou44 +250884 +250791 +10151015 +daniels1 +spencer12 +asdfghj123 +14111990 +sunshine18 +1133 +071288 +250283 +michael89 +hasan123 +madyson +certified1 +300188 +shelter +skyline123 +17081987 +rasheed1 +260682 +surfboard +180880 +rewind +1й2ц3у4к +constanta +emilyrose +27031992 +2kittens +240891 +01041992 +280985 +240984 +09091984 +03051989 +iamtheman1 +boston5 +248248 +bat123 +benladen +brandon24 +24121992 +15041985 +290890 +harrier +helphelp +17061985 +dumbo1 +das123 +pharmacist +160185 +mexicana +30051986 +keens_1 +fktrctq +firedragon +малышка +slapper +445544 +221280 +poodles +jurgen +ilovejeff +salman123 +lovely14 +sexy666 +hootie1 +14021983 +majiajun8888 +patches12 +redtruck +chatterbox +b1b2b3 +wheels1 +watsup1 +14091988 +angela13 +pipper +offroad +15021986 +198724 +olympiakos +200391 +buenosaires +520000 +131091 +190886 +amira1 +trails +050190 +brooklyn11 +marie93 +flowers! +scumbag +denmark1 +130982 +260584 +27031991 +03121990 +123e456 +onepiece1 +051087 +dionne1 +210192 +saddle +15061984 +diesel123 +13211321 +germain +hao123456 +150791 +04051989 +football29 +050787 +partytime1 +19101992 +110481 +day123 +240483 +sh0rty +110792 +sept21 +nowayout +triston +nando1 +190685 +26091991 +241181 +rock23 +071189 +14031985 +nicole04 +230980 +061291 +basilio +kitty21 +this +10071984 +zzzz1111 +pussylicker +31051985 +loving2 +lovergurl1 +coltrane1 +070785 +adidas13 +abuelo +manage +67chevy +tiktak +28051992 +davey +bruxelles +aaron7 +myspace66 +not4u2c +blinks +26021986 +290485 +emo4ever +251181 +honda22 +amber21 +woodpecker +150985 +111a111 +vampire +southside5 +400022 +orion123 +carros +equitydev +030788 +maxwell12 +30051991 +14041991 +paperina +jonathan23 +restaurant +11121992 +rooroo +babyboy21 +100580 +140884 +020291 +opera +11011988 +18051992 +101099 +07071982 +buddy21 +amber16 +supernatur +ludwig1 +blondie123 +julia2 +blanket1 +bmw330 +habitat +123456dd +pony123 +010010 +bear69 +hartford +vasilica +winnie123 +levis501 +butterscotch +guadalajar +20111990 +breath +08081989 +070777 +200486 +dumbo +bethan +britneyspears +james99 +nesha1 +kickers +rock22 +surgeon +heather13 +shelly123 +freakshow1 +tattoo2 +280192 +kosova123 +lavidaesbella +111115 +blueyes +nacional1 +pisello +blazin1 +10081992 +loverboy69 +june03 +280880 +solyluna +tickets +010385 +bestman +nikki23 +george21 +19011991 +190387 +william14 +poopies1 +baby66 +swindon +01021983 +nokian97 +creamy1 +pebbles123 +james05 +sports3 +divinity +18011990 +fields +13456789 +17031993 +nada +2good4you +swoosh +181284 +05031989 +forreal +berlioz +maxwell1 +280787 +hockey09 +wilbert +1hustler +250782 +niners1 +nicholas10 +300885 +130579 +amari1 +gat +2203 +strega +fktyjxrf +thick1 +260285 +cat101 +boogie2 +steveo1 +gotika +jaden123 +********* +muslimah +waldo +04081988 +catolica +wassermann +160482 +040886 +look123 +kissass +010887 +22021993 +19011988 +sandip +09071987 +14021402 +andrea15 +kitcat +1qwertyuiop +7532159 +lowell1 +010483 +110282 +buck12 +15061992 +16091991 +franny1 +azeqsd +8vfhnf +12071983 +300383 +cervantes1 +hanhan +melone +insanity1 +230982 +31081987 +janae1 +angwar77 +kitty1234 +5432154321 +..... +27101988 +donsun123 +samantha. +football68 +texas23 +tootsie2 +jayshree +batgirl +sept18 +20042005 +superdog +david20 +28061986 +151082 +24021987 +18031991 +200190 +sebas +password321 +7uqbwx8n4z +honda2000 +30111987 +brett123 +emily6 +marky1 +cutiegirl +barbos +reyrey1 +31101985 +020382 +nikkie1 +281183 +gunsmoke +logan3 +erica12 +02121987 +music69 +kingman +09071990 +17011987 +google4 +a12321 +nor +19081986 +melissa4 +131986 +taylor00 +ronaldo7 +17051989 +lam +tommie1 +190691 +july06 +leander +diddy1 +261081 +jade01 +matata +dredre1 +21111989 +03051985 +29051985 +takuya +fuck1you +06061984 +inuyasha11 +29101992 +lili12 +jeremy23 +qweasdyxc +antoha +helloyou1 +22091986 +290684 +lilsis1 +bree123 +240983 +23101983 +020484 +198606 +19031986 +pinecone +231281 +method1 +101278 +august07 +270482 +deinemudda +sunil123 +07041987 +dental1 +motherland +classified +kappa1 +abigail +green19 +20071985 +pass +avensis +elocin +nb +04061990 +triangle1 +frogman1 +saruman ++++ +blunts420 +17051984 +redstar1 +install +m00m00 +07081991 +cupid +1dickhead +111178 +1derful +huf7dkgd +27041991 +dentista +metalica1 +pooface1 +mabelle +kinky69 +miguel +sunbird +dancer10 +sho +30061989 +14251425 +blue26 +ripper6 +rosie12 +йцукенгшщзхъ +volvos80 +kevin16 +rossignol +251081 +123z321 +destiny +swagg1 +150681 +310886 +170886 +simone12 +shaggy69 +starstar1 +13071992 +fatdaddy1 +� +nygiants1 +171283 +230483 +lollo +damascus +nicolas2 +03051988 +kamasutra1 +mamasboy1 +140681 +freddy2 +lineage2 +10111982 +jeannette1 +14091991 +rangers +s1s2s3s4 +250182 +a12345678 +bassist +290584 +dance7 +jess13 +03041989 +04071985 +badooo +james88 +black24 +dennis01 +orleans +05021985 +fottiti +051184 +27111987 +ash1234 +softball25 +apples01 +fuckyou1 +qwerty123 +ade123 +football63 +malabar +ten +ilikepie12 +25121982 +13011986 +012369 +cody14 +marcus3 +forgive1 +24gordon +11051986 +girlgirl +alinaalina +25111988 +marmota +letmein01 +lovely10 +giotto +nanna1 +271191 +lyndsey1 +florencia1 +2122 +010485 +17011991 +300991 +ktm250 +simona1 +carlos. +atreides +554466 +america100 +london09 +thekids +jeanclaude +hondacity +medecine +paulus +anthony20 +11081985 +moctar +maroc +150192 +070688 +greg12 +marianna1 +alex55 +01041993 +19061985 +220880 +bayside +28101992 +1welcome +16021986 +bilal +choupi +010785 +gaga123 +babygurl4 +love83 +16071991 +369741 +dominik +molly22 +123456789r +191184 +29081987 +klara +matrix3 +demetrio +nakata +19031989 +metallica. +katie4 +baseball77 +starwars7 +kazuki +football93 +120894 +lothar +beyourself +vhbth55jec +gato123 +fozzie +01012007 +connor10 +jobless +dylan5 +miespacio1 +zrszd9p238 +pink92 +was +300491 +17121983 +24101985 +220782 +rascal12 +10021002 +240584 +allana +11111982 +shelby +integrity1 +ukflbjkec +bugbug +kiara123 +seasons +rjpzdrf +boeing777 +babypink +smokey5 +14151415 +111992 +97531 +lion12 +inday +230592 +fairfield +bunny5 +emily07 +090890 +jorgeluis +november +piotr1 +cleaner +199414 +180591 +24111986 +spikes1 +654321z +pooh01 +161281 +15121991 +diana2 +261291 +291084 +800000 +29091986 +bioshock +bitch20 +michelangelo +reina1 +02031990 +21111988 +mydarling +june123 +rockport +neworder +310582 +badminton1 +29041990 +1245780 +nicetry +kfgekz +tea4two +momo1234 +a123456z +201280 +loko123 +scotland +elmer1 +mikevick7 +kuttan +bornagain +vidaloca +tar +26111987 +18111989 +spamspam +dino12 +19051984 +spooky13 +thebig1 +169169 +pokey +27121987 +120878 +analucia +romans1 +lucky1234 +19944991 +060891 +gamer4life +toontown +270384 +fernando +remedy +27031989 +130192 +scooter01 +beasty +666hell +28081987 +mustang! +freezer +tiffany11 +thebomb +20011983 +190790 +19111984 +mike420 +friendster1 +player101 +hahaha. +18041985 +simple2 +heller +symone1 +220781 +19061992 +frozen1 +brandon05 +198725 +mojo123 +29101988 +mysp4c3 +1billion +120779 +tommys +23071992 +19041987 +murillo +ziomal +franki +arctic +vasya +121298 +070590 +goldgold +rapture1 +05031988 +zanetti +chukwuma +140482 +12081984 +bcnjhbz +aracely +03081987 +morgan6 +123498765 +micheal123 +06041987 +bigsis1 +giants56 +fuck!! +1705 +grandma7 +muffin3 +she123 +290490 +24111992 +071187 +iop890 +friends09 +130182 +waterh2o +1712 +salsabila +100393 +jackie7 +180988 +elmo11 +homo +flippy +gabriel5 +dima1234 +italiana +diet +290785 +09041986 +adedayo +carling1 +280792 +agnes1 +zh8o9ly3gi +marusa +papagaio +25021989 +05021987 +shadow25 +shannen +10041983 +030488 +230282 +19031992 +20111989 +120494 +31071990 +aaa555 +benito1 +mitica +rucaxefu +pepe12 +080585 +25071984 +190389 +division +asd123qwe +password97 +poopie12 +jolanda +041086 +040887 +rumble +11071984 +014702580369 +1hahaha +17031990 +diamante1 +canterbury +honzik +vanessa10 +200786 +11031103 +05051993 +bannana +cornholio +151092 +cuntface +murielle +jhenny +gitana +thumper2 +halo11 +morgan21 +scoobydo +cookie24 +110901 +nehemiah +password.1 +21071991 +tortuga1 +jake99 +nanita +13071986 +aravind +happy100 +andria +27021988 +210783 +chuchay +laker1 +jason08 +2469 +welcome01 +wishmaster +faith07 +lucky09 +starla +duane1 +220592 +money45 +221093 +02041983 +boom12 +13081985 +satanic +giovana +lolo1234 +talking +benjamin3 +elevator +200883 +jigga +donnell1 +angel66 +dflbvrf +001975 +rikimaru +taylorlaut +brook +mixail +200282 +august06 +18081992 +bagpuss1 +pinball1 +shield +18071986 +thecrow1 +softball33 +kopa1961 +deathwish +complicate +120495 +pallone +amanda8 +copacabana +040686 +mature +freestyler +030692 +texas01 +red666 +bisexual1 +rajesh123 +25111990 +040587 +22071990 +030586 +friends22 +18031985 +shanti1 +19081987 +hummer3 +061087 +soares +samsung22 +katie! +919293 +red111 +surya +jennifer. +pomona +290783 +hawkeyes1 +hersheys +marvin +vanbasten +idontknow! +ily143 +domani +andrew20 +single13 +baseball55 +quintin +2apples +football98 +030889 +babyboy14 +prince13 +050685 +saab93 +sanluis +21051992 +ikaika +starchild +cookie99 +15051981 +141092 +270582 +01121989 +john12345 +120478 +password_rr +musika +adamant +usa12345 +31121983 +can123 +18101992 +tigers21 +batman24 +sevenfold +rfghbp +spirit123 +1346795 +labelle +joyce123 +serhat +bratislava +scarface3 +cornelius1 +shadow06 +020786 +01061985 +gibson123 +connect4 +harrys +160385 +buggie +rocco123 +lilboosie1 +nathan14 +w1959a +22011985 +140785 +licorne +ranjit +optic99 +class1 +23031983 +silvano +ophelia1 +01071992 +22122212 +buck123 +anjink +qqqqqq +roselle +951623 +98mustang +emailonly +spanner1 +tazzy1 +123123qweqwe +hayhay +lefty +djeter2 +tinker5 +lionne +commons21 +maisie1 +2404 +321000 +tiddles +bowie1 +09051986 +sexy123456 +18041986 +250483 +206206 +414243 +08121987 +holanda +ladygirl +pimpin4 +28031987 +disney01 +asdfasdf12 +heyjude +18091984 +tylerj +5girls +1icecream +anthony03 +25011989 +sarahh +mustang09 +tokyo1 +perrita +++ +098 +01051989 +cliff1 +babamama +pilates +padfoot +rockroll +210692 +030585 +aspirine1 +08061988 +thaddeus +260286 +thesimpsons +chair1 +rafael12 +snoopy23 +jenny23 +daisy10 +alex91 +lala01 +031190 +18041989 +sluggo +lolipop0 +08031985 +twinkies +chilli1 +060696 +distance +giovani +jenny3 +31081991 +030384 +5alive +200202 +5fingers +british1 +california +nini123 +caligirl1 +matthew99 +enchanted +snowbunny1 +masha1 +1dakota +memyself1 +13071984 +4grandkids +nikita1998 +amarachi +party12 +walker12 +pinewood +23011992 +16071988 +wiseguy +true +25071988 +danny69 +travis11 +sean11 +1andrea +nokia6230i +greentree +110055 +1508 +12041993 +cutecute +220582 +standart +kristoffer +domination +lovepink1 +jean12 +280391 +starwars5 +redneck123 +antichrist +123589 +18031992 +1brooklyn +egypte +kroshka +sarah21 +bullet123 +19391945 +babydoll12 +sherrie +rebel01 +milena1 +14121984 +kibbles +31081986 +shiva123 +311084 +juve +nirvana! +kylie123 + +28021987 +shakur1 +freelander +palestra +pamela12 +280187 +dimitris +cigarette +01031983 +150784 +kolokolo +0606 +parent +qwasyx +pashka +1234567809 +joseph09 +marvin12 +sarahb +pulpfiction +tyrant +kot +skidrow +babygurl23 +prizrak +andrew1 +01101985 +longboard +hatebreed1 +1234zxc +marcie +picsou +ceecee1 +1234er +break +monolit +pfhfpf +123kids +whatever123 +carcar1 +ilovehim7 +mike12345 +nazareno +11111981 +181292 +innuendo +klokan +shady123 +budlight12 +sirenita +rebelde2 +16031991 +martin21 +carlos19 +booty69 +loveya! +excelsior +silvietta +05051982 +02071982 +171291 +25101983 +smokes1 +190489 +thomas9 +loko13 +23121992 +ositos +09041990 +kitana +peter +trueblue1 +hellome1 +madison03 +170384 +jenny5 +070887 +horseman +23111986 +hello33 +4mylove +18061992 +test1234 +08150815 +160685 +290686 +270684 +fermer +24121985 +01071984 +12061206 +brooke10 +monkey96 +cameltoe +120793 +15061986 +07051990 +dblock +doudou +061086 +farting +salim +fishstick1 +bailey21 +mollys +morphine +maryjane! +swifty +luisangel +haley12 +toby01 +chicos +11021984 +strongbow +mybaby123 +021292 +160188 +140784 +friendster +allfor1 +sweet19 +marcell +260681 +29101986 +brandon19 +261091 +villa123 +030785 +202202 +hotboy123 +24111990 +khulet +puppies3 +291089 +jimbo123 +truffle +t-pain +03011991 +080390 +04081990 +07831505 +ninini +bunny69 +123423 +03031985 +marin +tumama +laura +estrella2 +chair +monkee +11031984 +savanah +1qasw23ed +yungmoney1 +robert25 +sabotage +kissing1 +adam22 +gismo +1324354657 +21011992 +153351 +raining +kali +kbnthfnehf +sweetbaby1 +sugarpie +151080 +deedee2 +20041984 +nicole95 +uniden +killa13 +bubba22 +rosary +fifa2000 +japan123 +dianna1 +03071990 +30011986 +baseball03 +volkswagon +220681 +fri3q9arjg +potatoes1 +rome +jakarta10 +654312 +14111984 +bluecat +fatboy01 +katasandi +121005 +sham123 +200383 +voltron +22101989 +05031990 +220792 +dipset23 +a77777 +myspace321 +courtney! +werty12 +nessuno +speedy +2306 +110187 +050886 +neng2000 +080883 +tiger007 +17041988 +purple26 +baltika +schweden +31081989 +casper22 +fart12 +31051989 +goober2 +heaven07 +6letters +251082 +assasin1 +hiuyt75f +da1nonly +one2one +metals +bigdick2 +amidamaru +wilber +marques1 +rams +safari1 +nasir1 +220382 +260791 +christmas0 +asdfas +burnley +reznor +05051983 +masaki +cartel +nightwing +king12345 +400708 +brittany5 +jamie11 +ebony123 +royale +20101993 +newyork! +lolz123 +f15eagle +1664 +lindsay +enamorado +powpow +110780 +nigga7 +pepper99 +josh17 +moosey +20121984 +lauren6 +hejsan1 +warcraft12 +reunion974 +08031986 +20071992 +210582 +ghbynth +francois1 +030385 +morgan +fucker7 +hacker12 +11031992 +clean1 +toohot +biking +dogwood1 +fucktard1 +vans12 +12345678o +74747474 +skyline2 +valentino46 +26061992 +kayley +15061989 +cvetok +circle1 +ilovemylif +6669 +worldwide1 +26011991 +050786 +htown1 +altima1 +bigbass +carolina23 +glock19 +sczouvie26 +stronza +151280 +myles1 +margo1 +travieso +20041992 +1804 +16051985 +teaching +apteka +faggot! +mano +winter05 +animes +5bt2jtztke +dani1234 +jackets1 +19021986 +22558800 +muffin13 +jakedog1 +240681 +091090 +minnie01 +r3m3mb3r +28031988 +calamar +liberty2 +martin7 +abbey123 +161284 +180289 +03071988 +steelers09 +thomas24 +woodland1 +princessa1 +zwjbvhy184 +18041992 +071190 +18081986 +magnus1 +polska11 +seun20 +schatje +skittles7 +root123 +austin03 +050582 +darkmaster +babygirl0 +6565 +farscape1 +charlott +24011990 +16121992 +deirdre +iloveyou32 +74a82s78 +nokia5228 +king88 +stars5 +reggie123 +badboy22 +15111991 +florence +mueller +190984 +january +allycat +22101982 +skumar +31071987 +wojtek1 +scorpion +25071990 +3214789 +efrain +140792 +lovekiss +270391 +spring06 +29081986 +legolas +kronos1 +warcraft123 +05011987 +feefee +oiseau +teresa123 +jamesd +130692 +tootoo +daz3d +26081986 +300682 +221079 +joseph6 +eminem! +prettylady +belles +21041985 +geografia +01051991 +pitbull123 +25031989 +30101990 +090545 +playboy23 +darthmaul +19071983 +adrianne +break1 +300393 +austin +kane12 +retro +emeraude +1playa +20061992 +230291 +cookie +sakarya54 +familia123 +150491 +bianchi +141987 +25071986 +chaves +08051990 +modernwarfare2 +babyboy6 +delaware1 +15041992 +caligirl +12031983 +1spirit +4j9r4rnttp +27051990 +single11 +march03 +24031989 +thrasher1 +14101990 +170991 + +12111992 +198327 +20011990 +khadijah +computer9 +palmira +ginger23 +mahmud +b0ll0cks +marcinek +040586 +ginger21 +luscious +mike99 +chikita1 +deniz +05021992 +26051991 +kaizer +fallon1 +shreyas +mannie +010885 +123456789zx +130392 +051183 +201180 +dragon08 +260289 +polkadot1 +oleg123 +rahasia123 +11091984 +trogdor +drywall +nezabudka +19121912 +260191 +061282 +230580 +sweetest +sexo123 +121000 +rastas +05041988 +godislove7 +m000000 +091289 +17101984 +scully1 +wes123 +nathan99 +29121992 +adriana123 +change2 +jordan96 +14051986 +greatness1 +12081993 +jets +30011987 +baseball31 +vyacheslav +5jn16uxpid +ganapathi +my1234 +030883 +listopad +gather +kellykelly +stabilo +rama +destiney +ckiue73jp +karen2 +jenny14 +123blue +160887 +11011101 +almudena +16071992 +199211 +winkie +22011990 +buzzard1 +sk8er +060987 +maarten +parvathi +100297 +adelaide1 +dallas07 +250581 +babygirl33 +280385 +mufasa1 +05121990 +wwefan1 +amber10 +28081986 +1e +15091985 +santina +86402241 +baybee1 +boyssuck1 +xxxxxxxxx +cameron06 +yankees25 +success +privetik +2143658709 +tweety06 +kruemel +danie1 +ginebra +matkhau +before +twinky +18061986 +chan +juan11 +200683 +030489 +290489 +1478523 +181183 +gjpbnbd +123bob +naruto. +panther5 +11071992 +002200 +19071994 +thunder13 +bajaonel12 +77777a +prince10 +666xxx +eddie3 +03021989 +28031985 +cornel +lettuce +sexy90 +beautiful5 +sausages1 +170691 +cheerleading +20100728 +pizza! +coolio12 +duh123 +alyson1 +martinez12 +mit +aniram +1502 +ilovemyboy +26051989 +dancer09 +kirkwood +sexy93 +060991 +180286 +crabby +star44 +24091988 +ilovehim13 +baseball30 +1111111111111 +wingman1 +boracay +010986 +identity +stalker123 +301284 +27111984 +080590 +150981 +06081990 +070690 +27041986 +asecret +antonova +poppie1 +chico13 +nailpolish +superstar5 +2403 +calamity +10091992 +closed +zealot +01101990 +jacob08 +07021990 +haters123 +191284 +mark10 +270186 +chinyere +191189 +johnny6 +evgesha +02031982 +hughes1 +danuta +alhamdulillah +nmnmnm +macky +030379 +janessa +boyscout +010391 +dinamo1 +juneau +jessica25 +28111988 +cecil + +050490 +melissa8 +150980 +snuffy1 +22061984 +sunnyd +cottage1 +lauren. +310192 +tokio1 +elmo1234 +7575 +grady1 +alejandro +13021985 +harley883 +football57 +familyguy2 +09121987 +26101992 +danielle22 +gajanan +#1mommy +petersen +17031988 +eee +iamsocool +bartman1 +piero +liliput +123rrr +irakli +happy2009 +29011991 +02121991 +chiquis +100879 +08031987 +eagles +gloire +creed +1234pass +afonso +click1 +connor +18051986 +15011989 +weronika1 +panther12 +131001 +021290 +beautiful4 +elnene +heather21 +thomas1234 +lacrosse2 +sz9kqcctwy +808808 +lila +marine12 +031087 +charmed123 +itsallgood +gangstar1 +ilovejoey1 +baller25 +success1 +85bears +mensah +1lilmama +ggg123 +lilshorty1 +adeline1 +honda400ex +green07 +trey12 +lovers13 +keaton1 +erick1234 +051083 +sweetie7 +amanda20 +alkaline3 +luna13 +xiaoyu +15061983 +june2007 +271085 +zlenk77nge +sport123 +pink93 +420bitch +120596 +zaq1@wsx +13261326 +21091986 +morgan23 +22021994 +28462846 +31081990 +24051986 +28091991 +sheepdog +dfcbkmtd +789456q +barnsley +06021987 +nov +peace. +190486 +130880 +superfreak +margaret +300789 +198702 +sarah23 +slipknot. +124578369 +103 +soccer#1 +babyboy10 +asdasdasd123 +170391 +nic123 +15021984 +loopy +smile23 +19021989 +5q2w3e4r5t +blanche1 +jason14 +loser15 +290683 +randolph1 +finally1 +music14 +hs +sto +21081992 +yamaha22 +12041983 +1,00002e+14 +yamaha450 +monkey98 +tiscali +angel86 +kodak1 +kitten! +55555f +120182 +19955991 +121974 +1236541 +20041993 +261282 +010386 +jessem1 +itsmine +240680 +qwertz12 +iluvu4ever +190189 +tempesta +09121986 +puffer +sevastopol +batista123 +andrei123 +maeva +singh1 +viridiana +150393 +26111991 +fuckyou +florida08 +destin1 +15071992 +bball44 +dkflbvbhjdbx +12111989 +20202 +sadiemae +nights +brownie123 +killer90 +crash123 +2509 +nikki22 +1whore +lollipop9 +kankan +bastian1 +yoyoyo! +123456789qwer +defence +suckit12 +dickweed +shishi +24071992 +midwest1 +161182 +harrison +30091988 +27101990 +homes +198402 +logmein +elshaddai +nike1234 +121178 +bluesclues +anna2000 +rebellion +jansport +111179 +michael02 +2302 +kappa +nester +1forall +060588 +mollyb +1a2s3d4f5g6h +boxers1 +260784 +110281 +mayuri +141080 +pericles +ballin101 +13081984 +julio12 +210581 +14011989 +gemini6 +belvedere +jackass7 +080688 +281187 +devin12 +badromance +peters1 +estudiante +a8675309 +050189 +mamedov +evolution9 +160682 +300189 +26011989 +dallas41 +sticazzi +saavedra +qwertyuiopasdfghjklzxcvbnm +120379 +090585 +jaz123 +adidas7 +july2007 +xiomara1 +270184 +271083 +love200 +0909090909 +050691 +crunch1 +26111986 +jacobs1 +130882 +jeffjeff +560054 +raiders4 +mylife123 +27021991 +dennis11 +150391 +170783 +westlake +temptemp +050581 +linus1 +nbnfybr +progress1 +haven1 +jackie5 +27121986 +10071992 +hamasaki +treysongz1 +fuckme4 +jack99 +bitchin1 +nation1 +111222333444 +brianna11 +anarchie +03051991 +nerina +100981 +ryan18 +loveboy +sanibel +28091988 +hockey66 +1020304 +16111991 +cexfhf +flicka +26071991 +190787 +idiots +tomatoes +bitch19 +041089 +faith5 +08041986 +12121994 +020983 +1969camaro +040689 +144001 +meadows +rustydog1 +explosion +motorolav3 +1w1w1w +jomama1 +071088 +210981 +25122512 +brielle +interior +newage +10101978 +07021991 +asaness +spankme1 +19071984 +holycow1 +270285 +misery1 +davidek +viorel +matthias +punto +2cookies +1jason +30011985 +02031992 +farmboy +27091987 +jimjones1 +allison123 +melissa10 +fresa1 +211084 +m1m1m1 +debbie +freak2 +tazz +sophia +....... +goodday1 +jake08 +ybrbnrf +251281 +andrew03 +160886 +reds +austin04 +27031986 +bear10 +laker24 +scientist +sunflower3 +granny2 +tisha1 +aneta +miller11 +cookies4 +1dreamer +david05 +240184 +260582 +stolen +monica10 +21121983 +lulu22 +qzwxec +galleta +180484 +06081988 +411021 +blue28 +juandavid +216216 +190385 +galaxie +260483 +150595 +28091984 +mishel +good4me +blair +pass.word +crisis +tournesol +dirtbag +jeremy3 +barman +09071991 +12101993 +training1 +reason1 +12091984 +corky +09031988 +rhfcbdfz +loves2 +victory7 +scooby +senhas +071089 +yan123 +medvedev +280185 +guy123 +081287 +17011985 +z1z2z3z4 +lild123 +poderosa +22041993 +150792 +littleboy1 +144000 +larry2 +09121988 +boston617 +dicks1 +150382 +lbvflbvf +lovely09 +siegfried +wertyu1 +231987 +matthew17 +7555545 +louise11 +bradpitt1 +onyeka +honda95 +clippers1 +mysp +daniel95 +04051984 +23021983 +cornwall1 +vasilii +issues +venise +nayana +iheartyou1 +123cool +junior19 +1q2w +katie14 +260683 +cappuccino +lucaluca +240684 +241986 +nathalie +amor22 +141292 +egypt +17021989 +crystal01 +u123456 +david101 +bravo123 +karachi123 +030886 +ghosts1 +marissa123 +murphy2 +beryl +casita +260983 +100880 +dragon27 +screwyou2 +1angels +cowboys23 +kissmyass! +jerwin +hunter16 +yahoo13 +29041985 +busted4 +marie06 +030485 +terrorist +chesney1 +progressive +161291 +arquitecto +271082 +sick +nickie1 +08071987 +jh +purple44 +123564 +nigga69 +douglas123 +abstract +07071983 +freedom9 +marlow +290887 +naomi123 +12091983 +missy11 +17121993 +170782 +vandamme +19891229 +toothpaste +ghbdfn +17071984 +c44n6vijgc +301282 +qwerty44 +nicnic +may2007 +pizza10 +06071991 +112233123 +putanginam +honda150 +20041983 +slutty +hejmeddig +hennessy1 +lovers22 +05061988 +18121988 +04051983 +apples5 +bluedevil +westport +27061987 +sept13 +juju12 +fireman2 +pretty4 +livorno +26031984 +tina11 +chasse +juventus +shift +04041994 +hazel123 +1710 +15121981 +300583 +passion7 +manhunt +motherlove +gericom +5000 +eastside2 +pieces +199595 +041091 +21061992 +olivia08 +mumanddad1 +020383 +ilovecandy +ichiro51 +amormio1 +mitchell +peace22 +barcelona123 +qwerty91 +mahima +anna1996 +may1992 +cordell +03051986 +30051992 +310891 +jordan88 +11071983 +winter21 +lukman +jeezy1 +chicago1 +100479 +jess11 +volcano1 +23121993 +ckflrfz +21071990 +amorzinho +powerpower +vfhbyf +11101983 +marife +170884 +010790 +4everme +qwerty999 +marcy +patchy +26071988 +mitzie +magallanes +2405 +claire +29051992 +mexico. +daddy1234 +29061985 +060490 +26121992 +ilovemax +music8 +karsten +palermo1 +gus123 +040988 +cameron07 +kelly01 +060989 +love82 +07081989 +walrus1 +preston2 +caddy1 +tigger05 +27071986 +lovee1 +janika +010685 +ilovedan1 +1415 +stylus +eminem8 +2beautiful +210392 +270991 +081090 +kelly5 +18101984 +patrick23 +bitch12345 +cdtnrf +gotigers1 +sept25 +bitch45 +bouchra +missymoo +bubbles08 +123qweas +god666 +jason4 +11081991 +homepage +cjcbnt +anna1994 +twilight08 +batman15 +130791 +313001 +greenday5 +09091992 +melove +sara13 +pinhead1 +megans +babygirl32 +060787 +redrock +sravanthi +nicole28 +carley1 +dizzle +skate10 +tigress +iamcool2 +08031991 +700064 +160285 +girl13 +sexyguy +150484 +barbie5 +nomelase +rachana +fidelis +baby44 +matias1 +200983 +jsmith +brisbane1 +jesuis +natasha12 +13091985 +whopper +020294 +fellowes +candy8 +colonial +210482 +allstar2 +midnight11 +beyonce2 +bankole +250881 +040989 +16041985 +197711 +07071991 +iloveyou94 +bootsy1 +020884 +asdqwe1 +prishtina +ruffles1 +612345 +30011990 +210291 +marley2 +poohbear! +02121985 +adeola1 +angle123 +03091991 +070588 +ghost2 +america23 +071186 +twilight10 +02031993 +pass123 +maria16 +300492 +1604 +200292 +kick +1precious +02011982 +ashley04 +atlanta2 +bunbun1 +nic0le +ta123456 +67shelby +boo-boo +02011984 +09011987 +destiny06 +jayashree +benten10 +capricon +02081994 +6996 +009d9cc2 +05091989 +1nation +charming1 +131080 +sputnik1 +27011992 +twilight17 +blackbear +dragons123 +spenser +missy3 +thomas8 +neon +azazazaz +soccer0 +13051983 +andrei +1bullshit +03091988 +123100 +gtxtymrf +murzilka +11011992 +zxcvbnm1234 +dr0wssap +monkey97 +05121989 +061284 +bailey23 +04051985 +cheerios1 +06081987 +12345! +appleseed +redrover +03021986 +nariman +17011986 +26091985 +1warrior +l0llip0p +casual +cowboys31 +purple1234 +060290 +pandey +26071987 +250183 +12091992 +240683 +greenleaf +yura +raiders23 +boating1 +catia +1593570 +250681 +nfyz +butt12 +clubpenguin +141183 +29081990 +sasha1234 +snake2 +1chivas +kbpjxrf +271180 +getmoney4 +124512 +13071991 +170882 +milou +781005 +fatboy11 +baby#1 +220184 +05011990 +footballer +12358 +23011988 +22011986 +180586 +lol999 +11051982 +23061993 +poohbear01 +jennifer123 +11111s +1shannon +196800 +marina11 +110294 +130580 +030985 +1success +taken1 +tiny12 +050986 +05111986 +271092 +broccoli +dthyjcnm +stimpy1 +carcass +coopers +10111992 +16081989 +fuckevery1 +america8 +123qw123 +160286 +bratan +yourmomma +30031985 +15011983 +mysister +15031984 +051086 +020691 +falco +04101988 +ertert +windex1 +fighters +dragons12 +23111984 +poops +nathanael +mackey +ecstasy +040787 +gobears1 +borges +flounder1 +2loveme +002002 +421421 +zxcvbnm123456789 +monkey1 +10121980 +melissa23 +generator +caracoles +jayden11 +110184 +avvocato +janie +maxxxx +25111989 +getrich1 +crf250r +torchwood +casiopea +030790 +fuckyou!! +bedford1 +westside6 +281291 +15041989 +140584 +13pass13 +mechta +20011985 +honda5 +caster +23061985 +2324 +chilling +adamko +11091988 +poppa1 +johannes +justice123 +25051995 +alex1984 +passsword +01071983 +2506 +02011988 +scipio +12345678v +taranto +king16 +jessica06 +bobo1234 +10071983 +28041992 +backup1 +121007 +vargas1 +federal1 +2cool4you +austin97 +needlove +dubai +19871015 +janusz +21091989 +kokain +starter1 +ultra1 +09071986 +06051987 +texas21 +chucho1 +anthony88 +411057 +barney11 +kjiflrf +03081991 +040790 +silver23 +dodgers13 +020392 +270783 +020886 +oreocookie +jc123456 +08091986 +philipp1 +19041985 +rjvgm.nth +coolbuddy1 +310791 +qwer1234 +batman1234 +nichole2 +291083 +120895 +mollycat +dylandog +kitty666 +qwsazx +puffy +27021989 +123456pp +01061984 +vallejo +2109 +2r97xj3xey +gunnar1 +131180 +pescado +010783 +jasper13 +260185 +28061984 +roxy22 +880088 +198324 +anna21 +789000 +cristian12 +-9 +1605 +beater +leigh123 +alchemy1 +nanda +aaron5 +12011992 +270486 +ronalyn +15071990 +chalupa +adrenalina +sakarya +qwerty1234 +041185 +twodogs +28051984 +sales123 +aquafina1 +tiffany13 +........ +colonia +zzzxxxccc +longshot +hightimes +231180 +sadiegirl +bronx +hawaii12 +dawid123 +buddylove +29111987 +1810 +supermodel +longview +220780 +typhoon1 +honeywell +mushr00m +sunday12 +kissyou +12gauge +03021988 +18121992 +canada01 +11111992 +iloveandre +20111991 +ilovetom1 +elephants1 +qxxm93js +reboot +08071986 +jetjet +mariposa2 +25031985 +310184 +thinker +lauren23 +3214 +honey08 +27021986 +26051990 +hater123 +padres1 +slipkn0t +1612 +spartan117 +alien123 +21081988 +panasonic +spiderman +illusion1 +6yhn7ujm +lighting1 +giuditta +noonoo +willys +05081986 +essj408 +budlight69 +toxic1 +dogbreath +zxcvbnm9 +element4 +ukfveh +recycle +qwerty1992 +caravaggio +amanda9 +18031989 +sept17 +ddddddddd +170982 +sarge +norteno14 +14071991 +funnyman +iloverob +271181 +110280 +mccarthy +1lovehim +120181 +jonboy +st.louis +03101990 +199415 +family23 +musicovery +catanddog +ginger99 +hayhay1 +03071991 +101070 +11051983 +25051993 +300489 +13101982 +topino +081190 +oliver7 +scooter +asawaq +jackson22 +31051987 +123wwe +chicago5 +180185 +teddy3 +hawaii11 +06071988 +14071989 +14081985 +catrina +rishabh +24071988 +playboy14 +jasmin +02091991 +samedi +140185 +pussy09 +05071985 +mary420 +jet123 +newlife10 +firestone +cantante +aniket +condo +aaasssddd +112358132134 +chisom +060288 +analia +shadow55 +plazma +victoria01 +2h7vkzo266 +newjob1 +250680 +barbie +lindsey2 +19071992 +cubana +bradley +ds +carlos20 +camaross +pennie +rican1 +2503 +qwas12 +12021983 +lexus300 +chicano1 +bertram +ctdfcnjgjkm +091283 +aaa1234 +angelita1 +15111984 +document +morgan08 +philosophy +baller20 +05041990 +1qazxs +20081993 +04091990 +peaceandlo +mother! +190384 +linebacker +051284 +sept24 +peaches5 +loverz +thunder4 +august09 +270484 +79797979 +angelo +d41d8cd98f00 +codeman1 +momomo1 +120192 +smokey21 +160983 +300387 +rfpfynbg +precision +candi1 +15081992 +lakers24 +090980 +140383 +gibsonsg +jade11 +03081989 +flashlight +anderson +jackass13 +doomsday1 +islcollective +darla1 +2108 +forever18 +pilote +iloveu10 +24031991 +jada +google13 +mama123456 +06071990 +10281028 +29081985 +perrito1 +precious3 ++ +element11 +scooter13 +floriana +tanita +25061984 +pickles12 +011286 +firework +gabe123 +29061991 +1776 +22101983 +07091987 +hayden2 +14021982 +030486 +mine1234 +onelove7 +grad2010 +020782 +hater +ss +0412 +dandy1 +emotions +taylor95 +azer123 +sexy6969 +inlove12 +rockford1 +mercedesbenz +070780 +05021991 +blueballs1 +mustafa123 +5121314 +600116 +rofl123 +jeremy22 +osito1 +200582 +nas123 +olivia07 +020293 +061190 +casacasa +04051991 +ilovedave +1naruto +cuore +bread +23121984 +bowtie +hellou +manual +korn69 +7f4df451 +hoodstar1 +`1234 +24111985 +sanglier +7788520 +05121986 +lateef +23122312 +jayesh +29021988 +11081984 +21021992 +jump4joy +dexter01 +25091984 +01061982 +velcro +051189 +joshy1 +montag +140782 +redone +bebang +linksys1 +pervert1 +pretty14 +watford1 +johncena10 +28111991 +strife +maldonado1 +16051992 +ville1 +202020a +p4ssw0rd +ilikecheese +josh07 +cestmoi +123max +hell0kitty +billy7 +titan123 +nathan6 +yahweh1 +12101982 +tweetie +hastings1 +vespa +maggie06 +130481 +mickey15 +adgjm +dima12345 +280183 +dance4me +hondacrv +24071989 +tendresse +22091985 +bor +samantha9 +edward5 +mylovely +vivalafiga +milo12 +05071989 +demi123 +29091990 +x123456789 +erin12 +280983 +061606 +azsxdc123 +blue89 +coquito +060889 +rush2112 +dod +clipper1 +150185 +red101 +meghana +20021983 +ghjkl +burning1 +270190 +crafts +glock22 +takumi +resistance +daisyduke +febbraio +170791 +texas7 +anthea +jovelyn +saosin1 +270887 +zaq123456 +199112 +allahisone +24081987 +bukowski +merdes +09021988 +damilola1 +rohit123 +jazzjazz +vvvv +291191 +password1! +16031989 +busybee +kartika +090983 +yourmum +crusaders +patel +isidoro +ondra +miche11e +28101990 +jeremy21 +bandicoot +bigboy22 +rebel12 +101981 +120377 +mirage1 +180285 +sooty +23031984 +titti +grenade +111193 +021184 +nokiae71 +01011995 +diablos +elefant1 +dumnezeu +buddy09 +confusion +28051985 +cute10 +317537 +controller +flocon +macchina +honeyy +sascha1 +vehpbkrf +delirium +ladydi +pft +walter12 +161183 +saber1 +05071984 +blessed09 +25081984 +199500 +heat +03081988 +150387 +mauser +160383 +girlsrock +asdasd456 +717273 +280591 +26051993 +indien +fifa2008 +cuddles2 +shahin +310892 +pdtpljxrf +perrin +molly6 +jamjam1 +21051989 +lalala11 +passwo +200191 +160982 +21101992 +califas13 +morgan06 +271183 +orange77 +11qq11 +2812 +gemini21 +150282 +11061984 +x1x2x3x4 +seaside1 +mestre +liverpool6 +040685 +cheater2 +lollipop! +hottie45 +291292 +03121991 +justus2 +02061983 +27091990 +21031984 +081089 +ballin10 +150581 +cheburashka +pan123 +l12345678 +jerjer +290387 +121179 +tyler03 +yngwie +trashcan +lovers23 +hotguy +fishers +forever17 +poopy! +ячсмит +woodrow1 +13051984 +jojo10 +020591 +hope11 +300692 +011091 +online12 +martin5 +ponce1 +17071988 +010203010203 +nuggets3 +19081990 +260991 +01031991 +25081986 +alex90 +lovelovelo +vjz +shannon01 +198502 +1409 +180991 +alycia +22011989 +st3v3n +mikey11 +kingsize +qwerty2011 +198627 +199292 +27041985 +060886 +iiii +29081988 +nummer1 +sexyme123 +vandal +rosangela +bears85 +290186 +cognac +ciaoatutti +babyphat2 +stanford1 +artyom +290581 +17101983 +03061989 +180892 +azn123 +25101992 +farooq +heavensent +juan10 +hotboys1 +110194 +bowler1 +rfrltkf +frolova +1258 +daddy14 +friday123 +matt15 +spook1 +meeko1 +852852852 +bonita12 +abcde12 +17061992 +020584 +306090 +babe14 +nomad1 +lilibeth +tristan +020188 +candy9 +030989 +mymymy +benjamin10 +baller34 +190887 +chinaman +ss6z2sw6lu +020387 +vlinder +power11 +booboo +schnee +270891 +platina +suckers +140682 +100110 +sharon +kevin09 +12201220 +130781 +198618 +bubba4 +qq5201314 +saturne +111111k +campanita1 +05031991 +brooke! +mnbvcxy +260384 +a888888 +10121994 +austin69 +02021994 +vanessa01 +bigbro1 +29091985 +198615 +130682 +weed1234 +0210 +30071991 +26021989 +ilovesos1 +kathleen +nicolas12 +2lovely +leonida +pearly +sven +movistar +160683 +skater23 +billy3 +1725782 +13121992 +1metallica +qweqwe123123 +jimmy01 +03081985 +tupac123 +muffinman1 +010791 +friendofthenext18peoplew +instant +amour1 +230781 +brizet07 +15935746 +011087 +13101983 +071086 +stoner69 +skater9 +nicholas +reggaeton1 +southpark2 +twilight3 +joseph69 +junior05 +18091989 +ortiz34 +06121986 +manasi +hello77 +papabear1 +17081991 +jake69 +justus1 +10sne1 +alabama2 +ringo123 +ilove6 +robbie12 +17091988 +flower14 +talbot +whiting +197111 +123456yu +21051984 +170983 +241082 +blake2 +leandro1 +21101990 +babii1 +090587 +morgan14 +10031984 +061090 +kiera1 +26121984 +desdemona +myrtle1 +garcia13 +beautiful +161082 +191192 +gfdkjdf +22091984 +lizette +candys1 +partners +muffin +ali1234 +230981 +blackhawks +faith08 +george4 +celtics33 +232232 +john08 +24021985 +borman +qaz1wsx2 +rebel69 +tower1 +loko +lovell +ultimo +gold1234 +mal123 +biblioteca +earl +school! +infinite1 +091187 +newyork23 +2611 +171091 +506070 +timofey +jolie +0000000a +ford350 +27011986 +1honda +fuckyou19 +tara12 +lee1234 +forever69 +hotone +gilera +132103 +budbud +19844891 +ashes1 +patrick21 +roy +d2tqqn28tc +05061991 +locust +allison12 +07061988 +fish22 +tigrenok +fdsafdsa +prancer1 +redsox08 +1711 +411004 +1shot1kill +29061986 +25081990 +troyboy +manzana1 +cummings +18071992 +199216 +doggie12 +07081990 +jaijai +winston123 +13091989 +20111992 +03041992 +131280 +741741741 +03011990 +chloe11 +080878 +blueprint +nana22 +rachel21 +bordeaux33 +qq111111 +05031992 +200982 +13051993 +18071987 +cntgfyjdf +trueblood +220982 +linkpass +dimarik +8seconds +soccer98 +celticfc1 +nokia5610 +thesecret +asdfg2 +cjcbcrf +pink94 +16031985 +malacka +890098 +23021992 +br5499 +jailbird1 +topaz.null +1939 +151180 +stella01 +witchcraft +scorpio69 +bella14 +110380 +13111984 +030391 +170392 +69 +viktor1 +fahjlbnf +crystals +roucky +210882 +15011988 +yankees8 +050188 +91827364 +jesus06 +dimond +eagle3 +18111992 +kamisama +rat +chatchat +taugamma +catsrule1 +g-unot +08041988 +redwings19 +shokolad +yellow +17031986 +23121982 +180683 +96321 +cute23 +coolcat123 +050593 +500015 +09101986 +170883 +tommy5 +stainless +110579 +12345love +29081991 +epiphany +davion +310181 +140191 +01091983 +ballin08 +121077 +stitches +matthew15 +med +hello16 +211092 +ginger08 +230481 +shawty12 +150582 +302302 +elsa +robert19 +marshall +frogger2 +clemens +hallo11 +07041988 +16641664 +090982 +malika1 +zcegth +anil +ramil +ghtpbltyn +198526 +alyona +cara +addidas +16091985 +guitar. +ilovesome1 +13011990 +09021987 +monday11 +16111986 +famous13 +270791 +030691 +honda13 +dream2 +merci +vazquez +monster14 +sophie7 +aceman +its420 +225 +marocco +181087 +201291 +bratz10 +thuglove +776655 +qwerty54321 +25021993 +normajean +triston1 +werner1 +peeper +ningning +13011991 +13251325 +161191 +pasteur +hoppel +sassycat1 +1pizza +020692 +27051989 +18081985 +purple55 +valentine2 +gerbera +tarasova +mommy9 +menthol +lestari +26011988 +savanah1 +dragone +superman00 +beer12 +17061983 +10061984 +nickj1 +buster09 +197355 +rachel22 +inglaterra +christina7 +maryan +love<:3 +filou +090078601 +ginger9 +lolo009 +180584 +bulldog5 +180885 +alskdj +02021995 +05101986 +kings123 +tiger08 +test123456 +0123456789a +hulk +astronomy +sanford1 +estrada1 +juelz1 +georgia123 +karma123 +10081986 +05081985 +milky1 +20142014 +21071985 +lilmama13 +190784 +27071985 +vagina2 +fr +latasha1 +invisible1 +foreman +280292 +xfactor +19841985 +english2 +queteimporta +30041990 +career1 +anshul +norris1 +1newport +090490 +faizan +12051983 +jamaal +tweety69 +soccer66 +primo1 +18071989 +milesdavis +brian01 +hayati +football79 +125896 +santhi +destiny23 +bazooka1 +mookie2 +25081991 +babycoh +starwar +folake +polkaudio +shaq34 +21121982 +20021982 +251179 +29051984 +pisicuta +140981 +lady13 +27091985 +tr +27081987 +marryme +daviddavid +jorge13 +123@123 +need +21091984 +tugger +250001 +gforce +huang123 +140491 +bosley +15071989 +loka123 +melike +sexyness1 +290886 +forsythe +answer1 +fucker13 +12345 +1lucky +veronica +rouge +salty1 +temitayo +19041989 +ballard +280589 +211281 +050580 +gwapings +greedy1 +31031985 +schnitzel +welcome! +210992 +rajeswari +qazwsx123 +taylor97 +pencil123 +1catdog +nokian82 +qazedctgb +141281 +bloodyhell +240883 +defjam1 +destini1 +mother23 +060589 +justforme +jenova +190890 +reg +ludovico +ninja13 +291091 +2ndchance +280687 +a33k5afgdh +02091983 +07121987 +134652 +jesuss1 +stephanie9 +thunder9 +optimusprime +michael33 +sagar123 +madalin +sexy111 +fuckitall1 +divya +bhavya +261181 +my1baby +bhbyjxrf +12011993 +07091982 +spanking +manitou +imtheshit1 +catsanddogs +monster +garfild +spe +mimamamemima +hunter18 +120395 +alex1982 +allyssa +idontno +hot1234 +060783 +snoop123 +240992 +babygurl18 +banana01 +dragon87 +cayuga +vikash +qwerty93 +bobby69 +040388 +cammie +gilberto1 +zwilling +thepimp1 +maximo1 +2102 +redneck3 +170492 +shutup2 +stoopid1 +600034 +gunner123 +ballroom +iloveandy +jason24 +rockydog1 +combat1 +shazam1 +17041985 +richard13 +1luckydog +bigbad#13 +formula1 +paulino +180291 +160186 +180785 +alameda +hunter1234 +291092 +1309 +1925 +1yankees +zombie123 +4ever1 +130181 +03061992 +alejandro. +katmandu +060391 +198501 +100180 +14101983 +ayoola +money420 +teddy11 +fluminense +bandit +07081987 +justice7 +061191 +suzieq +ringer +manifest +290891 +yingyang1 +hitman12 +mendez1 +intrepid1 +father2 +fajardo +gjrtvjy +mikey3 +120193 +power7 +cameron08 +22081983 +27061986 +06081986 +carmona +27081986 +1qwertyui +04071987 +revolver1 +veravera +niki123 +240892 +101978 +currency +missions +pain +julie12 +samtron1 +419419 +onlygod +241292 +luckycat +narutouzumaki +snooze +peanut14 +siva +slytherin +04041992 +171292 +lozinka1 +29071988 +sillybilly +everclear +threekids3 +dima1991 +francis123 +boohoo1 +алексей +abcd1234 +carolina +pink44 +250981 +250891 +playboy15 +bubba23 +dodge123 +210493 +140680 +010305 +sharapova +robert9 +encore1 +starwars77 +ronnie2 +181083 +67896789 +devine1 +batigol +08121986 +ang123 +martie +password82 +bunny6 +jamie3 +asdf0987 +kunimi92 +tae123 +chicago3 +113311 +070891 +hugohugo +cute16 +june2009 +132546 +likeaboss +1610 +july09 +password3 +!qazxsw2 +turtle! +edifier +destiney1 +slayers +berbatov +crazylove1 +classof05 +wladimir +180985 +matador1 +regina +23051992 +230780 +pumas +30061983 +02051983 +platano1 +200692 +31051986 +correct +robert99 +07051986 +vwpolo +1597531 +160884 +281292 +dude23 +pentium3 +kinsey +280684 +26091989 +kiss11 +america21 +just123 +290591 +gryffindor +gustave +phoenix3 +kitten5 +tigger25 +babygrl +yourmom5 +kenyon +bangkok1 +nonnie +conor +sparky7 +28121983 +papera +jacob06 +elements1 +gregory2 +28011991 +181192 +30081991 +11111980 +pelusa1 +lauren4 +singhisking +tiffy1 +pepper21 +bollox1 +221176 +now +scarecrow1 +mattias +bocephus +janette1 +quintana +080388 +treefrog1 +226688 +logger +260882 +jason6 +sadie01 +123456gg +sanity +babydog +12456789 +kam123 +tongue +max123456 +aminah +gismo1 +020985 +silver33 +redsox10 +16121983 +07071993 +grace3 +qwert123 +killer89 +gethigh1 +biggy1 +gathering +ilovejamie +220981 +rosebud2 +12081982 +05091991 +buongiorno +qwe111 +kissme69 +genesis7 +crazy08 +monkies1 +tyson12 +homie123 +sl1pknot +290288 +blazin +madras +starry1 +gordita1 +fashion2 +puppy10 +ayomikun +09061987 +13061984 +australia2 +lynn11 +221985 +070782 +4peace +canela1 +199494 +riquelme +30061992 +napster1 +alessa +johnny22 +spark1 +230892 +killer16 +i_love_you +aguirre +198922 +hollywood8 +795001 +mike00 +cigars +300484 +21031983 +fffffffff +10111981 +muffinman +caribbean +110479 +04031987 +harakiri +891 +linkedin2011 +andrew00 +01021980 +sean21 +14101993 +09091983 +22121994 +17051992 +01081991 +kayseri +11051993 +motorhead1 +08061990 +municipal +zachary123 +booger7 +13141516 +260885 +jackson08 +tammie1 +30101992 +hashim +121996 +marie88 +teresa +ari +16071984 +pratima +winger +010692 +shakespear +aleena +300386 +rogelio1 +cowboys88 +04121992 +michael28 +lasagna +290984 +rocafella1 +010683 +fifa +summer2011 +poopy7 +jeremy! +962464 +maya12 +avondale +creed1 +awesome7 +morfeo +091087 +ac1234 +24091989 +moonwalker +29071990 +chris03 +4815162342a +gagagaga +191283 +golfvr6 +070791 +18111991 +daddy07 +xsw2zaq1 +250384 +caracas1 +s1t2o3n4 +180891 +asdfjk +ghjcnb +saudades +davon1 +007123 +joseph16 +batman101 +peshawar +25111991 +nielsen +fishing12 +180980 +15101982 +912401 +240481 +mazdamx6 +27071984 +sammie01 +sammy08 +199400 +danielle. +brutal1 +porno69 +dance10 +#1baby +honda750 +egorov +13071993 +enough +04041983 +zuzanna +210782 +mexico1234 +ryan09 +brittany15 +mammamia1 +ferrets +sevenup +jennifer14 +tomtom123 +aa11bb22 +kompas +100893 +everlong +goody1 +olifant +01061991 +411033 +1100101 +derp +22091992 +aaa666 +nov151963 +131517 +110678 +250393 +poppen +softball01 +jaymataji +corey12 +jimjim1 +daffy1 +garcia12 +isabela1 +dancers +badguy +104104 +hemligt +280582 +asdfrewq +careca +30061990 +123admin +aniyah +garner +kitty15 +crip123 +22111983 +cooper13 +151001 +16041993 +qwerty19 +24011985 +ingoditrust +weenie1 +191987 +04121985 +1805 +lonesome +funnyface +wateva1 +lifehouse +romulo +fkmnthyfnbdf +230280 +emily06 +joshua69 +010492 +westside14 +myspace26 +derekjeter +bored123 +1.23457e+11 +sexybitch6 +reader1 +125690 +ousmane +30041989 +400069 +aziz +10081008 +samson11 +21111983 +sexy2007 +tommy13 +buzzer +020784 +26061984 +18071985 +baller8 +planotx +qwerty2012 +metro123 +250480 +xfx3ayfjrk +171986 +09051987 +abulafia +red777 +1fatcat +10061983 +3334444 +seviyorum +09081990 +160783 +eighty8 +210292 +lucky27 +bambang +fran123 +yahoo5 +usuck +lol000 +110381 +brewers1 + +wmilan +10181018 +fed +4646 +breanne +yohann +badkitty +fatty2 +020783 +08121989 +051291 +11081983 +monday2 +dixie2 +painting1 +fatass12 +16091986 +mariposas +mackenzie2 +shaggy123 +over2yangshuo +lima +bumble1 +1thunder +daedae1 +hardcock +13101993 +agent99 +141192 +conejo1 +robert1234 +pitufa +utjvtnhbz +kangoo +danielle01 +qwqw +ukflbfnjh +thunder +myspace93 +eastside12 +abgrtyu +26091990 +1506 +111222333a +160684 +batman. +murilo +031284 +monkey87 +reymisterio +jethro1 +030382 +180582 +040494 +jason07 +112299 +05021990 +beckett +monia +13021984 +fob123 +yellow +saimon +06051988 +gobigred +061287 +198718 +thereal1 +mikamika +04041995 +courtney11 +31071984 +ashton9 +lockwood +gogeta1 +sample1234 +ringhio +ethiopia1 +baseball88 +sharda +maxmotives +26121983 +omega7 +prince55 +kyleigh1 +couple +2507 +29071991 +09081985 +23061984 +avery123 +sirene +0303456 +06060606 +cecily +17091990 +babygirl00 +dbrnjhjdyf +celtics5 +tamara +blessed4 +17121989 +sagapo +devochka +raspberry1 +300983 +07041989 +230230 +27061989 +27051992 +mackie1 +31011991 +emma13 +bakery +rebel13 +28111987 +270192 +yourlove +25011984 +kaizen +shopping12 +otello +280682 +fnkfynblf +jiggaman1 +renaissance +ilovej1 +lennie +06041990 +aydink +198206 +04121986 +chante +06071985 +querida +28111989 +140881 +0411 +dhjnvytyjub +marillion +school13 +stella11 +25011986 +minamina +volcom7 +270491 +butt3rfly +knoxville1 +tommy11 +jeremy +020384 +301082 +kia123 +bombero +1306 +wallstreet +199771 +gondor +150583 +11021983 +greene1 +graziano +merengue +20031983 +150284 +160192 +brat123 +lilmama09 +fatima +headshot1 +booboo6 +180593 +classmate +191183 +1lauren +luglio +444333 +azul +bootycall1 +spongbob1 +4128 +020887 +280184 +20061983 +carrefour +200893 +max777 +silver +atl123 +tattoos +hotmama2 +lookatme1 +andrea69 +lovekita +180984 +cowboys1 +02081983 +toscana +28091989 +blackops2 +baby123456 +monthy25 +ashok +120995 +08061987 +burhan +tricks +040585 +www12345 +tarheels23 +290592 +denise3 +letsdoit +vanhelsing +das +omar1234 +fuckass +texas210 +azertyuiop123 +10million +alex87 +200783 +210880 +honey69 +master9 +starss +pockets +28081989 +29071989 +28071987 +29041989 +maianbinh +showmethemoney +12121995 +paul01 +foofoo1 +lovers21 +omicron +1234567890qaz +noway123 +quilting +colette1 +steph13 +webkinz123 +tartine +190987 +05101989 +100380 +silver99 +juli +asdfgh11 +confiance +joshua00 +anna +thomas25 +guilty +volcom13 +11041983 +shelby7 +sonshine +cake12 +eric22 +windmill1 +lilia +300982 +16021992 +murakami +741953 +090686 +concac +s11111 +12345zx +15091991 +28111990 +misfits138 +school +spencer3 +12161216 +thankyou2 +lozer1 +06021990 +santro +ligaya +saroja +ninette +kianna +221005 +volvo740 +03081984 +17051986 +calico1 +getmoney$ +mongo +honey14 +adriel +spring99 +10131013 +pekida30 +290383 +sabre1 +fastfood +280584 +flirty1 +computer13 +050892 +amber23 +princess55 +26071989 +passage +11021993 +strokes +21031992 +20051982 +pootie +if +dud +06021992 +onelove3 +iolanda +iamhot1 +j696969 +bounty1 +adgjmptw1 +270691 +redbull123 +draven1 +alicat +parishilton +mexicano13 +katerina +eagle5 +medvidek +one2345 +william09 +19061988 +rickie +wonderfull +199191 +021183 +31p5wtdyg/wgq +s654321 +iloveyou95 +191290 +forever08 +24121982 +stasya +ladylove1 +pacifica +1704 +benitez +kbytqrf +qwerty32 +gizmo13 +creepy +diva11 +02101991 +mojisola +witness +gayman1 +121111 +morticia +blessed08 +07051985 +asia12 +memo123 +19101983 +yadira1 +olusola +romantic1 +sound +metal4life +21111984 +271080 +09021989 +love40 +020992 +dandy +123999 +dede12 +198406 +091089 +homes1 +143637 +anderson12 +252525a +pass10 +diamond09 +angels22 +prettyboy2 +black08 +software1 +star19 +bella101 +merijaan +nanakwame +tiberian +jabber +backstab +natty1 +16011992 +06091989 +27061991 +121274 +04021986 +15041983 +wale +missy5 +capricorno +2fly4u +13061992 +baseball02 +1florida +freedom201 +пїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕ +011290 +cutebaby +bobby22 +23071984 +dutchman +danielle14 +231179 +010285 +yahoo1234 +stick1 +chandni +tennis10 +amma +stupid7 +sassy5 +05071983 +041287 +playboy01 +love2live +rtyfgh +wassim +kolokoy +29031985 +schwartz +07051988 +150580 +250692 +tweety8 +26091988 +130282 +200291 +brother3 +raiders! +88998899 +premiere +jamaika +kuroneko +071185 +28011988 +111994 +adele +seansean +goose123 +rabbit +198605 +36chambers +biancaneve +021291 +159632478 +050187 +dancer23 +hermit +111279 +14101982 +goober12 +101008 +220992 +2309 +mimi22 +derick1 +handyman1 +taylorswift +merrill1 +tabassum +tater +20021993 +hemingway +1313666 +26101985 +buddies1 +07081986 +wendel +11121981 +zero13 +160892 +151081 +556688 +farina +trista +15051983 +rogue +120575 +ferrarif1 +mulder1 +antonio5 +killer17 +love< +121008 +31p5wtdyg +giovanna1 +maricarmen +06011987 +mohini +westfield +doncaster +jesse7 +182838 +younglove1 +camprock1 +orazio +indra +mierda123 +010484 +170582 +21081989 +fire13 +1938 +aladdin1 +zucchero +18011989 +runrun +23111991 +198226 +gjlcnfdf +karthick +05051980 +02081982 +290889 +corwin +170792 +forever09 +december08 +24061989 +portugal +271081 +karate123 +181184 +workwork +141291 +advance1 +missy13 +05051994 +mironova +081188 +chicosci +survive +mexico69 +515515 +abhijit +23112311 +sept27 +master4 +020491 +retard123 +jasmine06 +iomega +sexybaby12 +savannah +a87654321 +roadtrip +250593 +katy123 +anand123 +2810 +1martin +meonly +01011996 +prophecy +avisis7 +follow +biohazard1 +jojo15 +buster07 +270889 +240384 +money19 +carrier +14041985 +218218 +master6 +genesis +01051984 +060389 +310383 +cowboy7 +samourai +12011984 +diamond14 +dumpling +pussyman +101074 +sagitario1 +gjikbdctyf +123123f +27091984 +piggy2 +030584 +21101984 +yasmin123 +stalker2 +kisses3 +granata +family1234 +180483 +brians +gateway7 +02111987 +pokemon01 +12071982 +gui123 +julies +jbgr3v7n3b +allstate +28051989 +harleydavidson +charli1 +090888 +dastan +19091984 +london07 +colin123 +cegthgfhjkm +280984 +krisha +lerato +diallo +15101980 +vanessa14 +tommy10 +juanca +autobahn +imgay +30071985 +allan123 +trini1 +martin3 +07021989 +hotdog3 +black07 +kobebryant24 +74gangsta +mariapia +molson1 +19171917 +joker14 +flashy +240791 +01021993 +13091984 +purgen +1q2w3e4r +28091986 +lqfg4hwt +binkie +centrum +nina11 +caboose +segundo +percussion +123321d +28051986 +kevin18 +tomek123 +291285 +400037 +nascar03 +14051989 +05021988 +landon2 +solstice +chica123 +120979 +pimp25 +iamno1 +pewdiepie +120577 +patsy1 +16011989 +at1234 +norberto +ekaterina +musica123 +marcelita +08051991 +electronica +01051983 +220480 +myspace05 +tank12 +ironhorse +mormon1 +130281 +300887 +tristan123 +luxury +26071986 +040987 +barbarian +16031992 +borisov +cassandra2 +moose12 +30091991 +13091987 +goody +jasper +qdye17t1zv +161083 +2610 +02061982 +lfiekmrf +04081989 +06121988 +timtim1 +16081986 +24061992 +piglet2 +100780 +29081992 +181082 +babygirl28 +turtle4 +pea +coffee01 +duckling +26031992 +yahoo7 +123123j +280291 +skydive1 +gayass1 +04061985 +01041980 +xgx39zgisl +230479 +301283 +110578 +debbie12 +134109 +scarface23 +madison22 +198613 +paswoord +vivalabam1 +250983 +191083 +bresil +190791 +matute +260291 +dale03 +praisethelord +serenade +bart123 +18111985 +chiara1 +bailey +saritha +talktome +southside13 +261080 +bumper1 +16111988 +sheikh +neverforget +lalang +19855891 +angelbaby2 +bobby6 +neverwinter +babygirl91 +alexande +loveyou9 +01051980 +28081984 +dirt +dexter2 +020791 +lilbaby1 +cheerio +789852123 +5757 +han123 +07121990 +devlin +daddy0 +samsung88 +conman +11qq11qq +marisela +sexyeyes +03091986 +turtle01 +111111b +130283 +070488 +bush +warrior12 +150882 +1111111111q +310884 +yessica +scene1 +130881 +jordan101 +29111989 +hjcnbr +family. +cola +killer08 +159951a +280284 +brogan +230783 +junior6 +ton +banan1 +southend +jahbless +nicole86 +claire123 +cicciobello +slowhand +22061993 +020683 +28011986 +goirish1 +13111988 +asecret1 +ciara123 +morrigan +101294 +03071992 +global123 +14061992 +babyboy69 +speciala +greenbean +5.254.105.20:test1 +edward10 +28071989 +flute1 +300591 +stu +dance22 +eastside6 +spud +mathews +rainmaker +pierre +matthew05 +hatelove1 +spanky2 +chevytruck +nick08 +histoire +170285 +florida5 +230293 +ed1234 +panther +18091988 +whippet +exodus1 +rice80 +poopypants +tamilnadu +300384 +rossia +2307 +.kbxrf +oleander +emogurl +200680 +07031991 +manatee1 +roxana1 +share +pissed +sarah15 +faustino +arun +arsenalfc1 +122500 +butter44 +cherry1234 +spleen +150184 +smokey! +seyxe44hca +fridolin +paddy123 +198818 +fire22 +ktyecbr +jolene1 +olivia +buttfuck1 +08091991 +gators01 +coheed1 +27121983 +100579 +nicole91 +011085 +gerrit +1qazzaq! +passwordpassword +mama55 +limaperu +graphics1 +pescador +20041982 +fifa2006 +10121981 +06071989 +thomas19 +260696 +airforce2 +211987 +gangsta11 +bandgeek +27031985 +091086 +pussy10 +jesusteama +arlington1 +25061992 +am123456 +magic11 +081081 +superstar9 +100182 +kim1234 +contract +joking +walden +saliha +1allah +odeyemi +mylove21 +28061992 +16111982 +markos +qwertyas +1789 +polito +01061993 +soccer97 +110494 +300784 +katenka +robert20 +270183 +bokkie +260383 +appletree1 +1people +toyota123 +redhouse +j3nn1f3r +texans1 +joey22 +250482 +198227 +queer1 +13011992 +07031985 +redford +220579 +samantha19 +198713 +chesney +angela21 +031185 +lebowski +mandi +precious7 +emmagrace +kal +anna1990 +meandu1 +maggie6 +jaybee +mexico +emily22 +alyssa! +anglia +merrick +270185 +21051993 +megan7 +260884 +31121980 +nostalgia +j0seph +trevor01 +taotao +141180 +290483 +987654321j +pitbull13 +ninonino +michaelj +1coffee +goku12 +061185 +aleyna +28121985 +grace11 +30081986 +11041992 +101195 +password83 +dounia +21011983 +gerry1 +check123 +03021985 +03011989 +tessie1 +melanie12 +pickles! +tyler69 +amritsar +marconi +adriano1 +lemmein +groove1 +25041985 +200782 +123hot +k1ll3r +bobo11 +john09 +18021983 +170188 +crayon1 +megan! +31071988 +26111985 +jonathan14 +191292 +redsox9 +198420 +151292 +letmein69 +250892 +mihaita +sergeeva +myaccount1 +simone123 +realtors +oldfart +27091988 +danadana +mya123 +haley2 +marcus23 +jonathan21 +payback +250380 +759153 +agape +1pioneer +stupid. +puppylove2 +jagdish +alex28 +ashley00 +sebastian +301180 +180189 +brittani +30071992 +soccer30 +29111988 +danielle21 +pagedown +hope1234 +tiger07 +ytyfdb:e +070989 +toctoc +181283 +mexico08 +utopia1 +21121993 +carlos25 +199313 +christi1 +240183 +040783 +football41 +school4 +olivia06 +usa1234 +kalinina +iloveyou03 +admins +1z2z3z +ihateyou3 +gjhjctyjr +kissthis +youwish +lolito +700000 +280986 +dipper +rocky1234 +aayush +olivia7 +kvartira +papasmurf +nelson +secret5 +141084 +chris02 +kaylin1 +tor +def456 +may1993 +auxerre +020583 +good4now +saosin +0203 +physics1 +56tyghbn +gooddog +ninja636 +02061980 +julian13 +alicia01 +smile01 +fernando2 +19041986 +290385 +191988 +faggot123 +josh08 +ggggggggg +slam1984 +260182 +221291 +shadow19 +24111991 +yourock +golden2 +190582 +150392 +415415 +021186 +uncle1 +jacket +dreamtheater +20051994 +wow1234 +cooper10 +raikkonen +roygbiv +246802 +15071984 +enforcer +kayla4 +logistics +benz +123456789love +number01 +123qwe! +mobil1 +25021983 +blahblah! +q121212 +michelle88 +210791 +13071994 +jk123456 +reilly1 +231985 +05021986 +1crazy +130883 +teddybears +kristof +ratdog +mychem1 +serpente +02091984 +stalker +010684 +badgurl1 +lois +66669999 +nothanks +050683 +giants25 +tripper1 +michelle25 +200185 +sch00l +anabela +bryan2 +patrick6 +120195 +naruto96 +rae123 +gameon +not4u2no +gallego +bigman2 +me4life +28091990 +210380 +12pack +wesley12 +electra1 +1hundred +monkey32 +funnygirl +030290 +carmen +020385 +yeahright1 +081088 +nokia6680 +goleafsgo +19922991 +sc0tland +yellow24 +al123456 +101194 +2123 +kerstin1 +spades1 +28111985 +hotdog69 +apple14 +04021992 +simonetta +shonda1 +180791 +vincent12 +lover18 +malkin71 +080809 +junior25 +ferrari12 +rod123 +minimi +oscar7 +mousie +nfnfhby +season1 +okechukwu +tyler02 +ololol +tirana +a234567 +biotch +goldensun +06091987 +05011989 +ukrnet +sonechka +madison +steelers11 +1sunflower +football61 +order66 +hbk123 +karandash +qzwxecrv +24071985 +951753456 +21061983 +040892 +montecristo +03011986 +christ01 +sarkar123 +081286 +211080 +muhammet +catholic1 +karthi +270287 +frankie7 +240284 +250492 +qwert789 +harley21 +199217 +02071992 +registration +jacob14 +manning10 +05081992 +manchas +maple123 +06021986 +stroker +258147369 +12122012 +justin98 +050987 +sabrina +6464 +trooper2 +devil13 +260592 +180287 +marley11 +jacare +198717 +revolt +omgwtf +dogfish +brittany16 +angles +j0hnny +30051984 +180184 +johan123 +pizzaman1 +19111992 +30111990 +400086 +beeper +scanner1 +rowdy +060985 +4sisters +080486 +silva1 +22051984 +people5 +040786 +qwert7 +circa1 +200493 +280180 +bella6 +10031982 +05041991 +facebox +220493 +bmw318is +400055 +short +midwife +130492 +texas08 +baran +06091991 +civicsi +300691 +18121983 +teddy5 +26081981 +110879 +terry2 +shorty8 +yankees4 +lele +rtynfdh +jungfrau +183729 +greenfrog +saleen1 +mandingo1 +thomas20 +maggie8 +image +080881 +51515151 +ewq123 +190391 +q7w8e9 +cra +lovers5 +03101984 +28121991 +lovely16 +single69 +robinho10 +bailey14 +travelmoleoptin +1zg1h9suza +orange15 +88 +music15 +babycat1 +thankful +12071993 +black16 +lovebug3 +independence +098765a +080787 +master55 +pixie123 +160191 +ladylady +pass13 +ihatethis +24081984 +ryan17 +05081991 +890123 +12101983 +281080 +281192 +310883 +101069 +ass12345 +sarah1234 +cereal1 +iloveher12 +pelado +supercool1 +kimiko +forever15 +mousey1 +27121985 +30061985 +27101991 +291182 +090981 +301192 +260382 +olympe +buttsex +197272 +raymond +25071983 +140182 +thongs +angus123 +james1 +giant1 +tabby123 +lick +gedeon +tiger09 +030507 +20121982 +45m2do5bs +190491 +251092 +jose16 +vagina123 +mithrandir +cecelia1 +000000z +24021992 +spencer1 +seville +070781 +blackpool1 +pussie +young12 +vika2010 +shakey +jetset +09011991 +re +311291 +271193 +09041985 +contador +deutschland +evangelist +bitch0 +culinary +543543 +1936 +compass1 +29011988 +babygirl77 +picard1 +jojo14 +purdue1 +pottery +crystal5 +jackson5 +wallet +08071985 +05071987 +akon123 +brunos +already +tequieromu +divorced1 +carmen +freedom4me +levski +august01 +fedex +nirvana666 +amina1 +hokage +140791 +superman0 +alperen +198022 +yulya +060488 +kundalini +kevin17 +synergy1 +fullback +femist22 +cheese21 +blueice +201181 +passwrd +danita +07061985 +jonnie +lollypop2 +mary01 +kinkin +shadowfax +++ +keebler +bass12 +120293 +betty2 +winnie2 +froggy11 +pip +maggie05 +josemiguel +060504 +fdsa +amorypaz +belgique +union1 +13041992 +04091989 +patricia2 +778877 +rapid +16081987 +counselor +010170 +22061982 +08051987 +young2 +00000000000 +100781 +07041992 +zaizai +inject +leilei +hotass +l1nked1n +110995 +zoo123 +nicole85 +kik +210592 +tam +peter11 +30081990 +22081992 +racheal1 +eastside3 +20071983 +14081408 +ianian +1707 +mich +micheal12 +kevin4 +vaz2109 +pizza7 +rfvtgb +584201314 +shannon13 +qwertyuiop0 +siracusa +15091984 +nepenthe +16011985 +westside18 +mylove7 +cupcake4 +2233445566 +hatteras +chiller +010292 +entertainment +kevin6 +eddy123 +28071985 +park +jeddah +fl0wer +03121986 +whitedog +000aaa +люблютебя +13011985 +090590 +04011991 +280592 +21061993 +196000 +150292 +wildwood1 +08031988 +24091985 +240385 +20101995 +120280 +gusano +290191 +lovebugs +lovely08 +sw705547 +kenzo +ichiro +matt6288 +opelvectra +qawsedrftgyh +loveher +050887 +28101983 +huggies +28121992 +fordmustang +dominic123 +31011992 +denali1 +290982 +lopez13 +owned1 +mountainde +just4now +jayjay11 +gametime1 +playboy6 +030487 +150150as +13661366 +mjolnir +040380 +123sam +123321w +portia1 +12345678912345 +060892 +gokart +hbxfhl +wsx123 +whywhy +mart +jahlove +red333 +sid123 +max101 +hs: +yamaha01 +hawaii123 +shifty +30121991 +bradley123 +bubbles15 +screwu2 +morbid +breanna2 +30121984 +jordan2345 +191182 +25031984 +jenna12 +1403 +18081991 +getlost1 +hiroki +lauren +betty12 +foxy123 +amen +badboy5 +08031983 +sup123 +26031985 +brittany01 +06051991 +270687 +trekker +corey2 +taylor96 +gray +15111992 +14051992 +130893 +sonnen +austin96 +ratatouille +199513 +141181 +jack1 +naruto90 +ohbaby +27041992 +black18 +rainbow1 +sept10 +cheaters +110033 +mark69 +070892 +larry12 +17111990 +serega +cowboys +baby2000 +ballin4 +cupcake22 +candybar +400081 +16071990 +301281 +kiss1234 +200881 +cashcrate +240383 +pimpster +20121994 +sherly +040188 +leoleo1 +sailfish +jasper10 +070290 +170187 +kitten69 +101076 +1811 +tastiera +jamaican +140190 +bitch55 +111080 +150982 +24041984 +curitiba +rincewind +logan13 +130191 +cooldude12 +belen +03101987 +doggy5 +nana14 +proteus +021283 +26091984 +07101987 +haggard1 +041288 +mickey09 +holycrap +andiamo1 +nokia3220 +30071990 +11021982 +matrimonio +money2010 +aloevera +shanty +28011989 +corazon2 +221988 +summer98 +120808 +livefree +sonofgod +jonathan19 +737kkblskv +chelsea22 +warrior7 +10081983 +mononoke +prince23 +486486 +baskets +zxcvbnm1 +marzena +halliwell1 +chester11 +guitar6 +brand1 +jakob +030289 +toyota2 +22091983 +damnyou +sexy95 +godisgood7 +nanook1 +160992 +18041983 +shuriken +hd764nw5d7e1vb1 +futurama1 +fuckme13 +17081984 +sonora1 +jackrabbit +250292 +godblessyou +lavieestbelle +myspace198 +1323 +saoirse +150480 +27091989 +yxcvbnm1 +branson +blabla12 +casey11 +19011985 +05091988 +100679 +s666666 +198706 +131179 +axlrose1 +dima12 +nestea +dickhead2 +pussy420 +260891 +#1cutie +zhanglei +20061994 +emma22 +travis13 +300684 +chaotic1 +ogechi +manohar +weekend1 +ilovekatie +loser09 +fis +15101983 +vinita +skate14 +analla +titotito +williamson +sissy2 +charlee1 +181281 +ilovemywife +aaaabbbb +yankees10 +samoan1 +rodgers +roger01 +110192 +samantha6 +scarlett +jasmine18 +saltydog +061186 +170981 +199613 +260282 +jor +soccer +konrad1 +198921 +lildevil1 +140280 +honeyz +24101992 +050692 +vfifvfif +020190 +010384 +luv4eva +reward +qweasdzxc +smokey +linalina +daisys +annika1 +1881 +567891 +mockingbird +florida11 +pepsi11 +2710 +120180 +01012006 +17011992 +14121993 +barnabas +100194 +countrygirl +nike22 +560079 +03081990 +dieumerci +chriss1 +black88 +qwerty08 +monkey34 +101992 +zenzen +fatjoe +30111985 +stylin1 +kirstie +030986 +jehova1 +10years +rallye +1blunt +corrine +manouche +joshua. +juan14 +ok1234 +500004 +dickweed1 +120977 +120777 +getmoney10 +sexx +zx1234 +karatedo +hogan +24101983 +071284 +stripe +cranberry1 +eminem +serafin +pdiddy +25071992 +3737 +123masha +linkedin2 +freeport +sickness1 +diocane +poop12345 +june1986 +sweetie! +xcountry +mack123 +24091984 +900900m +30011991 +dropkick +quake2 +626626 +olesia +tristin +w1958a +123456789987654 +pop12345 +enfermera +cmoney1 +246 +pizza101 +030891 +superstar8 +24071986 +hairspray +210792 +yellow55 +11081982 +spike13 +forever16 +greenwich +270584 +gab123 +tink14 +05091986 +kalimantan +28021984 +andreas123 +iamhot +200880 +slayer +07041990 +matthew. +160392 +police2 +04091991 +riffraff +654321d +screamo1 +style1 +fastcar1 +02041993 +senna +mariagrazia +15071983 +270782 +vagina! +271291 +dashenka +190286 +oddball +mantle +12345qqq +tulip1 +210680 +030885 +gannon +austin16 +lauren16 +silver10 +gnomik +casper +manutd11 +devilmaycr +250392 +honey4 +sweet01 +crap123 +26111992 +ricky13 +hatchet1 +16031984 +12021982 +kimba +starz +pardon +aidana +19071993 +longtime +210283 +000000s +linkedin2010 +alley1 +jimmy6 +password007 +110002 +evans1 +ukraine1 +1timothy +lulu1234 +030684 +dfgdfgdfg +ajibola +empires +creativity +300592 +shanel +hottie06 +alayna +198405 +metallica4 +1q2w3e4r5t6y7 +0511 +25081992 +superpower +030991 +rebeca1 +11aa11 +time4fun +guy +newyork22 +love_you +26011986 +heather22 +17121982 +1trouble +06071992 +29121991 +22031983 +24081992 +therasmus +duke23 +12111982 +letsrock +lbyfhf +beata +lilwayne5 +newborn +danny1234 +damdam +250882 +timmie +8008 +babcia +hotgirl123 +rockstar14 +qwerty100 +theblues +100480 +bella +23091982 +sdfghjkl +dea +010891 +rap +ltleirf +07061991 +menorca +pasha1 +loveme07 +destini +flyguy +pepper69 +07021985 +lon +volcom3 +18061983 +imawesome1 +metallica123 +sweetpea12 +analuisa +230880 +butter3 +silver6 +water4 +shyguy +200791 +forever10 +140392 +terminator1 +26071984 +190983 +watanabe +newyork21 +putamadre1 +sadist +strategy +07111987 +kelly69 +peaches11 +adelia +volcom11 +26081985 +redmond +igetmoney +fluffy13 +orange24 +kabouter +29031987 +system12 +passwort1 +georgia +130577 +17061989 +10051993 +petals +25011992 +samantha23 +yellow16 +020189 +03071984 +kaktus1 +210881 +holley +whatnow +nickey +allahuakba +171192 +160291 +gwen +hardwood +penguin3 +dirtysouth +raider12 +kendal1 +basher +dc1234 +gratitude +kids12 +300992 +17111985 +qwerta +claudius +naruto09 +18081982 +210693 +12121977 +friends07 +password#1 +14101410 +kingsley1 +plaisir +macman +gecko1 +pablito1 +malutka +liverpool. +danny15 +zanessa +mimi01 +120696 +03081992 +baba12 +p3pp3r +scooby10 +31081992 +baller101 +&3 +buster6 +300782 +gotti1 +mamasboy +genaro +sweet9 +09041987 +38special +rajaraja +mylove1234 +1703 +261180 +09061986 +290979 +12581258 +pimp33 +dgf68yg +m00000 +211181 +31101984 +260782 +sk8terboy +26091987 +s0cc3r +coimbra +doodoo2 +michael04 +pumpkinpie +jaquan1 +batman18 +zara +patch123 +thenumber1 +120877 +270983 +02041982 +24021993 +131079 +20091983 +21061984 +djhjyf +black17 +250992 +pika12 +ovation +sexy911 +yourname1 +kas +conway1 +moosie +sugars1 +comrades +666123 +fedora +petrucci +3@p@g# +way2go +drandreb +blackbeauty +winter22 +kid +jack2000 +qwerty07 +dmitri +ihate1 +star12345 +19091983 +jesse11 +tenten10 +19031984 +26081992 +14011985 +molly4 +ladybug13 +mybaby3 +carlos4 +charm1 +01081992 +pam123 +15121993 +skip +14091986 +artiste +apostle +19081983 +brady123 +razorback +lilmama3 +booboo14 +pianoman1 +jordan32 +tiffany01 +07051991 +31122008 +lovestory1 +212224 +001989 +agarwal +1steelers +565758 +neptun +edward14 +ashley03 +210780 +depeche1 +29071985 +gfhtym +ghbrjkmyj +dorothee +20062008 +sexy94 +wildrose +uniden1 +artart +rebecca7 +preppy1 +millonario +johnson5 +denise11 +yijeong +enduro +loveme33 +260292 +badong +201179 +taxman +baby_gurl +cassis +30111989 +031192 +300883 +seinfeld1 +islamic +acura +flowers4 +160483 +lakers22 +record1 +kristen2 +191084 +231177 +laughter1 +aol.com +mario7 +reggie5 +carlos6 +egghead1 +060888 +b1b2b3b4 +31031992 +hartley +warsaw +king77 +cielito +pimpshit1 +13121982 +26051992 +201091 +pass22 +nahuel +31031991 +italia90 +12101981 +110979 +timoteo +pangetako +13581358 +23081984 +ruby1234 +rangers9 +buttercup7 +maximus +michael03 +31081985 +lan123 +lokiju +itunes +alchemist1 +lacrosse12 +manjunath +alyssa4 +lynn13 +tt123456 +unicorn7 +07031990 +16111985 +darkwolf +davidc +torres123 +meaghan1 +1pookie +197612 +truck123 +uniform +04061992 +troy12 +23081985 +180783 +greatdane +100281 +bubble3 +seashore +lucienne +04061983 +lol123123 +ricardo12 +moppel +06121991 +antman1 +hoova52 +ivanhoe +12061980 +tennis7 +tigger02 +dakota07 +29011985 +030791 +canada2 +angel31 +canberra +run123 +30031984 +061283 +19051983 +edward4 +wetwet1 +110679 +0212 +123123qw +emelec +olivia5 +winter +gogo12 +jeffhardy2 +26011985 +171281 +tankist +suckme2 +83773049 +astrid1 +love2 +fatdaddy +1401 +kenneth12 +gators12 +dima777 +14781478 +123456yy +passme1 +angelo12 +lovers01 +mickey8 +shanelle +0211 +161092 +bestbest +biotch1 +161290 +bond007 +nikita11 +31011988 +23041993 +dededede +784951623 +snowbell +fuckoff4 +270392 +daniel28 +280493 +got2go +tartar +lesbica +miller01 +03121985 +lolly123 +goldrush +pedigree +johnny21 +nineball +angie2 +geometra +12121979 +230993 +30091984 +120994 +090288 +18031993 +gocats +scottish +baller08 +pink27 +poppys +florine +30091985 +crusher1 +010110 +060188 +16091990 +123456cc +unicorns1 +111111w +1501 +brother123 +bailey6 +niko123 +070886 +thatnigga1 +claudia12 +rainbow +lovelace +missile +mylove69 +220381 +blo +snowflake2 +bobby01 +badboy21 +oksana +punani +nathaniel2 +soccer90 +123321zxc +sw3434! +198228 +290790 +akinyemi +chelsea09 +bratz2 +080789 +sigrid +ilovejack +stereo1 +crossfire1 +180284 +money0 +251093 +laura10 +vfif +amazone +wrench +mydestiny +cats1234 +125874 +beefy1 +heygirl1 +220293 +26111990 +mike55 +henry8 +1southside +fuckup1 +maurice2 +pimpin. +mamounette +den1ks +cooper22 +kilo +tay +ritinha +bunnyboo1 +badboy10 +sesame1 +gianni1 +tommylee +987654321k +spanky12 +111993 +patrycja1 +27011989 +01071990 +ladybug5 +qwerty1231 +chicken01 +300884 +bahrain +myspace92 +gayguy1 +samarinda +omooba +coraline +fal +181280 +copper11 +030380 +kaka1234 +ghetto2 +time123 +041192 +tikitiki +280883 +25041992 +louise +as123123 +03091985 +steelers5 +brooke7 +kiersten1 +250291 +210381 +daddy! +dipset12 +nokian72 +direktor +240482 +solid +sebastian0 +16121984 +rere +vectra1 +flossy1 +sneaker +superbad +sandra10 +dunbar +delgado1 +polka1 +tiff +nick07 +foolproof +peanut +cosmic1 +paige2 +dragon420 +090785 +29101989 +john07 +rebecca +klm123 +nunzia +celebrate +spongebob. +05041985 +buttons2 +tristin1 +040986 +teadoro +starbuck1 +05101985 +sugardaddy +198701 +princess87 +bloodhound +milkmilk +sammycat +samantha22 +zzaaqq11 +dfczcghjcbnm +191991 +chanti +1234563 +bama +martin69 +fermin +stupid01 +cowboy13 +buddy15 +albert2 +kjkbnf +uuuu +08051985 +bandits +monster. +charlie15 +lovely9 +09021990 +newcastle9 +administra +11121983 +tianshi +tiffany! +hickory1 +gatitos +78kdow9spf +06091990 +richards1 +knightrider +523456789 +tiger33 +0310 +lolita123 +hardball +0.0 +260392 +jackie22 +steeve +01121985 +teamo10 +jac123 +baby29 +987654321d +010584 +hjpjxrf +1234554321a +pozitiv +010175 +03021984 +22071983 +talia1 +katherin +111082 +jackson8 +georgetown +230480 +tuttle +198705 +25102510 +blaze2 +04071991 +anaheim +pooh10 +01101989 +soccer91 +pacifico +cool1 +18121982 +112266 +bacteria +050388 +chartered +jenny15 +lisa13 +football96 +lovemusic1 +enriquez +andrey1 +21011984 +sel +14111983 +gumball1 +apollo13 +danny6 +undertow +1507 +08081983 +cfif123 +flameboy +220593 +monkey56 +160882 +america! +suzanna +7654321q +br1ttany +3838438 +25031990 +boston3 +jordon23 +gothic3 +30121990 +gangbang1 +crazy16 +bonds25 +pepsi3 +chula123 +kishor +kayla08 +ilovepie1 +bella2010 +protocol +spartak +joao123 +anthony99 +6767 +apsk0518 +harrington +redcross +21091992 +20071982 +kameleon +211182 +flipside +170781 +netgear1 +joakim +17091992 +050891 +skater4lif +27031988 +pudge1 +snowing +060680 +екатерина +03021992 +francisco2 +/.,mnbvcxz +promises +cory123 +010984 +100980 +fyfyfc +lennox1 +trampoline +ponyboy +leighann +04051986 +baseball0 +20031993 +marketa +jeffrey +12281228 +411040 +reinaldo +homebrew +skydiver +simonka +090687 +4getit +travelmate +basia +mawmaw +praveena +nadya +noble1 +milwaukee1 +babygirl90 +bianca +25051982 +abigail3 +918918 +isuckdick1 +120794 +05061984 +rapid123 +booboo21 +nancy12 +2308 +flamer +270777 +21091985 +billy69 +woodwind +ihatemen +silver77 +sergey-ivanov +sammy9 +15031983 +qazqwe +tamale +culito +29021984 +sakura +robben +usajobs +1611 +07101991 +twogirls +dima1993 +170282 +vanessa5 +basket101 +padilla1 +farid +andrejka +300981 +lopez12 +spider7 +kyle01 +30061991 +royals1 +892 +mikey13 +daniel1 +13081993 +boyssuck +060492 +sadie11 +ilovesean +dude01 +17111982 +salman1 +23111983 +2468013579 +fuckyeah1 +230183 +babygirl97 +maiyeu +google22 +26021992 +1maryjane +05091990 +marino1 +666999666 +girlsrock1 +choudhary +holycrap1 +rocio1 +02101981 +pakistan1947 +bummer1 +yfdbufnjh +ninja7 +hoffnung +dudedude1 +070486 +2707 +lunallena +021092 +anna23 +30071988 +blessed +samson2 +bugman +080589 +angelo4ek +reaper13 +brian69 +apartment +wicca +1qw23er45t +pazzword +zubair +020685 +240693 +barker1 +300683 +bitch77 +google23 +09061988 +summer101 +240882 +beachbabe1 +states +babatunde1 +4success +baxter01 +bhardwaj +23011984 +sweetcandy +16061983 +gracie08 +assilem +available +031091 +100694 +011089 +hunter25 +123456789_ +gostoso +silverchair +table +28061985 +benjamin123 +hermoso +050885 +cenerentola +03041984 +1kevin +oliver99 +kaylee2 +100181 +1cookies +u1v7hhh7ef +fuckme11 +peace10 +whoknows1 +290685 +03071985 +17061990 +19861010 +metal4ever +killemall1 +110193 +lovingu +yamaha +callum123 +annemarie1 +glendale1 +yy123456 +julita +schroeder +8xxg4gcc9q +parker11 +29031989 +minnie11 +python1 +megan5 +religion +mexico99 +selene1 +khalid1 +nicholas13 +07091992 +24081989 +16061984 +thomas02 +oliver! +redsox01 +oladipupo +03031981 +rissa1 +qazwsx12345 +pembroke +221178 +240392 +whore2 +az12345 +langley +10071007 +23041984 +hfvbkm +05091985 +gerger +20021980 +black99 +strat1 +janejane +130780 +rufina +28041984 +grandchase +obrien +bvgthbz +01021981 +trogdor1 +shan +chorizo +mafiawars1 +010884 +adrian3 +солнце +270707 +grandma123 +198198 +010194 +29071992 +china12 +honda4 +juggalo2 +hidayah +morrowind1 +morton1 +180392 +wildcats12 +14031984 +moni +130382 +nikki21 +05021989 +pinacolada +120294 +jeremy69 +cbhbec +011285 +stupid5 +30011989 +redwall1 +barbara2 +jamesdean1 +090984 +30011992 +140281 +dupa11 +bills1 +abigail123 +darkelf +mymommy +071291 +091290 +onmyown1 +18111990 +29031984 +chandran +08041987 +united11 +26081991 +luis21 +lovejones +200581 +katinka +fishsticks +100993 +19001560 +hotgirl12 +bastards +piotr +30081987 +alliecat +130679 +happy07 +18051983 +030190 +s8kril9u4f +superdude +12345678u +marcus22 +gateway3 +zxcqwe +070188 +150992 +02021979 +12345611 +luis01 +chester5 +f5ghyjqhav +apple69 +pauline +25101982 +farter +joe12345 +2911 +198202 +14081984 +brandy13 +yaq12wsx +vincent7 +srikrishna +scooby5 +02011990 +tarpon +300580 +151192 +tito12 +switchfoot +drummond +sasha5 +lovelyme +icecream5 +091185 +09101985 +pol123 +13041993 +250180 +140992 +420man +251193 +buttercup3 +12111983 +ching +partyboy +charan +yupyup +121484 +joeyjoey +260183 +portugues +ritarita +willow11 +300187 +fordescort +560004 +fjfjfj +kayseri38 +newlife07 +ak47ak47 +666666m +123456_ +110182 +ятебялюблю +jasmine. +deadpool1 +helena +sandra22 +noel123 +young10 +cytuehjxrf +sheeps +samson +brutis +abc1231 +kaktys +triana +600073 +291282 +19121983 +06071986 +chacha123 +iraira +pecker1 +bedroom1 +jamie01 +dragon44 +angela22 +14061983 +22041984 +060681 +zzzzzzzzz +150695 +minolta +maryline +slonko +fuck99 +280808 +youwish1 +matthew69 +dallas88 +kulit +11061983 +frida1 +imissu2 +shann0n +comets1 +farside1 +black25 +31051992 +pantera2 +111278 +081085 +jesuschrist1 +tanning1 +letmein +tigger. +18101993 +brownies1 +auntie1 +estefani +090287 +lupin +nnnnnn1 +asdfgh. +150892 +250381 +9749676621ok +kitkat2 +071285 +peace01 +hewlett1 +1808 +jessie7 +chevyman +sperma +horror1 +30121989 +tonymontana +08091987 +lovesux1 +210382 +120694 +brave1 +jesusa +comeon1 +123bbb +abe123 +stokes +bubblebutt +zoomzoom1 +bureau +310393 +chris92 +snoppy +velasquez +healer +honey10 +qwerty45 +211082 +samantha123 +220481 +farm +romuald +12041982 +11223344q +tennis3 +blanco10 +tazdevil +sovereign +message1 +francis +legend123 +samir123 +savage12 +nathan15 +kirk +ladybug4 +victorious +hulk123 +sophia01 +shimmy +legia1 +harley4 +200183 +241178 +london21 +whisky1 +alex1981 +centre +13011984 +smackdown2 +ilovemyindia +cowcow1 +196500 +joseph18 +pipo +wangjing +bear23 +030491 +131279 +06061983 +190783 +07091990 +semeolvido +jackie23 +adrian23 +marie95 +felipe10 +killer420 +motorcross +24011992 +2199127551 +barbie22 +mookie123 +nine99 +241078 +24111984 +street12 +victoria5 +il0v3y0u +tigger101 +260284 +sondra + +231293 +111972 +72chevy +03021990 +08061989 +031084 +wilson +170192 +20091994 +10091989 +28091985 +xxxzzz +pollock +bur +christina3 +creative12 +russell2 +deepak123 +28061983 +aa111111 +aaliyah3 +ilovetim1 +registrati +07041983 +11011994 +fylhsq +aquaman +31121982 +minami +08031989 +boys12 +siemens +ontario1 +wallpaper1 +110993 +b00mer +haters2 +violino +050386 +babygirl03 +solution1 +180983 +ichunddu +poopsie1 +19101982 +refinnej +sookie +rbh.if +arturik +autumn2 +johncena11 +samantha16 +01071982 +180692 +raul123 +01011960 +pinpon +sparty +caca1234 +october08 +tajudeen +260787 +19041984 +tweety +250594 +bittersweet +25091992 +21101983 +17011984 +spirit +rkelly +godsent +27111991 +flower69 +serenity7 +111092 +chili1 +binder +130980 +nataly1 +addie1 +bocajuniors +02081992 +hpl +outside1 +victoria! +happy4me +atkinson +770077 +05121988 +rfhfcm +monkeys7 +bartolome +cathrine +mustang96 +december +mylove08 +tehran +slipknot5 +020191 +peter5 +u6e6r9hwix +banban +darkman1 +element6 +door +zachary5 +socks123 +0312 +060390 +bandit10 +030984 +dallas69 +05101990 +hottopic +q2q2q2 +223 +guismo +12021980 +zoom1234 +25031983 +sebastien1 +051084 +100394 +king25 +20061982 +29031986 +qazxswedc123 +randy12 +rocky101 +30081989 +1pokemon +marco12 +telefonica +ge0rge +boswell +240480 +330330 +soccer29 +021082 +brandon99 +hit +crip13 +sanju +260883 +1qazxdr5 +030884 +147852zes +miruna +important1 +11021994 +babies4 +militaire +011188 +eliseo +svenja +audio1 +fengshui +brian5 +198025 +makeitso +14022009 +06021989 +prospero +171180 +single3 +busta1 +tori12 +011011 +malou +bintou +mounette +holymoly +sonic3 +123mmm +210284 +peepers1 +sandoval1 +princess34 +10031981 +060287 +inicio +pop1234 +rasta123 +passwort12 +katya123 +chelsea07 +1234567899876543 +tweet1 +sophie22 +mitzi +240192 +yomama! +061182 +milacik +2200 +190484 +watkins1 +230581 +teddybear7 +550055 +20021981 +102030102030 +nicole96 +nissan123 +bambam11 +123456789qwertyuiop +shyann +joshua25 +haikal +22081984 +emiliano1 +k9g2xpce1e +crossover +dominic +021185 +198401 +leslie +barrera +powerpuff1 +171280 +official1 +jaydon +02011983 +denise13 +spring123 +1qazzaq! +27081985 +500026 +manutd10 +05121987 +261193 +m0rgan +andre2 +111293 +041292 +01121988 +8675309j +phoenix12 +hun +29011992 +symone +ilovebrand +titten +ajhneyf +gunawan +denver7 +babyluv +peanut8 +13591359 +171191 +fireblade1 +milanac +carmen01 +rocky23 +mike6453 +salsal +pink05 +10111980 +meatballs +devil12 +charles5 +steven15 +shan123 +210793 +sundin13 +prime +miniman +poopoo22 +140581 +180383 +magoo1 +17021985 +dale123 +giusy +asddsa1 +sacred1 +03071989 +04101990 +jacek +arafat +bebe01 +08091992 +1702 +a7x4life +humphrey1 +10051981 +vanesa1 +doogie1 +outlaws1 +jackie10 +demon6 +killer18 +pissed1 +hamster +imhappy +07051992 +amedeo +carlie1 +1l0v3y0u +mirek +asdfghjkl. +rjyatnf +13121980 +142536a +06101987 +beehive +sexy91 +bandit3 +islanders +125125125 +catfood1 +morgan07 +freeporn +220680 +superbowl1 +hotbitch1 +romans8 +04101986 +gramps +198707 +summ3r +superjunio +18021985 +beauty +momo13 +1fatass +las +y0y0y0 +137946 +ingram +1tyler +rosalyn +elevation +29081984 +wendi +081189 +shaina1 +baxter +09051990 +redroses1 +1scooby +snake12 +spicegirls +iamblessed +100478 +310183 +rfhbyjxrf +padang +08041985 +hannah17 +yang +puszek +1425 +sebas123 +smash +reggie2 +shaaba +04011989 +chevy88 +qwertyui12 +poppy2 +300185 +chastity +05051995 +07061984 +090788 +love999 +djamila +19101993 +linkedin99 +010493 +aaron10 +imsingle +lucrecia +kupal +18021984 +280683 +nicolae +400061 +ert123 +171181 +13081992 +jose17 +monk +10101979 +060885 +070585 +underwater +30101983 +15041984 +dctktyyfz +12abcd +timothy3 +04011988 +222222q +dortmund +artemon +society +sherpa +pepperoni1 +lulu11 +nicholas4 +25041984 +weezie +berkay +geegee1 +miomio +nathan03 +04121990 +mariguana +jacob6 +1jeremy +sammydog1 +dinger +bellaboo1 +jlbyjxtcndj +chelsea21 +25121980 +costa +110781 +blondie7 +nsync +16081985 +steven18 +21031993 +strato +198603 +05031985 +helpmelord +07021986 +only4u +wooster +090586 +cookie88 +continental +dolce +18051984 +grandkids6 +mecanico +hammer2 +110795 +frodo123 +impact1 +217217 +david99 +auditor +santiago +081091 +shinhwa +jeanmarc +06041988 +090487 +22071993 +28011990 +football83 +fifa2009 +21071984 +raiders10 +yoyoyo3 +rrr +pool123 +27091986 +lady1234 +07061990 +sandhu +821010 +antonette +killer0 +icetea1 +nina1234 +myspace95 +iglesia +rfvtym +lord12 +simens +katie10 +frfltvbz +awsedr +500008 +16111983 +landon06 +emily23 +langka04 +bandit69 +blacknight +cookie07 +22071984 +10081982 +winters +admiral1 +jjj111 +cute15 +riches +shkola +blondie12 +zidane5 +140183 +austin00 +ромашка +wouter +chauncey1 +06091988 +198122 +negra1 +bebebebe +anna10 +doodie1 +080591 +181081 +06101988 +2222221 +coolkid123 +annabel1 +07021992 +191985 +190001 +221192 +thebear +17091982 +04081992 +galapagos +celestino +trouble3 +07091989 +230679 +babyboy15 +firestorm1 +gary12 +vatoslocos +inflames1 +albert +letmein7 +oliver5 +slurpee +sonja1 +sasha1994 +040482 +0246810 +makaron +football86 +1forme +18091990 +wizard123 +india@123 +151986 +pyramids +bala +090979 +adam23 +angel#1 +gblfhfcs +manimani +batman77 +redsea +simone +youaifa569 +wilson11 +669966 +smarts +10031995 +nfymrf +12101994 +20101994 +game1234 +layton +chandrika +adolf +tweety18 +slamdunk1 +lyon69 +dogbone1 +osito +26111984 +020991 +everlasting +wenef45313 +birds +26081990 +26111988 +1champion +hector12 +26061993 +nitrous +ibm +13011983 +hunter55 +ivan1234 +210883 +iceman69 +haydee +09111987 +06041989 +010287 +fodase +garrett2 +1penis +hotline +w1957a +29111985 +red123456 +manchita +rascal2 +ilove11 +fucktop8 +300382 +mobbdeep +familia5 +toothbrush +caro123 +lauren18 +dupa1234 +totally1 +enjoylife +hawaii2 +051283 +emelie +wootwoot +gil +genesis1 +iam2cool +phi +satine +sandy01 +29111990 +170293 +18011985 +ainhoa +jr12345 +pippo1 +qwertyq +013013 +environment +chris143 +161161 +samsung13 +14071984 +050287 +louisa1 +panthers89 +brit123 +358358 +sabedoria +123456789ab +breakdown +410410 +070390 +29061984 +lubimaya +opaopa +buddy9 +looloo1 +bernal +slut12 +baby2011 +76767676 +210577 +alyssa06 +230582 +donut +mouloud +070689 +12qw34er56ty +200909 +coco14 +alex1983 +jesse5 +daisy4 +cool24 +richard! +asshole +pookie7 +boomer13 +francis2 +13041985 +020582 +kona +gabriel22 +khan1234 +311281 +lupe123 ++ +aleksej +63636363 +cobblers +04031989 +16081983 +joseph07 +akhilesh +thisisgay1 +chaudhary +athens1 +lovingme +steve01 +binweevils +dipset123 +130185 +241081 +27081988 +playgame +bayliner +biggun +katharina1 +fancy +2811 +bigboy21 +octopus1 +1qaz2wsx +1269 +piano123 +caceres +asshole101 +travian +trevor2 +basti +purzel +mario23 +mic123 +kyler1 +glock23 +rachel +20091992 +killer25 +candyass +montana +16091992 +05051981 +211081 +peaches4 +n12345678 +tobias123 +03061984 +yamaha11 +foreverand +dfghjkl +191817 +tigres1 +090908 +nirvana12 +malaikat +zac +iguana1 +cottoncand +match +matt16 +allmylife +2502 +110051 +rosa13 +daddy8 +orange16 +070793 +chelsea15 +13101310 +2580369 +prettyboys +31071989 +kahne9 +sixsixsix +260184 +united12 +dylan07 +slipknot123 +onyx +robocop1 +hujhuj +7777771 +301301 +23021994 +boudin +skate69 +281084 +motomoto +beleza +jeepjeep +ячсмить +horses01 +161080 +feanor +fatboy3 +cheese8 +come +050991 +anna1997 +010583 +kozlov +madarchod +jade13 +100179 +football94 +robertino +christ +010782 +09101987 +boston7 +198205 +miguel11 +navyseal1 +azul123 +darling1 +2802 +10061994 +randi1 +050684 +delia +woods1 +tdutif +05121991 +uytrewq +inshallah +poop01 +david77 +sparky69 +jasonb +tacos123 +27031984 +crazy1234 +carisma +starfox1 +windy1 +30101982 +izabella1 +12121978 +071283 +kris12 +10091982 +2209 +garnier +rugrat1 +08071988 +papamama1 +tiancai +heaven +modesto1 +trilli +27051993 +bigman12 +woogie +270580 +02101983 +drew22 +16111992 +123man +violence +chrism +240285 +angel123 +over9000 +changeme2 +21041993 +retirement +winner11 +september +frank13 +180583 +duckies1 +tobago +06101989 +rai +cody10 +199393 +vc123456 +26031993 +sept19 +doggie123 +12081994 +tyty +ellada +mylord1 +aarons +69966996 +nicolino +fortis +26051985 +03081993 +26041985 +karlmarx +skipper2 +sugar11 +500033 +jannik +charmed2 +callahan +leona +alex111 +m1ch3ll3 +2112rush +199515 +070289 +03101986 +teamo14 +naruto94 +17111984 +070389 +741852a +que +eastwest +sundevil +fuckoff22 +789521 +08051989 +29051988 +liverpool09 +hemlock +katherine +zero11 +12011983 +04101991 +evil123 +050783 +rocky21 +010383 +jamaica123 +johnny4 +zhuzhu +071286 +godsfavor +bandit22 +elina +brinkley +140781 +ninja11 +pretty15 +blue777 +yellow88 +alexander12 +07071994 +leeryan +22051983 +sonechko +231178 +sammy07 +froggy13 +20101981 +120875 +mariokart +000069 +cellardoor +angel34 +peaches69 +juanjuan +05061983 +thomas89 +yfcnz1 +nastya1 +22011993 +260482 +seeking +marina13 +00000008 +batteria +chris. +bogie1 +10031994 +w1955a +12213443 +socool +anna1995 +westside21 +peanut06 +basket11 +unity1 +07041986 +midwest +crazycat +bahagia +011084 +thebest99 +27061984 +pebbles +081087 +honda98 +040885 +1234wert +ilu123 +karol123 +hisham +101012 +199311 +oaxaca +mitten +010171 +turkish +260680 +290884 +12081981 +junior9 +09031987 +199611 +montblanc +15021993 +jmfxl78nhe +250193 +branco +alianzalima +england7 +roxy10 +1f3q8aunke +casper69 +comandos +001972 +selamat +tinkerbelle +eclipse2 +eddie13 +pirulo +sharad +190591 +02091982 +aaaassss +200381 +070885 +frederique +vvv666vvv +porcupine +samuel13 +03081986 +spookie +998998 +24seven +girafe +bj1234 +33103310 +naruto24 +butch123 +mancha +homeless1 +gabby13 +14031992 +player15 +200810 +maddie3 +s1s1s1 +cghfibdfq +william16 +10011993 +jarrett88 +21041994 +tiara +sardine +trucking1 +tpklmq9668 +mindless1 +11111aaaaa +300482 +trinity5 +amanda06 +estefania1 +fernando9 +rideordie +molina1 +16051984 +dancer16 +202 +toronto +stephanie8 +florida09 +fuckoff9 +griffon +sasanext +summer89 +13041984 +comedian1 +manuel01 +500050 +fotball +bankhead1 +060887 +751953 +carter01 +198203 +140192 +04011985 +01051992 +scooter4 +16071986 +parfum +270284 +newhome +lemonlime +marie89 +alannah +raiders81 +a1a1a1a1a1 +chris04 +311280 +03011985 +pringle +professora +sandi1 +sexy03 +saintsrow2 +sangre +ryan24 +keziah +maple12 +daniel96 +invader1 +loulou123 +kayla15 +170283 +andone1 +master101 +fktrcfylhjdbx +diva101 +080292 +2ps5wlc4xq +060609 +kenneth +uchiha1 +toxicity +200482 +11111k +jonathan8 +student123 +lauren15 +lovemylife +ginger6 +1chick +170992 +brian23 +mikey7 +180682 +allahu1 +2277 +lsutigers +22061983 +kiefer +michal123 +heihei +171080 +ginger14 +kristofer +chad85 +280282 +07081988 +god4ever +museum +jeff11 +25041983 +jo +06081984 +jamaal1 +manuel11 +24071984 +reddevil1 +lindsey +siberia +anna1998 +leto2010 +boss1234 +11101992 +nimrod1 +nuclear1 +scotch1 +mando1 +poohbear21 +04031986 +tuna +060388 +051182 +1606 +hamster12 +14051983 +10111993 +1234aaaa +21101994 +121096 +27071983 +24011986 +090290 +savannah3 +26031989 +joao +rdfhnfk +anime101 +09071988 +270583 +vivi123 +030591 +harry11 +bujhm +butterfly123 +220882 +love50 +mylife12 +amber08 +domingos +nixon1 +07121986 +qw1qw2 +super69 +hokies1 +lola13 +pancha +horses7 +sat +191086 +sexymom1 +kcchiefs +04021990 +ksooz +fishin1 +250481 +2552 +230182 +160481 +lanlan +greenville +teamobb +ivan13 +09091982 +goofball1 +montana123 +jerusalem1 +cookie18 +melissa9 +alessia1 +awsome123 +14041982 +leslie2 +nihongo +bleach12 +1988comeer +yoville +southside6 +291081 +ja8yc8uxsx +17111991 +05041989 +09081988 +marley01 +dsmwssr955 +jomari +eeeeee1 +manhater +06101986 +10041982 +tongtong +070489 +2606 +nothing! +14081992 +friday12 +elaine +starman1 +amanda25 +0410 +maicol +nails1 +170292 +151985 +daffodils +lele123 +08021992 +vanina +06121985 +270982 +redwolf +davidj +145263 +140580 +donald12 +22041982 +261281 +100578 +ace154ever +041083 +cheeta +fernandito +18011984 +nana23 +jenny22 +alalal +aolsucks +vitara +kevin! +400604 +09101991 +110394 +mani123 +3105 +serendipit +emma07 +loveguru +spacey1 +shaquille1 +pasha123 +5starg +zamalek +100677 +187 +310384 +reaver +porno123 +123234345 +romanista +132333 +newlife7 +booyah1 +skaska +iloveu15 +mustang94 +wolves123 +race +overload +william06 +220578 +rodriguez2 +steven16 +monkey78 +atanda +zooropa +flavie +theone2 +love1111 +babe01 +14091985 +08101991 +david. +050291 +hannelore +hollister6 +galang +siberian +140295 +050387 +200480 +sashas +jayjay13 +123pimp +gemini23 +12345698 +nassau +kitty16 +08011990 +gopher1 +220183 +luke01 +eminem5 +blue29 +whodat +memo +babylone +money2008 +invaderzim +unleashed +imbored1 +choco123 +basement1 +money$$ +factor +1thuglife +12501250 +250781 +198427 +jayden04 +wayne3 +190282 +favorites +050785 +01081983 +08061992 +skate4ever +heater +guitar4 +party2 +merlin11 +02041980 +24031985 +akinwale +060785 +kai +bigboy14 +sebastian1 +123happy +19851986 +prince21 +25021984 +110577 +jason18 +lavida +hoobastank +18051994 +steward +adi +221989 +shannara +260892 +boulder1 +intense +zasranec +1pickle +diane123 +milhouse +210681 +27041984 +ilovem3 +hairy1 +shutup123 +180293 +qwertyuiop1234 +jimihendrix +huntington +sniffer +summer17 +riversidec +jazzy13 +mikel1 +rage +eden +groundhog +08021985 +nfqcjy +1144 +sundari +9379992q +computer8 +poiuy6 +hello45 +poissons +1923 +newyork10 +160991 +fkbyf001 +flathead +grad08 +010881 +mark +04011987 +300192 +baggins1 +31011986 +05121992 +07011988 +rachna +charchar +09061990 +alanis1 +010283 +navigator1 +lastfm123 +puta +mostro +adeleke +lis +stafford1 +10051982 +159357q +classof12 +010286 +171082 +1236540 +kitty08 +b111111 +1321 +yuiop +170382 +rainrain +flashback +selena2 +flossie1 +mookie12 +131984 +wizards1 +janani +boone1 +hammad +ugaug55jdb +barbie69 +22101993 +bonou2 +060489 +joker22 +balla4life +haribol +dr4life +mclean +15121994 +halliwell +dirtydog +buster15 +20031980 +pitbull3 +pratap +18061989 +striper1 +jackhammer +ginola +nyq28giz1z +longdong +solare +amethyst1 +10061993 +brittani1 +jordy1 +160493 +301191 +g00ber +iseeyou +bitch89 +1goddess +guitar22 +cheese6 +dallas24 +240981 +yfnfif +brentwood +margarita2 +2323232323 +2406 +travis3 +roses123 +favored1 +300891 +single10 +160782 +blow +love1985 +090488 +night123 +alejandro7 +tiesto1 +kinetic +purple28 +010892 +gordon +06051986 +26121982 +cupcake101 +usa +apple99 +packers04 +cassie10 +08101986 +sarah08 +lexus123 +24051993 +adam21 +25081985 +31051984 +liljay +spider01 +250780 +atlant +anjing1 +peejay +dolphin8 +alegre +trevor11 +dirtbike2 +babolat +120394 +masahiro +170483 +yourmom11 +lampard123 +falcons2 +24031992 +18101983 +lapins +hateyou2 +blue05 +wijaya +hanuman1 +wang +frenchie1 +050491 +bet +180681 +090189 +vivitron +knight123 +bakla +00000o +mansion +paralegal +060585 +one1two2 +voetbal1 +21041984 +jager1 +lugano +328328 +cleopatre +gfgfgfgf +gabriell +280782 +manilyn +tigger33 +codydog +kizzy1 +cb1234 +victorhugo +000003 +tuananh +renzo +020592 +imhotep +177177 +garry +shadowcat +mariafernanda +weareone +fernand +280287 +010106 +2hott4u +doutdes +chinita1 +iluv69 +samy +23071982 +j7777777 +231278 +cadets +requin +lmfao123 +lincoln +jonnyboy +mefisto +shannon11 +01051982 +firehouse1 +killmenow +tennis13 +feder_1941 +blondie3 +fresita1 +1chevy +traxdata +198607 +marcos12 +151987 +4848 +pele10 +krakow +210593 +24121983 +mahler +22111982 +blink183 +123mom +080389 +10101977 +julian11 +register1 +caralho1 +water7 +1gabriel +21081984 +princess29 +01031993 +tomtomtom +doorknob1 +131987 +1please +051082 +liverpool11 +melissa. +rc.irf +stupid4 +olivia4 +adrian08 +asdfgasdfg +ak123456 +500062 +orphee +06121989 +jonathan4 +lafayette1 +dinodino +jack08 +26101993 +nikon +02061981 +03051992 +190382 +180186 +040891 +sweetlover +harajuku +chelsea. +ilovemymother +cameron9 +password2010 +sponge12 +babyboy! +serpico +sammy69 +fakeid1 +aly123 +benjamin7 +26091992 +pipopipo +joseph9 +goodyear1 +nasfat12 +jenny69 +steven4 +deinemutter +abcabcabc +catgirl +04091988 +heydude +naughty69 +pollyanna +braydon +arenas +daniela2 +freak12 +7979 +контакт +11261126 +blood4 +pooh08 +16021982 +040583 +brenda +fletch1 +200492 +asqw12 +fkbcrf +130480 +151181 +pantera123 +jo1234 +04031991 +26041983 +110594 +alinutza +maciej +pimmel +gofast +190581 +christen +getlikeme1 +3004 +bharati +katorse +13061983 +101276 +horses5 +2bigtits +201988 +100493 +redeyes +1houston +everybody +ethan3 +brianna10 +11112 +26071983 +getmoney07 +198224 +satoshi +aaaaaa. +ajax +26061983 +16031986 +197411 +cool69 +251079 +01071993 +kayla07 +sebastian3 +190885 +burak +060592 +pacers1 +kayla22 +300882 +221279 +saltanat +110277 +qweasdqwe +199218 +270182 +1pothead +delbert +delivery +2407 +infiniti1 +ramses1 +duckman1 +chocolat3 +110694 +louane +shayan +yamada +walter +youandme2 +eminem23 +kisakisa +040291 +cacapipi +13031993 +290691 +charlie16 +drawing +7angels +jake15 +04031988 +surekha +12051994 +tijgertje +ilove14 +95mustang +superman33 +19041982 +whatever8 +victor7 +1112223 +160492 +020984 +episode1 +hobo123 +qwerty20 +sekhar +harry5 +02031995 +xavier11 +20071993 +12345678aa +gallagher1 +kitten01 +meduza +ethan06 +garfield12 +26081989 +1w2w3w4w +skoda +jennifer6 +17051993 +annaba23 +darklight +marie25 +ipanema +04051992 +020186 +2525252525 +chakra +14061984 +orders +minombre +gwyneth +papillon1 +fordman +a11223344 +29091984 +renault19 +photon +250693 +24031984 +111222q +5353 +02091992 +rfhnbyf +keerthana +19081908 +pencil12 +penis11 +shital +anaheim1 +marie20 +178178 +hanover +gibraltar +mary22 +joshua88 +titanic2 +619 +rocky69 +daniel92 +darkhorse +arrakis +140780 +21091982 +scuderia +sophia2 +ainsley +belkin1 +15011984 +brianna +fireplace +16041984 +edinburgh1 +141986 +rjnjgtc +jonathan16 +191986 +061084 +monkey04 +199696 +1922 +01061980 +audition + +23091984 +troia +anabella +080290 +300680 +29121984 +breakdown1 +pompon +04040404 +descartes +amanda1234 +golf11 +30091989 +060786 +beaver69 +260591 +16041989 +mylady +cowboy10 +leonardo12 +1423 +031282 +bluefire +nadanada +wander +08081980 +buttbutt +bombshell +madyson1 +arcadia1 +maryjo +28031984 +p455word +roxydog +lovedove +nigger9 +blood6 +bloodlust1 +number33 +monkey420 +180283 +smiley3 +xpress +20051980 +08021984 +1malaysia +donatello +goofy2 +deathrow1 +babala123 +kaunas +vtkrbq +harry01 +a7xa7x +jake101 +lisandro +gunblade +600033 +july02 +bizarre +kourtney1 +salem123 +elbereth +babe23 +ripdad1 +197512 +kaulitz1 +ladydog1 +clare +happy1 +zhjckfdf +4thekids +290491 +241987 +xpressmusic +caroline2 +coaster +25111992 + +191291 +naruto0 +240792 +djdjdj +smiles2 +28071990 +0812 +4xxlqu94yo +143341 +candyapple +31101992 +#1daddy +159753852456 +jubilee1 +123pop +courtney13 +jesse01 +nomad +121177 +232 +12081980 +sticks1 +1933 +sniffles +21071983 +240781 +420pot +pato +04021991 +0512 +400021 +324324 +negros +client +010203040506070809 +lovers09 +140883 +raymund +samsam123 +30041984 +angelica +internal +bubblegum3 +030381 +280783 +123452 +1231233 +paintball3 +asdffdsa1 +honey8 +271280 +schoolbus +251985 +imran123 +dillan +summer24 +mewmew1 +waffenss +princess44 +trustno1 +wazup1 +lovely18 +pebbles12 +japan4 +daewoo1 +steve +yourgay +felina +lifeguard1 +johanna +studly +dark1234 +fiona123 +19966991 +leonie1 +090289 +bballer1 +emmalou +kissthis1 +dragana +bobsaget1 +slutface1 +battousai +198207 +manuel10 +7845120 +290582 +fhnehxbr +breebree +mylove09 +i4gotit +tigers4 +gatekeeper +55555s +02011991 +lunarossa +1452 +jupiler +1alyssa +251279 +170481 +deuce1 +bumerang +inverness +22121993 +vfhnbyb +122000 +messer +010291 +081086 +juana1 +keira1 +normajean1 +vfrcbv +kiki01 +131989 +265349 +30081985 +020684 +htrkfvf +07091991 +kaibigan +ibukun +sargent1 +beer4me +lemmings +03121988 +041281 +17111992 +amoremio1 +pitbull12 +open12 +oracle1 +newuser1 +77 +jaclyn1 +250282 +shelby! +charlieboy +gabriel08 +sushmita +marsupilami +montoya1 +08051986 +manny12 +elijah07 +tommy69 +260492 +teddy13 +155555 +01031982 +rocky +198507 +170393 +thelordisgood +buster9 +23041982 +020492 +rachel24 +elephant7 +john33 +50 +gofish1 +19021984 +segovia +dragon12 +anjela +solosolo +440010 +milion +martin06 +polite +fulton +purchasing +telecono +28011985 +lunatic1 +280992 +1a2a3a4a5a6a +perro123 +302004 +lilman3 +adagio +cece123 +hardik +yfltymrf +sexxxy1 +sept26 +pthrfkj +weedhead1 +hello1 +bkmlfh +071282 +spicey +jacob9 +021281 +spock +256buowriz +16051983 +1212qw +20081983 +babycake1 +040682 +denice +alicia +malmsteen +1savior +1popcorn +motleycrue +fishcake +18dummy +chelsea23 +dylan10 +maria6 +qawsedrf1 +201079 +wolfpac +jb123456 +ihateyou7 +lucky! +buccaneers +160282 +1letmein +01101983 +maldini3 +freiburg +02121992 +040591 +18071984 +ratboy +161192 +270594 +050985 +deutsch1 +jessie! +123.123 +darcy +rediff +196700 +06121990 +money123 +virtue +blah22 +yeah12 +15321532 +kasia123 +ted +killer34 +fender69 +guyg56fghf +010784 +supply +elijah08 +01101992 +rimmer +dominicano +190483 +panda5 +07121985 +nowhere +030492 +abigail1 +andressa +2712 +mugsy1 +071192 +21101993 +magique +021192 +azerty789 +sanders21 +18081983 +18081984 +athletics +bigdog11 +03031980 +xantia +qasdfg +rainbow23 +lynn22 +fucklove14 +papero +master15 +football05 +mohan +harley77 +15071982 +tempo1 +taipan +121299 +surfsup1 +300582 +1brianna +newark1 +600078 +cococo1 +three6 +230381 +nasty69 +pimpin22 +lupita12 +*love* +infinity8 +05101991 +260283 +fuckme666 +pretzel1 +daniel97 +skittles13 +230180 +110878 +210695 +vasanthi +scooters +070985 +gene +17071983 +nunzio +cazzarola +bb +ulrike +ducati748 +pimp20 +vvvvvvvvvv +christal +liebe1 +021083 +kaitlynn1 +270884 +28021994 +vaness +gus +dezembro +alberto2 +aftermath1 +pharmacie +anhyeuem123 +kinger +pooh09 +10021982 +kazama +treetop1 +02031981 +pancho123 +02111990 +sexybitch! +12345lol +cynthia2 +06031988 +sleepy13 +colonel1 +magiya +newlife11 +joseph. +cheer22 +welcome4 +piglet12 +201293 +dreamy +07081984 +hockey26 +nyjets1 +music9 +popsicle1 +201093 +nina13 +270495 +deluxe1 +loveme17 +190291 +c.ronaldo7 +678901 +shadow02 +chargers12 +trendy +jm123456 +191181 +antonela +vivek +raffy +joann +fuckme22 +04091987 +formentera +1qa +harlequin +salisbury +150780 +sept14 +13071983 +22111992 +201281 +love1998 +thatsme1 +06021991 +loquesea +marilia +chachita +vivalabam +dikoalam +sadie3 +lolol123 +30011988 +daffyduck1 +190481 +190191 +shivbaba +qweqaz +junction +sanches +16111984 +150680 +cxzdsaewq +nitsuj +nkechi +130183 +305mia +eagles06 +ambrose1 +newmexico +chiave +19071995 +comercial +d111111 +seven07 +mellissa +mich3ll3 +nassima +zachary11 +cometome +krisna +goalkeeper +mihai +diego13 +nothing. +071191 +290682 +ronron1 +qwertgfdsa +sk8ergirl +mother6 +derby +miranda3 +parkside +weezy123 +ditto +salasana1 +ingles +anthony101 +08091990 +chucknorris +slavka +ireland2 +040190 +31071992 +golden11 +mabel1 +hustla +197810 +1singer +19111989 +19841010 +ersatz +111111l +maria17 +osbourne +allsop1 +psicologa +27121984 +011092 +240493 +cash1234 +brand +kubrick +thanhcong +600024 +chinook1 +13021302 +melocoton +090591 +090789 +290885 +fuckit13 +26091983 +meatwad1 +dillion1 +logan07 +3grandkids +marissa12 +cthutq +yahoo10 +i123456789 +hihihi123 +kenken1 +030309 +baby67 +merdaccia +devin2 +311082 +#1baller +farmville +06121987 +ahahah +ilovemom12 +whatislove +los +kahina +mojojojo1 +aries123 +210394 +trophy +hoi123 +sagittario +baby56 +ferhat +hummer123 +kamelot +hiawatha +onedirecti +goldfish12 +302020 +30061984 +flasher +13011993 +15121980 +040191 +400062 +sasha12345 +240881 +chaotic +08021989 +26071985 +apocalipse +20081982 +13031983 +kaylee123 +hooters2 +chicken21 +sim123 +love2fuck +09041991 +210480 +xavier3 +azertyuiop +peace23 +personne +winston1 +16021984 +121012 +tucano +illmatic1 +140481 +111081 +12061993 +neopet12 +orlane +060791 +09051983 +squid +rollin1 +demon12 +1803 +chivas21 +football91 +06091985 +gfhjkmxbr +inuyasha7 +heloise +sarah16 +faustine +ybnkoia569 +november08 +remember12 +beba123 +newdom +ad1234 +bmw330ci +23021980 +hiphop7 +hilario +1212qwqw +200781 +angela7 +240292 +highfive +fabietto +06091986 +bruno12 +560003 +packers +keepsmiling +100894 +04071992 +keines +driller +310385 +love4real +15901590 +net123 +25031993 +abc123!@# +july01 +150693 +emily08 +baba1234 +abcd@1234 +skyfire +bellbell +academic +katies +06011989 +26051984 +131293 +feliciano +pretty09 +qsefthuko +clockwork1 +kelly3 +i.love.you +cosworth1 +bernardo1 +lovesux +27081992 +yuvraj +fuckhaters +whatever10 +almaty +slappy1 +160592 +clean +diver +chicken +loveya12 +restless +041191 +kaylee12 +aikman +j3nnifer +810810 +razzle +123012 +myspace28 +pretty8 +241279 +brittany8 +140293 +bofo100 +jesus316 +10061980 +rempit46 +coronel +2805 +130000 +azteca1 +cacamaca +nani123 +austin24 +karebear +serega123 +011189 +jangan +1098765432 +melissa14 +0912 +qqq222 +toto12 +m666666 +missy7 +hooter1 +241991 +thebest12 +lauren8 +123578951 +east13 +kaka10 +limited1 +toiyeuem +23071993 +szkola +04071989 +090689 +28061987 +orsetto +alivia +basketbal +yflt +07051984 +blood7 +birddog1 +trafford +xjcri66kfd +202001 +kodaira523 +220879 +soulfly1 +ward86 +je +slapshock +alexis00 +graduate1 +colts88 +driving +15081983 +cre +1509 +22051995 +phillip2 +17091993 +12091994 +hihello +180282 +040481 +020391 +pepper14 +brian21 +27011990 +scrabble1 +05111987 +kiki22 +040290 +16091983 +2million +brittany18 +newyork8 +200792 +jacoby +16121982 +focker +08031992 +7777777z +theking123 +norway1 +25011993 +southeast +millie +15041993 +1tinker +zoccola +250679 +mart1n +231193 +muffin7 +kathy12 +27051984 +georgia12 +naruto93 +gabriela12 +kenseth17 +chels1 +05041987 +nanana1 +wolfen +031184 +220182 +canon123 +yankees! +30091992 +alex1980 +spanky69 +heinz57 +dempsey1 +zaqwsxcderfv +24061982 +061192 +15091992 +allah99 +child +fellowship +k123098 +050288 +energizer +05121984 +18031990 +cynthia123 +bitchin +2143 +130479 +130981 +qwerty765 +07061987 +02121981 +160792 +240782 +alexis16 +america15 +lokomoko +171081 +secreto1 +asdflkjh +baseball29 +yomomma2 +220393 +lakeland1 +123456ad +rileydog +250878 +yugioh12 +250192 +25111983 +motard +chessmaster +08061986 +luis18 +1231231230 +11271127 +29111986 +mybrother +pussy +alpha1906 +benjam1n +150182 +mamas1 +05041986 +notyours +11061981 +1qa2ws3ed4rf5tg +number18 +03031994 +michael00 +200392 +centaur +marines2 +yell0w +06031985 +whatnot +08021991 +scott69 +09051984 +280182 +230881 +marcus13 +hari +fallinlove +brenton +wootwoot1 +aymeric +lucas01 +13091992 +indy +teddy7 +thething +star20 +blanah +peanut15 +bikerboy +randy2 +brokencyde +05111991 +kool-aid +precioso +charlie17 +qwerty1990 +dianas +annelise +260981 +300191 +joey23 +332335 +ashely1 +kinga +iloveu4eve +meeting +junpyo1 +choppa1 +100495 +adolfhitler +polizia +natalija +kathmandu1 +24061990 +061183 +gauloises +nighthawk1 +112131 +08021988 +mommy2be +1larry +fartfart +hot4you +200681 +application +catdog3 +bubblez +bianca2 +charlie24 +sem +250792 +cosenza +111970 +18011992 +tink08 +scott11 +010592 +040189 +180382 +ypt123 +breasts +roxie123 +290184 +ava123 +skunky +198515 +040883 +abccba +chrispaul3 +22121981 +tro +huevos +baby87 +251194 +041190 +121973 +meridian1 +mag123 +9086916264 +vauxhall1 +ducati1098 +171987 +02061993 +iloveyou04 +peanut99 +coco69 +diablo69 +jonathan! +04121984 +dracon +1802 +040483 +20051981 +grihan +hat123 +- +3344 +lookup +ana1234 +170682 +2408 +alexandre +wealthy +06041991 +11011983 +walker123 +270592 +caleb2 +040785 +1jackie +eeeeeeeeee +150378 +190592 +bellamy +1fineday +07031987 +9988 +natalia12 +14041994 +jaxon1 +21091983 +tbfj7no671 +guzman1 +rfczgecz11 +bayram +iceman23 +teddy01 +sugar3 +zoey12 +power13 +iloilo +pimp45 +rfhectkm +asswhole1 +ytgfhjkm +q1111111 +tourism +10091983 +poopers +07121989 +tivoli +11121993 +skorpion1 +babyboy22 +school +april2008 +sasha10 +tiphaine +lotion1 +jasmine17 +310882 +15011992 +joseph8 +arequipa +brian22 +marianne +08021986 +puppies! +301092 +lucy22 +lovejoy1 +platoon +5grandkids +211293 +090787 +0612 +bigdaddy3 +210182 +songs +money247 +zxcvbnmzxcvbnm +genesis123 +180992 +04101984 +oklick +fuck999 +mopar +22021982 +miss123 +sa +cowboy21 +27041993 +sierra13 +20304050 +calliope +me4you +250980 +020693 +030680 +pandit +23091983 +boston10 +08101987 +nikki14 +brielle1 +obvious +fluffy! +brownie12 +ihateu! +23081983 +07101986 +junjun1 +123456kl +aparecida +christine3 +lilwayne13 +skorpio +skater6 +rockstar01 +bulldog11 +timeout1 +robert77 +09081989 +15111983 +rhianna1 +jerk123 +mmm666 +letsgetit1 +kzkmrf +trickster +tw +280991 +juehtw +telefono1 +barsuk +sweeper +giugno +katie22 +yellow17 +27111982 +rockstar4 +azeaze +james77 +01121992 +29111984 +301083 +majestic12 +15051993 +250284 +dragon26 +honda69 +melchor +niunia1 +julija +saber +27101984 +himura +bunny01 +havana1 +fuckyou87 +290384 +oxnard805 +chiens +potatoe +28011992 +130593 +leapfrog +211111 +novembro +040288 +311292 +240980 +fairydust +5zgb2t764b +ass1ass1 +820820 +19051995 +08101990 +261092 +korede +zoolander1 +070794 +humanity +200980 +julie2 +22011984 +superhuman +09101990 +horses4 +fucku4 +stargazer1 +fregis +anna1988 +2601 +hjhjhj +newholland +no +twilight14 +07031986 +vbkkbjy +campanilla +band12 +241193 +20111983 +121269 +123456789abcd +elle +metal6 +24091992 +digital123 +220991 +10011980 +hannah97 +spiderman +wetwet +smack1 +sergio13 +cheerleadi +lucky +3010 +poopie3 +jack5225 +buckfast +donnell +grounded +noentry +halina +06081985 +200184 +jessie10 +marine01 +missbitch1 +bambus +trashcan1 +curley +andrea16 +301081 +gfhjkm +66666a +rachel14 +huangjin1987 +murmansk +000111222 +bunnys1 +ditto1 +letmein3 +niniko +010691 +1sweetpea +abigail12 +199117 +bhavna +199010 +topgear1 +14021995 +kzueirf +230379 +krokodyl +teremok +kiss13 +water23 +30121982 +cartel1 +1drowssap +ayinde +1apples +1scarface +marmalade1 +amadeo +123india +martha123 +11091983 +gitler +robert06 +2funny +braulio +12345678abc +gazette +nike21 +06011986 +evidence +04121991 +151079 +15001500 +review +bf4ever +lampard08 +2604 +free4me +raistlin1 +cmpunk +foreveralone +sassy10 +anajulia +armelle +15101993 +jazmyn +whateva +skoal1 +gdn7414 +8585 +jagannath +carrington +lottery1 +june1987 +sammy! +charliebrown +130193 +12041980 +100280 +bahamut1 +230382 +warden +2741001 +shoelace +perfect2 +101176 +110379 +crystal69 +01011965 +240893 +drew11 +neha +gundam01 +miguel23 +161988 +lovesex1 +040791 +161292 +1johnson +mickey18 +anne12 +z111111 +bmw320i +minimal1 +29101984 +jake07 +sarthak +jayda1 +padmavathi +forever9 +101097 +09031991 +bentley +29031992 +hobart +$hex +strat +02011981 +jennifer9 +mistress1 +fuckhoes1 +30041993 +stef +kayla09 +naruto18 +25112511 +270481 +newyork4 +160283 +shotgun12 +lara123 +228822 +dima1992 +021284 +soccer4lif +tester01 +moomoo22 +nicetry1 +residentev +140882 +19111988 +darksoul +polka +31011984 +aavlg728 +college2 +montagna +230577 +gabita +my2boyz +sajjad +171092 +pooh07 +getmoney6 +surf123 +greater +03091984 +akucintaka +emilyann +ekx1x3k9bs +golfer12 +rose15 +gigigigi +222999 +nt +greenday10 +020880 +annalise +rich12 +1346790 +14021993 +220980 +hahaha11 +abosede +cdtnkfyrf +kayla! +dragon92 +destiny! +zeke +eureka1 +pokemon21 +rad +boost1 +peavey +cecil1 +school09 +mercredi +sally12 +latisha +lalo +custard1 +loislane +britney2 +22111976 +woobie +sept28 +beaute +1603 +flora1 +leighton1 +isidro +kennyg +221001 +tinker10 +bubbles16 +bmw318i +tokio +chris#1 +palestine1 +ricardo2 +a123b456 +17021984 +12345q +slater1 +03041993 +smoky1 +naruto17 +ara123 +jai +disc +playboy22 +iloveu1234 +helloman +abcdefg. +198309 +14011984 +198506 +bopper +xk55xdxcyr +maxell1 +030394 +steven17 +erfolg +05011991 +china2 +03051984 +danielle8 +homestead +hoanganh +012345a +diamond! +craft +03031995 +kindred +booster1 +donald2 +panda3 +199020 +05081984 +170684 +ali786 +ishtar +adrian21 +oreo13 +sept29 +lauren99 +kratos1 +boxer123 +water22 +200192 +gifted1 +demarrer +chad12 +hamida +cicamica +playboy +nikki8 +150395 +lytwa813ib +caspian +010195 +puma123 +dkssud +7896541230 +141081 +alesia +22051982 +310392 +nakita1 +dennis +juergen +chloe5 +patrick14 +estopa +cancer7 +halowars1 +pitcher1 +29011986 +mack11 +excellent1 +2psxvvd7 +09121985 +19281928 +09081984 +23091994 +310792 +optimistic +paokara +11101993 +dirtbag1 +06011988 +alias1 +alejandro3 +gothic2 +ncc-1701 +27101985 +help911 +mariel1 +bolivia1 +school1234 +59piru +aspirina +youandi +hakim +kardon +carlos24 +171984 +agata1 +21121994 +1sexyman +punkrocker +198314 +boogie123 +dexter21 +kloklo +010681 +calamaro +15111981 +corona13 +mikey5 +29041984 +1soldier +160880 +22071994 +1456 +hotspur +mexicali1 +mybitch1 +sen +lashae1 +tweety101 +jordan93 +121202 +chichi2 +071085 +fourboys +myonly1 +178500 +140208 +myspace90 +belly +rayquaza +stratus1 +060784 +alesya +rangers1690 +170170 +28101984 +1babydoll +olivia! +1qwerty7 ++ +wolverine2 +lololol1 +carbon12 +02111988 +assassass +molly101 +jordan94 +21031980 +diogo +250579 +brothers3 +salam1 +230281 +stephen12 +ethan05 +161081 +junior02 +dogs11 +22101980 +27011985 +jared12 +komo123 +dumitru +addicted1 +020680 +30031993 +anacleto +candy09 +wolf11 +br0ken +290492 +050489 +emachine +opensaysme +khairul +kalima +dominican2 +06051989 +finder +escorpiao +myass1 +23101993 +ilovejose +25011994 +jeremy10 +bagpipes +rafal +12061983 +xdf65b6666 +150193 +clinic +443322 +mamoune +angelina2 +brisingr +07121984 +taobao887 +spike11 +mylife09 +154263 +iluvjesus +harbor +santos12 +1barbie +wel +erika12 +ljames23 +jacob! +sybil +rakizta +120396 +mommy24 +031182 +lindsay2 +170893 +08091985 +kamryn +speakers1 +shovel +030189 +twentyfour +16031993 +stomatolog +protect1 +010176 +10101996 +yahaya +cincin +natalie5 +igorigor +spider69 +viper2 +cupcake10 +corvette +putter1 +301181 +cheese9 +11041980 +cumberland +stephanie! +altoids1 +280482 +dario1 +bigtruck1 +girls4 +200993 +chrysler1 +marcel123 +gizmo3 +071184 +27111988 +emmett1 +06031989 +pariss +010792 +basspro1 +26011993 +dylan7 +123123c +45683968 +kamille +climax +1marcus +jeffrey123 +380009 +qwerty98 +1aaliyah +poohbear08 +abaybay1 +doradora +solar1 +131078 +angel4ever +198413 +241179 +star89 +121266 +19021993 +15081982 +venus123 +babyruth +play12 +madurai +4815162342q +dunkin1 +400000 +09081986 +churchill1 +hola11 +05101984 +25101993 +hayden08 +radios +homestar +dakota4 +nightingale +01041982 +140692 +skillz1 +sys +minecraft1 +man1234 +sluts +skater16 +simplyme +111277 +nemanja +joselyn +may1990 +hakan +fraser1 +dicks +linkedin1234 +18121993 +rascal01 +poohbear15 +1panther +football97 +windows8 +laura22 +15061993 +codybear +shaun123 +genevieve1 +dehradun +compaq01 +010591 +cherry8 +198221 +karan +honda97 +lucila +fender01 +240494 +trinity01 +02121982 +danilov +041183 +moschino +22101981 +210993 +111111c +131093 +waylon1 +8rlb9l1squ +579395571 +charlie18 +eatpussy1 +lovehim2 +flubber1 +06051983 +280383 +mollie123 +198714 +deangelo1 +chatham +tommy01 +morita +25011983 +martinko +123123aaa +chanel2 +buffy2 +autumn11 +england2 +redfox1 +polar +04011990 +drumnbass +isaiah123 +65432a +malakas1 +17051983 +knight12 +08041984 +guessthis1 +261280 +1420 +babyface12 +blanquita +casey7 +missthang1 +camila10 +150880 +lovesucks! +shah123 +legenda1 +faith13 +14041983 +gin +penguin11 +alex2011 +tombstone1 +suzuki600 +shippuuden +jackson9 +godknows +emily14 +231078 +15031992 +raster +020281 +270682 +metallica5 +charlie05 +vlad2000 +meditation +09031989 +robert88 +19011993 +vanechka +560027 +heaven +korn12 +020580 +199316 +eminem21 +vfr800 +marlena1 +pussy9 +portugal7 +27011984 +marzipan +dirk +army12 +15041994 +codename47 +hooligan1 +hajduk +penney +postman1 +redsox21 +110894 +queen13 +moon1234 +jeremiah2911 +777222 +mann +apple24 +chapulin +asus +kokos +frankfurt1 +opportunity +zepplin +tristram +smiley7 +fedorova +kjv1611 +bill12 +250879 +777123 +03041983 +anitas +vegeta12 +nigerian +1teddybear +samuel7 +2100 +18121981 +23031995 +junior. +bosshog1 +20011982 +16091984 +rebecca3 +methodist +nine +mariarosa +pretoria +ribery +199514 +qwerty76 +thomas1 +smith12 +lluvia +darshana +cicero1324 +nick17 +lemonhead +jeferson +anna14 +smokey23 +asdfghjklz +badass13 +dragon007 +andrea! +shaila +170482 +11061993 +jacob09 +lifeboat +1q2345 +turkey12 +03111986 +lupin3 +alicia13 +vasquez1 +gocubs1 +toenail1 +danielle23 +lumpy1 +welcome2 +aaaaaaaaaaa +virgil1 +111122223333 +224224 +moonman +victor3 +25111984 +06091984 +100395 +010387 +death5 +marieke +bmw316 +23081992 +boogaloo +lou123 +07081992 +291280 +090191 +josh101 +616263 +2612 +lancers +lucky25 +muffin22 +javier2 +04021988 +alexis17 +jojo21 +loveyou23 +smoothie1 +pirelli +160393 +0305 +nintendo +lyrics +saints123 +fenerbahce1907 +braces +21011993 +stephen7 +kyleigh +dallas81 +gamestar +xi345bjfvp +edgewood +18051993 +groningen +13111992 +moonlight2 +chienne +iloveubaby +2muchfun +frechdachs +251986 +newera1 +jenny21 +forever27 +12011982 +anyway +15031993 +10031003 +chato1 +150481 +crazy09 +baguio +iloveyou29 +saddie1 +merlin13 +nexus6 +chapis +199018 +230493 +282930 +permata +16041983 +sandy7 +198616 +220679 +dddddd +tam123 +bugmenot +banshee350 +doggy7 +djkrjdf +lovemenot +juandiego +letmein11 +678876 +sexygirl69 +03011988 +seekbang1 +040592 +198328 +alevtina +sarah17 +160984 +babydog1 +bobdog +030191 +deb123 +password54 +08051992 +horses10 +1hotchick +sudoku +porsche9 +01091981 +090589 +09041988 +johndoe1 +07101985 +2sexy4you +06021984 +nanonano +12345678ab +1z1z1z +332332 +24061983 +27061983 +midnight01 +sommer08 +asda +s55555 +06091983 +010985 +prabhakar +yourmom13 +rockstar15 +serrano1 +baphomet +blackie2 +30091990 +iceman11 +fred22 +2541435 +13121981 +305305 +190186 +24051992 +rafa +vitali +adinda +03111988 +happycat +kjgfnf +vista +lala21 +janka +21041983 +lovepeace +1234567892 +dayana1 +aqua +samantha15 +bondage1 +14021994 +deerhunt +050390 +040409 +06071983 +92631043 +linkedin10 +14011990 +ultima1 +loser8 +021191 +daytona500 +198916 +21091993 +kk +000420 +leopold1 +250880 +spiderpig +peach123 +080588 +04101987 +8888881 +svetlana1 +albany1 +15021982 +casimiro +tahoe +07051983 +ihave3kids +greenman1 +macherie +231093 +babyboi +playboy16 +payday1 +juicy2 +ivette1 +010482 +socialbook +doggone +coheed +05081990 +04021985 +morgan09 +124536 +240580 +antonio23 +branch +560064 +old +malysh +monster99 +kazbek +cooper7 +pasodeblas +10011982 +ganda1 +tomkaulitz +weezy +timofei +gbaby1 +coupons1 +gokhan +1cutiepie +070987 +blessed12 +roleplay1 +100193 +gemini123 +johnson3 +hellomate + +shopaholic +1726354 +pineapple3 +stressed +11051994 +denver15 +0214 +scorpio +max2010 +1iffqb66tw +foufoune +24071980 +bungie +golfball1 +freedom6 +lild12 +00001234 +anna1991 +150380 +takeover1 +kailee +carmen13 +12051982 +m55555 +060984 +jonas13 +crusty1 +ramstein +honey07 +kir +170993 +nick09 +vfvekbxrf +eminem22 +bozkurt +gordis +04041981 +tetsuo +ness +jerome +04081985 +030892 +220392 +220793 +sorento +567 +270292 +f0lhvbok +23081993 +2muchmoney +dududu +nightowl +greygoose1 +castaneda +scopare +billy11 +nayara +280982 +190383 +qqqq1234 +вконтакте +bestie1 +02071981 +tunnel +hellobaby +rockhard1 +25061982 +teddyb +140993 +spike3 +dumass +casper7 +economist +therock2 +green27 +stylist1 +pokemon14 +leonel1 +1921 +091292 +11122233 +02121990 +lennart +exbntkm +spartak1 +29121983 +james. +ankush +hood +charge +caramelle +160691 +13641364 +12071994 +best12 +613613 +magazine1 +27121992 +cristel +1qazxsw23edcvfr4 +baby96 +stitch626 +xiaofeng +telekom +xavier07 +krishan +dipstick1 +141093 +199600 +danilo1 +bhabie +241079 +lena12 +mudar123 +fpna23aas1 +animals2 +jesus001 +chloe06 +221992 +jerk +29041993 +reseau +cody22 +280583 +honey16 +penguin! +160382 +13061982 +lioness1 +400056 +2401 +29021992 +kabayo +biscoito +moonpie1 +jordan23 +210481 +dreamer7 +dark13 +pensacola +hoffmann +amber4 +301291 +02121984 +roach1 +cabeza +roberto +in +lawman +ashoka +17081993 +wolf1234 +princess30 +mughal +noynoy +17091989 +080986 +18111983 +04101989 +cute18 +asm +05041984 +yahoo. +cheyenne +donald +joshua1234 +050883 +slave +vampire6 +piercing +05061982 +cas123 +121212z +brittany17 +sophie5 +chayank +251278 +100695 +02101982 +1608 +brother12 +sports5 +araujo +jasmine101 +sanrio +double2 +131985 +sammy8 +198403 +100678 +laulau +camille22 +toyota12 +book12 +salsa123 +123456dm +198503 +avokado +booger11 +14091984 +44554455 +02051992 +linkedin13 +eagle12 +miangel +sheshe1 +dabest +andrea17 +brooke5 +02031980 +polipoli +scruff +happy +x15piq8snj +200992 +m7777777 +loveme88 +tatenda +caboose1 +00007 +25011982 +ilovesean1 +151291 +asd111 +archie123 +7123456 +singlelady +relientk +tink10 +mama14 +mexico16 +malfoy +fdhjhf +manutd07 +slick50 +karin1 +22102210 +03101985 +240592 +establish +anahi1 +hanibal +030292 +random2 +passwordnew +domino123 +lovemoney +bonnechance +191082 +kumars +whatever9 +google10 +qwerty92 +pookie69 +010392 +tdws011286 +pigeon1 +misspiggy1 +madison02 +1ranger +bobita +ashley95 +61616161 +22081980 +09041984 +ladyjane +22031993 +iwillwin +avellino +021091 +microwave +heart5 +happy24 +newmoney1 +07031989 +charles01 +piglet123 +ilove8 +051091 +chiboy +monina +26081983 +02091990 +sept30 +zkmxbrbcbkf +bailey04 +catfish2 +kayla16 +pimpin14 +2705 +financial123 +nicholas9 +latina13 +q1w2e3r4 +iloveit1 +130992 +patitofeo +1single +zamora1 +04101983 +chester01 +080192 +crispy1 +030395 +jemjem +summer33 +hancock1 +aaron07 +disney11 +nadira +04111988 +fuckit. +petros +151178 +24121980 +1denise +snakeeyes +120795 +020792 +box123 +251984 +cheese14 +emmanuel +01091980 +paarden +ethan07 +matthew02 +table1 +nectar +jammie +alexander! +198125 +joplin +love789 +duval904 +1stephanie +18061993 +02101980 +numb3rs +080689 +badass3 +samsung9 +198223 +200900 +gladstone +28101982 +ashland +1801 +150679 +123456xxx +16011988 +sk8123 +printesa +cavolo +myloves +818283 +apokalipsis +121297 +spencer7 +sophie08 +plankton +emma2007 +mexico07 +ilovej +121203 +d1d2d3 +040584 +112233445 +ranma12 +flip123 +141280 +panda7 +natali1 +badshah +11121982 +emily05 +280283 +sexygirl11 +zse4rfv +mj2323 +casper3 +210193 +quack +rennie +chocho1 +hiphop3 +blondie +281093 +lorna +sampath +teach1 +bully +400077 +bonny +softtail +06061980 +280384 +180893 +shithead12 +zxc456 +poopy5 +sundown +niccolo +06101991 +091085 +patrick15 +27121982 +221293 +eloise1 +qweqweqwe1 +biquette +280878 +desperado1 +kika +080391 +161986 +220394 +j3nnif3r +vbitymrf +tooshort1 +pimp88 +popkorn +vfieyz +bettina1 +olivia05 +zarate +billy13 +03011992 +beerman1 +mickey17 +240282 +myspace94 +24061984 +110101 +volcan +summer1234 +060484 +dallas8 +santiago12 +allstar12 +logitech2 +azn4life +cristianor +fordranger +toasty +girl101 +hockey87 +140880 +1245789 +031191 +iloveemily +011190 +asawakoh +30071983 +steve13 +ravipass +ktybyuhfl +winter5 +17081985 +198715 +150579 +res +11041993 +abcdefg! +28041994 +isabelita +201294 +29111983 +raghavendra +iamking +maranda +doo +pepper6 +shorty9 +swe +desktop1 +qq +prisma +direct1 +nicole0 +090190 +porque +kokomo1 +puzzola +millie2 +topdevice +ashish123 +truckdriver +dan1234 +kalvin +pattaya +336633 +djghjc +jason25 +omfg123 +05101983 +t5e1q9shfd +tracteur +mickey24 +07041985 +snowman12 +cornerstone +cdznjckfd +abgos999 +countylib +allison3 +198608 +protozoa +010883 +01051993 +120876 +yoda123 +040991 +marshmellow +thebomb1 +rafale +30081984 +foggia +efb +02051980 +single07 +alikhan +120378 +andrea4 +11051105 +119110 +gutter +vlada +harley88 +171989 +die123 +bobber +talent1 +teamojesus +machines1 +leboss +09031985 +yamini +yu-gi-oh +197910 +bigdog13 +198127 +311080 +johncena5 +bigdick12 +060884 +cthuttdbx +nathan16 +101274 +230893 +pimpin9 +11061980 +070189 +y123456789 +21012101 +01081993 +johnathon1 +santos10 +1monique +celia1 +chickadee +crawfish +iloveme09 +201292 +02091981 +rawr1234 +yahoo22 +nice12 +tiffany5 +bailey1 +qwertyuiop1 +290189 +190883 +19111983 +homer2 +rootroot +abcdef3 +barry123 +230277 +peugeot1 +harmonia +napoletano +vladut +15061982 +chonchon +detective1 +kayla6 +memoria +vfrcbvjdf +nicholas8 +pw898klkag +devon12 +231279 +mummydaddy +280881 +loka13 +180187 +gunit2 +141141 +240593 +alfaomega +tishka +lex123 +hunter20 +dope +hailee1 +2402 +светлана +lizzard1 +anarchy666 +112233z +myspace32 +pussy1234 +1slipknot +11119999 +innova +15111982 +peinture +imperio +anna1993 +stapler +120695 +300483 +13021983 +hotdog7 +230181 +lauren08 +sexybeast2 +broken12 +21061994 +james27 +200491 +88keys +metalman +nikole1 +backyard +ask123 +08071992 +09051988 +sillygirl1 +fktrcttdf +19121993 +528528 +700029 +23101981 +cecille +dav123 +17111983 +chupamela +alaska2 +superpuper +05021984 +gabriel07 +12345671234567 +sweet8 +annies +deepa +gusanito +paspass1234 +devil2 +adriano10 +soulreaver +albator +poopoo! +eightball8 +liverpool! +bigboy9 +snoopy14 +210579 +08071990 +lovefamily +batman00 +j123123 +1iloveme +junglist +4monkeys +070288 +021182 +tevion +mm +20061980 +corona12 +14091992 +ilovemen1 +maximilian +151279 +16061994 +16071993 +manis +domenic +2356 +lufthansa +01111986 +arizona2 +buthead1 +lindros88 +extra +29101983 +rfpfyjdf +28021983 +beautiful6 +infirmiere +ferrero +030484 +kiekeboe +floris +07011987 +06051992 +marcelo123 +gitano +100595 +vandam +04031992 +smiles123 +worldofwarcraft +youtube12 +020280 +01101982 +rose16 +hammarby +09011990 +30111986 +120505 +rudy102 +sharlene +anthony04 +maravilha +nhfnfnf +chloe10 +bella05 +16021985 +peaches22 +sandiego13 +198917 +02071980 +snickers! +daisy +leona1 +megan10 +genial +girija +chloe07 +romantica +shopping2 +dewa19 +741000 +010201 +monique7 +230995 +moriah +el1zabeth +couture +warcraft3 +jerk77 +ladybug11 +20111981 +oceanside1 +nursultan +linkedout +polkadots1 +mak123 +07091985 +560011 +terry12 +mixtape1 +tacobell2 +avrillavig +egyptian +marlowe +xavier13 +aventure +04041982 +1bubba +080488 +mishka1 +sexyako +050594 +paco12 +frog11 +dawn12 +02081993 +050791 +160391 +02041981 +160184 +110181 +dorothea +redsox3 +ostrov +15051995 +20011994 +fordgt +ganesh1 +24051984 +08011991 +13091983 +london2010 +bassett +falcon16 +14021980 +fuck15 +198513 +emma2006 +harley00 +vitaly +01101993 +xdxdxd +qn4kbwv559 +bourne +050784 +ben12345 +nene13 +angeldust +facebook2 +98765432100 +jackson23 +sandy13 +askimaskim +kaitlyn2 +pogo +p1mp1n +pokemon. +0510 +bulldog13 +balikpapan +leo1234 +sociology +090786 +122188 +marshall2 +a456123 +marine2 +ellipsis +310783 +07091986 +friends23 +200682 +1brandy +rabbit11 +country123 +mosaic +05031993 +100793 +lollipops +17091984 +noneya +27051985 +shyann1 +gizmo11 +bonita123 +mike44 +thegame2 +06111990 +ilovedylan +laure +23061982 +gerasim +290292 +hijoputa +ambot +zodiac1 +sarojini +doc123 +20101980 +scotty123 +godhelp +daquan1 +whore12 +invasion +dem +myname2 +catalog +hearts! +140707 +luke11 +stanley2 +260380 +04111991 +ikarus +06101985 +02111984 +bigtoe +azertyuiop1 +tinytim1 +100percent +power4 +noone +200283 +topmodel1 +qwerty1234567890 +02111991 +dolphin11 +mikey01 +umpire +lilbitch1 +poipoipoi +longjohn +090486 +rugger +trust123 +johnny08 +140206 +rjntyjxtr +poohbear23 +3838 +michi1 +tony16 +gotyou1 +greeneyes2 +06041986 +bigjim +adriana12 +201061 +earthquake +pitbulls1 +guitar10 +kri +baboshka +qwaszxerdfcv +240381 +peanut24 +060189 +02051982 +071087 +andrew27 +100878 +msn123 +jason! +07021984 +somalia +cassy +280485 +260606 +26011992 +zuzanka +01031981 +ilikeu +fidele +josh09 +jt1234 +pepsi5 +06031983 +banner1 +mum123 +110278 +gizmo01 +ooooo1 +dd +azerty13 +antonius +legion1 +051192 +kumaran +mark14 +14031983 +boogieman +012511n +natedogg1 +rere123 +bubba21 +instinct +bar123 +hockey55 +jokerjoker +bella2009 +jackass11 +motherof5 +bella! +fallen13 +thehulk1 +pearljam10 +taylor1234 +unicorn2 +pretinha ++ +190982 +boknoy +200280 +190381 +02040204 +180182 +nicole29 +joseph19 +110060 +shepherd1 +111234 +happy88 +friendsfor +17031983 +170594 +0104 +bagger +310781 +196400 +trick +advertising +frazier1 +260581 +caritas +newtown +buster1234 +martinek +corsa +blacky123 +chilango +tanveer +hammy +karabas +barnett +green. +shitbag1 +aaron22 +2hot2handl +2605 +love345 +hello25 +080190 +30081992 +anna1992 +10051995 +marecek +holder +jamari1 +widzew1910 +red555 +110777 +killer12 +231984 +03031982 +strings +sabrina7 +marcus21 +latisha1 +angella +magnetic +050389 +berlin123 +b8ca6yz1nj +hollywood5 +woods +05011988 +darknight1 +freebies +yyyyyyy +1lovee +alexandra +sverige1 +spotlight +johnny10 +jadore +dragon95 +logan10 +57575757 +yyyyy +fylh.irf +ralphy1 +nazarova +franchise +kambing1 +180394 +19071982 +gabriel4 +taylor101 +031283 +tommy22 +dubstep +homeschool +corleone1 +march07 +07021988 +4g3uvrxn7w +rainforest +kohinoor +robert1 +michalek +24121993 +king17 +101072 +1234567890d +trinity12 +10081994 +freemail +kyle22 +171293 +l0ll0l +200879 +chloe08 +angel333 +frankie! +pepper9 +17031984 +hhhhhhhhh +lada +wingnut1 +27101982 +sweeney1 +imhere +memyself&i +messi1 +scarab +12901290 +brandon101 +smackthat1 +senators +banana10 +jakejake1 +06031992 +roblox +copper01 +persephone +paulette1 +a1b2c3d +spiritual +19081984 +lovers08 +black +iloveyou1 +200678 +310391 +230193 +72727272 +blackass1 +290781 +623623 +galata +hvqjvxvb76 +servis +farhat +guitar101 +redsox09 +samarkand +artem1 +0112358 +alexis98 +271984 +fuckyou25 +cameron! +191091 +cathleen +123abcde +mariaeduarda +jesse14 +160582 +laurent1 +madiha +220193 +260982 +jones12 +05021993 +bubbles +ktyecz +marie1234 +pink95 +120194 +23041983 +030681 +slutbag1 +29081989 +friends21 +cha123 +03091990 +211192 +230380 +chase01 +46and2 +hx28o9e646 +070592 +trinity4 +pretty9 +rtrtrt +31101983 +erdbeere +twokids2 +icare123 +jason09 +day +eggplant1 +fit4life +1butter +13631363 +cristo7 +19861212 +joker15 +bartolomeo +0304 +1500 +glock45 +landon08 +poussy +vanilla2 +protein +28071984 +duke21 +blonde2 +whyme123 +020781 +maison1 +1314258 +alabala +eric21 +secret. +adidas23 +17121981 +iubita +honey15 +apple15 +nelly12 +babygurl19 +bibi123 +271091 +221179 +inuyasha3 +anthem +quintin1 +bigman123 +zaq1qaz +pitbull7 +3103 +sunkanmi +illini1 +sasukeuchiha +maharot +7sfqc8zi5d +22011983 +holden05 +bmw320d +faithless +alexandr +natalie01 +01234560 +18101982 +rui100 +123fuckyou +cavalli +22061994 +jeremiah29 +fremont1 +noonie +freddy +soccerboy1 +290484 +sebastian7 +genesis12 +161987 +parking +ilikegirls +fietsbel +godrules1 +1loverboy +montreal +donegal +sample1234 +ilovepizza +06081989 +123123456456 +ibrahima +091191 +cutie17 +123456zzz +28121982 +dustin +magoo +16061982 +1602 +2486 +300184 +tabasco1 +staystrong +armonia +16071989 +260381 +neisha1 +hateu2 +novell123 +laralara +drewdrew +198121 +050285 +230294 +montague +congress +b43m6xhiee +19821983 +griffey24 +denied +paloma123 +starling +capoeira1 +ryan05 +alyssa14 +170777 +mybabe1 +mustang93 +airman +celtic7 +21071981 +gasoline +marleen +031092 +seraph +money34 +maddie13 +asshole10 +tigger00 +collier +galatasaray1905 +060289 +pooh21 +epson1 +140381 +password36 +liberation +mariner1 +danni +ammukutty +08051988 +sebring1 +kirstin +dsdsds +lilpimp +godlove1 +chevy07 +190683 +andrea18 +06051985 +ninjutsu +falcon123 +sweet09 +mausi1 +514514 +11031982 +rocko +emma2005 +30031983 +170593 +220993 +290192 +triste +26111989 +olivia22 +adrian7 +sorokina +ficelle +dwade03 +emmalee +130381 +chevy3 +blondy1 +asdasd12313d +grenada +guard1 +mamamary +oladele +mario22 +nemezida +hondacr125 +jaguar +imbored +max111 +142142 +lolipop2 +pamela +willie01 +marcus10 +fatty12 +castaway +08121992 +mithun +smiley! +020681 +09061984 +spider +twinkle2 +stratos +251251 +friend5 +manzano +071183 +finlandia +loulou2 +198907 +recon +17041984 +14081983 +brian14 +091284 +cutie1234 +dragonfly7 +natalie11 +04081984 +12051981 +121075 +hounds +bigboy6 +090592 +19051994 +10041994 +260992 +emmanuel +123qwe +654321l +footy1 +mello1 +400006 +nikki10 +210479 +091184 +shake1 +pangeran +rockers1 +kurakura +rawiswar +av8ygj1f2u +rfrfirf1 +miguel14 +iloveboys2 +india1234 +drum +1travis +21312131 +claudia2 +trill1 +260781 +lkjhg +peanuts5 +autumn123 +four4444 +killa7 +07101984 +vbhjyjdf +30051982 +199118 +abdul1 +saskia1 +dragstar +111969 +07061986 +prashanth +10041993 +magnum44 +mim +fire666 +210980 +jonathan15 +123700 +123sss +monkey100 +10021995 +kiki10 +231194 +emachine1 +brooke22 +guineapig +071090 +scholes +soltero +ramramram +25121993 +111194 +fairmont +190185 +mimi14 +lithuania +p12345678 +198019 +++++++++++++++ +riley01 +bassist1 +dakota08 +reflection +3500sucks +operator1 +bluedevil1 +tktyf +050983 +02091980 +tekiero1 +jeanmarie +090683 +password72 +abbie123 +love79 +020882 +25051980 +060590 +jesus007 +harley1 +titi123 +hh123456 +stetson1 +burgundy +creative123 +gangsta14 +apokalipsa +faiths +claudia +hoover6 +greenbean1 +1realnigga +euro2012 +ghostface +0405 +malone1 +sharon01 +diva13 +valparaiso +cute1234 +25041993 +whopper1 +godislove +231195 +12031994 +magnat +07111984 +130380 +mustang87 +raven666 +050984 +24031981 +home11 +19851010 +420bud +19041992 +makeme +green20 +london13 +080492 +090485 +connor3 +hottie911 +pisang +princesa12 +cigar +gembird +07061989 +10141014 +brenda01 +franchesca +anu123 +18021994 +shadow92 +130493 +stanton1 +kool11 +nena15 +redeye1 +shepard +renee3 +newyork9 +da123456 +horsey1 +harlan +will1234 +abcdefg7 +direngrey +251177 +asdfghjklzxcvbnm +sexyme2 +cuba123 +tamuna +backspace2 +haleluya +katya1 +14061982 +carlo123 +11041994 +chopchop +19041993 +021280 +newspaper1 +21051983 +sexylady2 +macbeth1 +ilovejeff1 +mandy2 +eatme123 +biarritz +ronny1 +116688 +18011986 +lollipop7 +schule1 +08011987 +ostrich +abhilash +15071993 +girassol +280580 +25021982 +adeyinka +2223 +maquina +iloveanime +290481 +qaz123wsx456 +iloveyou1 +tyler04 +123123as +sektor +pascaline +johny1 +357 +shannon5 +love37 +natanata +8899 +03121984 +serial +watcher +adidas +14121994 +lalakers24 +shorty24 +jonathan6 +040286 +finland1 +william15 +ilovejustin +chanelle1 +muhamad +amanda99 +benjamin01 +ciccio1 +jason15 +cindy2 +fanta123 +trailer1 +strongman +talon +houston13 +echo123 +030286 +shilpi +newfie +casper10 +linares +15121512 +14071993 +061083 +23071983 +swords1 +shodan +cjkysirj +270494 +vfhnby +tennis22 +dustin01 +211277 +maint +291281 +sexisgood1 +allycat1 +roksana +newmoney +anna12345 +07101988 +wwwwww +julia11 +luntik +costel +5225 +thegame123 +3friends +081092 +honda94 +aaaa0000 +marcus5 +orlando7 +salesman +147258369q +iloveme14 +26021984 +qwerty27 +juicey1 +freedom22 +031083 +scorpio8 +puzzle1 +luckylady +kenton +mynumber1 +innocence +pimper1 +dancer07 +29121981 +dancer15 +dragon777 +280785 +stup1d +deer123 +nitin +021985 +21031994 +bonnie11 +arabian +interpol1 +aaaaaa7 +07051989 +horus +bayley +08071991 +booger! +230879 +apple101 +lklklk +iloveluke +eagleeye +antonio9 +19041983 +sulochana +160681 +max2008 +stephanie +amor1234 +london1 +asdasd +mantas +redred123 +ashton2 +101197 +130578 +122009 +adrian22 +ukflbfnjh12345 +golosa69 +070284 +elenberg +040480 +25051981 +cutie18 +rasmus1 +rahayu +gattone +jonathan22 +sophie07 +bear21 +jadejade +vineet +cavite +everafter +slawek +005500 +dragon90 +itsme2 +compras +pinky11 +30111984 +eduardo13 +08091984 +monaro +momoko +09011985 +anna1986 +qazwsx +chocolate1 +christos +pot +savannah7 +180492 +slideshow +753dfx +021987 +fuckme7 +24011988 +were +dakota06 +110895 +douglas +cloudstrife +evicka +valladolid +file +31081984 +we +yahoo23 +austria1 +08041992 +centauro +stink1 +210194 +260481 +lollol11 +naz123 +11081993 +sommer +531531 +isabel +get2work +jose20 +181987 +turtle69 +pepsi101 +051181 +250394 +billys +solsol +fallen2 +friends14 +squire +831011 +hotstuff! +28zxrpvnfa +240391 +killer19 +camel123 +mujahid +140193 +vanity1 +ice-cream +julio13 +opera1 +19121994 +210495 +30111991 +steven8 +031082 +lisa22 +10061982 +30011983 +bul +159987 +shit666 +53535353 +11041104 +jesuslove1 +corpse +pa22word +:tytxrf +11111993 +221278 +majesty1 +198628 +formel1 +orbit +travis! +mati +fuck00 +dante666 +tickle1 +ilovelisa +irving1 +091183 +nigga. +richard69 +abdelkader +03061983 +nikusha +sec +060587 +tink22 +191281 +tacotaco +031280 +boarder1 +22031994 +supermann +220678 +200600 +aerospace +aissatou +fratello +popapopa +mortal1 +hilda1 +mylink +abc124 +400028 +chris28 +ewelina1 +topmodel +198716 +06031984 +dumbass! +17021994 +abcdefghijkl +xiaolong +farts +stress1 +loveyou14 +thomas77 +1freak +14091993 +060191 +sandor +saratoga1 +ryan99 +alberto12 +199700 +#1babygirl +thestrokes +pomona909 +aj123456 +scorpio13 +gethigh +su224466 +1806 +us7860loans +bently1 +hippy1 +kubota +060986 +faggot. +food11 +gentry +#1player +miketyson +rajaram +130594 +tippmann +tommygun +manish123 +tigger27 +witches +beast23 +123456s +12051995 +ozzy12 +noriko +dudette +shante +kamkam +babygril1 +investor +fifa06 +hunting2 +mexico +291080 +nirvana. +walter34 +21081983 +racers +tweety24 +24111982 +050682 +boss429 +torque +jessica0 +2flowers +080882 +caca11 +twins12 +070388 +yessenia +pink02 +24031983 +30121983 +rangers2 +jazzy15 +jaeger +neverguess +190782 +070587 +danny4 +minnie +pantyhose1 +25061983 +doroga +bubbles1 +schooner +skate1234 +wipeout +111093 +tamayo +brandi2 +ratbag +coolwater +chris4ever +050286 +aceace1 +190183 +caroline +11eleven +jack14 +sum41 +penguin13 +rice +04061989 +1580 +forever6 +adam10 +novasenha +420666 +06101992 +lgkp500 +a147852 +arthur12 +20032004 +16011984 +orville +david26 +30051983 +160581 +sasha_007 +fucku23 +saranghe +pimpin420 +olugbenga +753951a +buckingham +2603 +silvermoon +jessie22 +klop +tranmere +110087 +janell +grillz1 +alvina +211093 +wayne23 +30101980 +bayonne +091084 +asdfghjkl +familyof6 +heather23 +221193 +saqartvelo +v647947 +27111992 +oceanside +080386 +260192 +armagedon1 +danielle +snakeman +13021982 +kenny7 +izzy12 +shuffle1 +master2006 +1arsenal +22121980 +grandprix1 +cosette +vista1 +031292 +gulshan +456456a +chang +teste +summer55 +cleveland2 +dfkmrbhbz +darkblue +back +second2 +blackwhite +zoubida +shiznit1 +090993 +lover4life +vik +buckmaster +honor1 +270882 +pops +sana +dima1990 +faith22 +jojo07 +palito +14071983 +kenyatta +hitech +armaan +uzumaki1 +gallardo1 +latinking1 +nikprommet +kibbles1 +michael101 +crispin +020581 +denver303 +asdfghjkl4 +070591 +17101994 +adrian5 +lingerie +delia1 +kayla23 +jump123 +cnthdjxrf +vascodagama +buburuza +150183 +monica69 +jandi +darkone +vfr750 +iloveyou96 +timothy12 +aidan123 +10091993 +81726354 +123poop +02021977 +9696 +kekeke +matematicas +fallen12 +myspace78 +tr1n1ty +bigboy01 +fresas +euro2008 +15011982 +rabbit69 +203203 +15421542 +multan +luna11 +060491 +26041984 +05011985 +tweeling +12021994 +cupid1 +nash +171991 +edward1901 +07041991 +florecita +193728 +ilovemen +sickboy +scratchy +nasty123 +04021989 +glock9 +06061982 +300792 +08121990 +munch1 +333555777 +071182 +31051983 +bean123 +calling +15041982 +080308 +13651365 +america4 +doubled1 +26011984 +060190 +474849 +abiodun1 +05071992 +q12345q +august88 +happy15 +hello44 +2808 +neogeo +120993 +poopoopoo +shower1 +butts +ninjasaga +06031991 +16101983 +geneve +tylerjames +shadrach +26051983 +lovely24 +sarah6 +01081982 +zxcvbnm1234567 +graceland1 +lebedev +05081983 +snooks +kangta +macdre +courtney10 +198509 +maneater +tomodachi +13121993 +bleeding +moritz +cherry9 +twist +venom123 +steve69 +salome1 +123angel +inlove08 +pheobe +emo1234 +25121981 +supercat +munchy +416416 +tunde12345 +020393 +laguna2 +030683 +13071982 +290382 +grandma6 +mossimo +180183 +198609 +140593 +sabino +speedster +gumption +hemicuda +citizen1 +kurapika +qwe123456789 +bloodmoney +kiana +linda01 +1234589 +19011984 +gardner1 +6dnwch275049 +charisma1 +130793 +aqwaqw +211278 +15241524 +think123 +170184 +loveing +beyonce123 +giant +248655 +29061992 +numerouno +fable2 +honda100 +youngman +weg63tt243 +elvis12 +180579 +west1234 +toulon +tosser +shithole +whitesnake +viktoria +breezer +tomiwa +lorena123 +superstar4 +030187 +animals123 +110478 +zaq123edc +13121994 +07031988 +gkfytnf +tucker22 +120177 +jacob23 +061085 +gopinath +blessing12 +011083 +angel4life +24081985 +splintercell +cassia +hershey +karina2 +transalp +tony24 +tigger1234 +yfcnfcmz +krystle1 +bambam3 +config +220280 +jordan27 +ani123 +010284 +mascha +12332145 +05121983 +correo +thuglife7 +amorosa +lulu13 +killer33 +01111985 +100777 +david2008 +246812 +indeed +iamalone +lollies1 +controle +bonobo +050184 +sixflags +racine +canada +199413 +anthony27 +86868686 +28021995 +301194 +rollin20 +cutie45 +harry6 +dominik123 +candygurl1 +jesus4u +11031981 +akshaya +motoguzzi +potatoe1 +success12 +quack1 +231077 +happy25 +04121988 +modernwarf +bossbitch1 +96385274 +210393 +patrick69 +jovita +sketch +buddy +ishita +070586 +dabaddest1 +heather16 +010983 +boggie +mrniceguy +coco21 +twins02 +pumas123 +kenguru +01111991 +040187 +sumathi +befree +tea +lonelygirl +scholar +kaushal +aztec1 +951753a +270981 +mama15 +evamaria +farley1 +bootie1 +carmen11 +schiller +19041994 +23121981 +torsten +harshit +mysore +04111987 +02081980 +spectra +miguel7 +jason8 +12345tt +baybee +shakeel +eldorado1 +money666 +4568520 +140793 +my4sons +dominic3 +waheed +elephant3 +sabrina11 +wanshuai198202 +03091992 +lola22 +mika123 +gabby11 +tommygirl +chrome1 +venecia +041284 +07101989 +rowland +crafty1 +03121992 +12345688 +20111982 +102000 +carver1 +jennifer20 +20091993 +qpalzm1 +batman07 +devonte +300984 +alright1 +yankee12 +face123 +vimala +august05 +icebaby +ubvyfpbz +longisland +21061982 +bautista1 +disaster1 +04081991 +290681 +jack03 +jayjay3 +1927 +jackdog1 +310580 +misiu +happy2010 +peace09 +asdfasdf123 +010491 +dontcare1 +flopsy +stonewall1 +16101993 +27041983 +honda06 +23031981 +2804 +wentworth1 +tombrady +hugo12 +hobo +complete1 +feathers1 +310595 +130280 +stoopid +lilmike +lover17 +cygnus +edward15 +1qaz2ws +pa33word +crystal! +120202 +kel +joey101 +orange17 +pioneers +dortmund1 +warrior123 +emma08 +drama101 +fucklove3 +boyfriend2 +09071984 +impulse1 +carlos9 +maxi123 +london23 +06011991 +030481 +30041983 +051081 +aaliyah123 +iamwhatiam +looploop +210395 +la1234 +070387 +jochen +slipknot0 +1234rt +230894 +scamp1 +puppy13 +kikka +170480 +22091993 +jesusgod +lauren07 +101977 +12101980 +bendover +pikachu12 +amelie1 +jaimito +josh19 +bijou +katara +human +southside7 +stupid13 +11291129 +04101992 +fede +lovekills +miroku +1courtney +20112012 +alskeo +breanne1 +noemi1 +alicia11 +07121988 +ecapsym1 +asmita +midnight1 +500013 +230594 +11051981 +198604 +23061983 +mickie1 +summer01 +bettie +040582 +benelli +andrzej1 +maxdog1 +05011984 +purple06 +samsung10 +iloveamber +280784 +ryu750103 +1united +8765432 +patrick17 +hfpdjl +2904 +071092 +joseph24 +120708 +fucker666 +renee13 +sandstorm +sayang88 +bhakti +28041993 +gitarre +may1995 +19081993 +libido +251293 +0811 +basic1 +201178 +illidan +64646464 +miaumiau +tekken6 +04111986 +191092 +fizzle +lasalle1 +jazz1234 +maikel +08091983 +06081992 +wiktoria1 +123qwerty123 +197712 +19091993 +15051980 +blue100 +jojo99 +041087 +jenson +021181 +060192 +franklin2 +198703 +g76t94prm4 +25051994 +bella15 +199812 +perugia +050982 +diosmeama +hermie +chris2008 +diamond07 +rudy12 +22tt22 +19421942 +doggy69 +08101988 +quarter +vaz2101 +sid +mar +rembrandt +destiny1 +breaking +gbljhfc +161079 +dance4ever +hollywood +1daisy +juan15 +pink90 +hbw +211279 +redskins89 +09101988 +21032103 +wine +04121989 +industry +courtney5 +skater21 +180181 +1907fb +030188 +hello17 +cuenca +gtagta +28111984 +ecology +hockey08 +jackie! +devil69 +sensual +lovelife! +080879 +061082 +omarion2 +198825 +qwertyy +luvluv +makena +playa2 +muhkuh +13091993 +198823 +lorin +tarantul +hor +3011 +11071993 +mol +fatcat2 +renoir +thunder8 +bryce123 +280481 +eminem01 +shroom +charlies +22071982 +power10 +030693 +sasha1993 +iloveboobi +texas09 +laurinha +aaliyah7 +nicole97 +nirvana94 +110053 +harley6 +boogie12 +191282 +brigitte1 +6262 +07101983 +1maria +family21 +198028 +mardan +flower1234 +werder1 +160981 +mogul +140184 +09081992 +160047 +wal-mart +25111980 +06111986 +thomas03 +timeline +030783 +narasimha +121997 +maria24 +debbie01 +ashley92 +210678 +swedru +pierino +220694 +dusty2 +playa12 +rudolph1 +gardens +violon +pasaway1 +specialist +real12 +piggys +ktyf +leonessa +aaron23 +123456852 +mother. +froggy69 +mecanica +girl10 +godloveme +ilovesara1 +pumpkin5 +shawty10 +ashley87 +weird +130779 +16021993 +03051983 +katja +fishing +polikloh00000 +1husband +diegos +240783 +hottstuff1 +anna1989 +valhalla1 +jayden03 +rfn. +vonnie +www777 +070986 +bandit1200 +dummy123 +13101981 +alyssa22 +100779 +311081 +120496 +slunce +2121212121 +aaron21 +060792 +ballin14 +12031982 +purnima +holy +breana +bananas12 +sembilan +ginny +jack15 +dreams123 +150879 +emma10 +ashton12 +winner01 +dauren +jackson09 +ruby11 +1qazqaz +ou8125150 +02121983 +chloe13 +13221322 +jakub1 +azerty31 +081290 +smile10 +0103 +ghbdtn12 +122448 +jack06 +myspace420 +operations +chivas99 +06051990 +nicole30 +198709 +smoochie +230579 +coolio2 +maria69 +corpus +241984 +diva01 +michel +greenlight +qwertyuiop123456789 +28041985 +08031984 +stepup2 +24111981 +14031972 +brianna6 +1silver +justdance +frog1234 +151093 +apples7 +cunt666 +kol +fagget +ilovehim4 +sevendust +sammy15 +noregrets +zamira +candy08 +denisdenis +9yqss2h9ub +melody123 +charlize +slipknot +01071980 +18071983 +rosella +oksanka +2boys1girl +pluto123 +2pac4ever +mambo +banana +150991 +caonima123 +cronin +redblue1 +chileno +1chrisbrow +diego2 +lyrical1 +nokia6700 +verdes +05031984 +01021995 +bipolar1 +30081983 +20061981 +kanyewest1 +aida +freedom06 +arnel +2236 +29121993 +monika12 +matrix7 +04041980 +100593 +flyfishing +ferrari430 +dinero1 +america14 +ashtray1 +centro +08101985 +rintintin +198999 +writing +09071985 +barbie101 +040680 +n0vember +b1x7qn2tug +rocker2 +stephie1 +090389 +21222324 +born2run +tony07 +qaz2wsx +babygirl34 +29051993 +fuckit3 +16121994 +iluvher1 +251178 +colorguard +calinou +25172517 +24051983 +citation +444444a +victor22 +soulman +abeille +raymond12 +stussy +230793 +dubai123 +infected +twilight21 +simpsons +87654321q. +190292 +broodwar +09031990 +cleocleo +me123 +smile. +cobra2 +05071982 +270593 +07091984 +23111993 +030581 +handball +playboy101 +funky123 +crystal21 +imation1 +200494 +281181 +05051978 +dreamteam1 +meiyoumima +bobthebuilder +09051991 +lindros +honda21 +121207 +181990 +18111993 +19051981 +190289 +150493 +18041982 +121196 +juno +guapo +yamaha +ireland1 +halloween3 +sinterklaas +smiley01 +30061981 +jayjay7 +xena +motmot +manu1234 +09101984 +code123 +pheasant +abdoul +12111993 +september11 +brewers +london5 +angela3 +stevevai +2234562 +warehouse1 +hiya +laser123 +ama123 +babyface2 +jordan26 +010282 +vfrfhjd +sarah4 +hotdog! +bubba14 +101000 +jennylyn +09061991 +1917 +mariette +21111992 +women1 +mozart +05031986 +buddy123 +88mustang +197919 +050487 +19833891 +pretty16 +princess101 +plasma1 +nascar14 +02468 +spike01 +lisalisa1 +marti +marina01 +italy123 +boston01 +johncena3 +butkus +199410 +l0nd0n +cooley +456rty +franta +agent007 +newyork08 +gfgf +bandit5 +katrine +11101982 +595490067ua1 +pipeline1 +geniusnet +gator123 +starscream +sasquatch1 +chilidog +2806 +nigger666 +cyjdsvujljv +300693 +assa +nyquist +timoxa +dodge01 +treacle1 +tennis! +antiflag +160993 +exploited +gbljhfcs +buffet +ranking21 +steele1 +nabeel +envision1 +pantalon +pferde +122133 +honeybaby +brooklyn23 +starwars4 +martijn +cody15 +2704 +180384 +sammer +herobrine +only4you +411052 +kettle +francky +as123456789 +200677 +100594 +simbas +carly123 +199215 +arsenal9 +gfnhbr +mikee +railway +181991 +joey10 +sonu123 +deathangel +23242324 +14101981 +bantam +170680 +110378 +kennedy2 +16081992 +nokia +jessie21 +maegan +slankers +03021991 +600091 +560005 +penis3 +vianney +15011993 +0321 +1357910 +masterone +060187 +halo03 +241177 +asdqwezxc +196868 +pirates2 +sexxy6 +06011990 +250779 +leonardo +riptide +230693 +sexy2010 +17051982 +petrik +blonda +godlike1 +171985 +w45bj9upkz +may2009 +lolalola1 +asshole666 +wyvern +chopsuey +kiffen +love001 +ilovekim1 +pakistan123 +37gudoplfs45 +retard2 +search123 +maxwell3 +12332 +vedant +vince123 +04091992 +ilovebeer +newcar +10031980 +tight1 +liberty7 +060292 +30031982 +gangsta69 +martha +graywolf +ballin15 +23051994 +26101982 +adriana2 +playboys +020682 +20012002 +wobuzhidao +280392 +030983 +pinoy +1234789 +cajun1 +lilsis +salgado +170381 +181988 +22061981 +kelly22 +270180 +051282 +batman17 +richard23 +buster101 +playas +11021981 +nitrogen +101976 +heavens +lh6rjx44qb +1580welcamino +mnbvc +honda07 +lacrosse22 +theman11 +baby002 +vovan +yoyoyo12 +duster1 +burton13 +michelle06 +14121981 +mamichula1 +trace1 +boozer1 +yeehaw +biteme01 +115511 +borussia +bacardi151 +10051994 +baldur +310782 +19051980 +kieron +sexygurl12 +pookie! +chupachups +danielle15 +squirtle +condor1 +lovinlife +bandera +291192 +brick +rhbcnbyf +kimball +17021993 +198119 +260880 +scooby23 +26111983 +super4 +porky +honey18 +holstein +р»сћр±рѕрісњ +221983 +mathematic +john20 +johncena9 +davidlee +strangle +oladapo +sunny11 +steelers08 +cheyenne3 +storage +faker +babyjay1 +dinamit +170291 +julian10 +abcabc123 +slut101 +963147 +trixie +christine7 +29091983 +kitty07 +17081983 +sicily +chocha +mustanggt1 +110978 +mirasol +nina01 +wallis +princess31 +www.com +03051982 +05041983 +goethe +custer +robert0 +faith09 +pandemonium +gembel +pinto1 +basket123 +fire69 +peter01 +galaktika +canuck +kawasaki12 +123456286 +hondacr250 +05101992 +crunchy +18111984 +070984 +qebefcz3yx +sheryl1 +single22 +saiful +britt13 +190884 +stayfly1 +asdzxc12 +220281 +suesue +198407 +nurse123 +star66 +fade2black +12345678qw +01121983 +janaina +broken13 +oblivion +ilovehim11 +110037 +minstrel +mineral +run4life +waterfalls +password76 +madhatter1 +walter2 +27011993 +1122334455667788 +resource +zachary01 +benjamin11 +102030405060708090 +love81 +romantico +handy1 +081183 +austine +kairos +11051979 +braydon1 +buttons +olushola +dickie1 +160182 +vampyre +yahoo9 +piolin1 +221010 +squeaker +str8edge +ronald123 +emocore +kingtut1 +warzone +senior11 +070884 +1192 +vball12 +whatsup2 +28031983 +2288 +170880 +peaches13 +700016 +aa123321 +monica3 +techdeck1 +190184 +damsel +nemtudom +chicken1 +03111983 +jennings1 +04031993 +gotham +regina123 +stavros +12991299 +adam69 +filipino1 +jeepcj7 +consult +080987 +lalala99 +3101 +marina2 +wkgmkjh623 +vaz21093 +040692 +shereen +tmobile +lollipop123 +010907 +jordana +victoria8 +alex86 +woaiwoziji +bobby18 +iglesias +minute +13111982 +funeral1 +freedom21 +joseph17 +31051994 +portis26 +polisi +231294 +226226 +290583 +200281 +beef +mana +kevin06 +amalia1 +shangrila +bigpapi34 +22091994 +casey01 +06041984 +031281 +20031982 +hunter. +doomed +kaykay2 +nightrider +aw96b6 +kisha1 +ame +borisova +1gateway +26061980 +f76t93nqk3 +mexico6 +antonella1 +graceful +beretta1 +angela10 +matysek +networks +barrister +061092 +youare +121076 +lakeshore +03071983 +barbie23 +150180 +ganapathy +rfnz123 +coupon1 +pedrosa +rusty01 +hamid +kiska123 +poiupoiu +buzzbuzz +198617 +king05 +195555 +080288 +16061993 +19091982 +060883 +03121989 +cold +hearts3 +t666666 +kimberly +poseidon1 +14121980 +symbol +ballers +12051980 +lollol2 +chapin +09021985 +fuck18 +burberry1 +ceaser1 +bob666 +147001 +123321asd +maeteamo +081284 +110076 +connexion +convict1 +lemondrop +010581 +steinbock +08061985 +pretty22 +20121980 +sh123456 +allison +271281 +28071992 +spank +20041980 +hangman +12171217 +marianela +010682 +d11111 +10121979 +125634 +sammy16 +bill1234 +people4 +16101982 +180192 +drumer +040881 +bite +doctorwho1 +saidov12345 +5555551 +monica22 +100477 +thisismine +zigazaga +17021983 +logan7 +mexico19 +malini +200481 +161193 +wangyang +09091993 +pepper88 +creampie +juan01 +snowman123 +dove +ablegod +sugar5 +0205 +weddings +29071983 +aria +tiger25 +oreoluwa +balrog +rutherford +08121985 +rockies1 +edwige +pucca +hopehope +24061993 +scooby21 +rebecca11 +31031993 +500035 +sweets123 +311293 +10071980 +please! +jesus69 +you&me +yogyakarta +joanna123 +wonderwoma +03021982 +matthew25 +teddybear5 +gayness1 +starboy +shortstop1 +sweet +31011983 +lifeislife +laddie1 +gemini7 +ghjcnjrdfibyj +xt: +doodle2 +amor14 +stryker1 +08061991 +101974 +theodor +june1988 +20041994 +10121996 +060385 +05041992 +198404 +141293 +liaisons +04091985 +nana15 +180581 +approved +17091983 +pindakaas +05091983 +25061993 +alohamora +homebase +michael29 +anewlife +196300 +lover07 +09011989 +bonfire +198808 +stanislas +lovee +240780 +momma3 +tom1234 +stephanie5 +devotion +lokomotiva +sonrisa +warner1 +tonton1 +ataman +dimas +puppy6 +1478965 +clooney +1snowball +sallydog +poohbear09 +sceptre +03081983 +ilovedance +522522 +nooneknows +gloria12 +megaman123 +22091982 +pascal +dead12 +121412 +29101993 +dollarking5 +master14 +auguste +1314159 +edu +south123 +dignity +04011992 +250893 +kunkle70 +260780 +dixie01 +rangers12 +sisters4 +bebe10 +garena +pippa1 +trixie123 +lar +09091981 +savatage +abhilasha +nokia1234 +290792 +31051993 +hanter +rosiedog +sexyness +snowbunny +razorback1 +04051981 +bree06 +261986 +03011984 +joselin +530530 +nikiniki +gingerbread +robot123 +fleetwood1 +answer3 +nani17 +drummer123 +kingfish11 +shithead! +maritime +fordman1 +harry +blackgirl1 +sweetheart1 +ahmedabad +06041992 +190682 +chance13 +987654321b +yondaime +p@ssword1 +praxis +convict +edward69 +morgan15 +dillon12 +puddle +anna1984 +garrett +janjan1 +badboy +ashlie1 +monkey91 +cardinals2 +grandkids2 +mets86 +081285 +bloom1 +dillon123 +sweetpea3 +31123112 +dragon86 +poohbear16 +09041989 +baby34 +120196 +patrick. +cabrera1 +gingging +amidala +050579 +silver88 +110677 +12345rewq +01121984 +chika +keluarga +romantik +gonefishing +oasis123 +neruda +201307 +hurricane2 +198126 +alex +time4me +210282 +tink23 +caleb12 +160980 +28111983 +sextoy +betrayed +061091 +jessie +09071992 +777aaa +booboo8 +200777 + +heather +llama123 +02021976 +utahjazz +sdfghj +applejack +andros +holidays1 +fffff1 +azerty0 +250575 +skye +melville +bunny101 +sex4life +toenail +antonio21 +blooming +trinity06 +197999 +180381 +17061984 +148148 +010380 +firefire1 +spinach +pedagogia +harley8 +14101980 +pumpkins1 +199213 +11031980 +godspeed1 +mamere +02111986 +deerhunt1 +cantona1 +1texas +coolman2 +danielle1 +disney +sexymamma1 +nightfall +197312 +021081 +beast2 +nargiza +290883 +faraway +161180 +love47 +domino12 +h0ckey +yummy2 +gordo13 +razor123 +271178 +ishola +naruto89 +dreamer123 +666444 +120178 +gangster3 +11091982 +league +250577 +maria4 +toyota01 +jordan2323 +july2008 +kevin9 +30011984 +bambi123 +04081983 +smoker420 +doodle12 +hateme2 +fhifdby +mangalore +maddie +easyspiro +123434 +anika +james89 +jazz11 +221195 +love46 +macleod +samuel3 +linkmein +lala15 +smartie1 +louise22 +stanley +travis7 +03121983 +010880 +jerome2 +1penny +single23 +galloway +310581 +reyhan +280491 +14061993 +honeylove +kari +13601360 +sakura2 +kocham1 +kasparov +270291 +jones2 +glider +280193 +081291 +120778 +3001 +isuck1 +141278 +080289 +21071993 +practice +vita +nevaeh2 +pescara +plastics +17121980 +mikela +blue03 +23041996 +messier11 +materazzi +sunshine27 +connor07 +pilou +milaya +metallica +23041980 +071986 +partizan1 +sublime2 +tony09 +financial +african1 +220495 +050488 +060387 +emma06 +01021994 +mikasa +golfer01 +bullshit12 +baldrick +19061993 +robbins +kingdomhea +harry3 +thunders +mexicali +jonas2 +8787 +198201 +ivory1 +cronic1 +enfield +manali +ledesma +brad12 +259421 +calavera +rebecca01 +manwhore1 +p@55w0rd +gingersnap +elnegro +200578 +riorio +rockbottom +monette +lemonhead1 +assaassa +qavcx411 +14061995 +natalia2 +february19 +oneblood +outlawz1 +boston23 +230979 +dayday12 +270492 +270692 +197346825 +tink15 +nana09 +sports7 +shantanu +131277 +vfvihss591 +killer95 +summer78 +170681 +jojo69 +120277 +animation1 +qwerty123456 +030185 +gina12 +2703 +17101981 +iloveash1 +katalin +gasper +seesaw +29041994 +thesexy1 +paintball7 +elsie +eagle7 +il0veme +relentless +beaubeau +kreator +seniors +linda13 +636322 +june1990 +ufkfrnbrf +sasikala +251095 +ghfplybr +delta9 +daidai +mayflower1 +absolut1 +evgeny +onfire +040183 +tatum1 +white12 +cassandre +parents1 +28091993 +somerset1 +1122qqww +spam123 +1010220 +rjyjgkz +hunter33 +israel123 +linked11 +chapel +sansone +gr +sugar7 +rocafella +210694 +peugeot306 +13201320 +08121988 +30091983 +momma123 +tiffany1 +11111d +baller09 +patrick16 +swanson +sharon2 +12343412 +dardar +061292 +198409 +fridge +chelsea69 +angel85 +natalka1 +hartman +16021983 +tyler17 +flame123 +thurston +may1987 +woodson +andrea08 +03111989 +14071981 +050681 +ellen123 +pepper09 +templar1 +muhamed +230779 +dolfin +29091993 +seawolf +may1989 +nikki09 +chomper +aeiouy +easy12 +murthy +samuel22 +locked1 +01111989 +problem1 +cameron +dalton12 +riddler +jane12 +sdf +10071982 +aaron15 +23031994 +020483 +qazwsx741 +281081 +olympia1 +nana08 +mahalaxmi +chicka +coca +windows12 +hatchet +pizza23 +030784 +14011983 +tweeter +11021980 +faith4 +surprise1 +swing +171279 +kickass2 +honda450r +beto +pak123 +hussain1 +claire12 +highway61 +muscat +dolphin4 +natalie13 +198302 +itunes1 +quilts +100778 +1angela +mb1234 +andrew33 +seanpaul1 +dakota05 +16091989 +fast123 +kiki23 +privado +31121993 +130993 +savina +02121980 +cubano1 +spot123 +sabine +kalhonaho +1corvette +happyme1 +pegase +whatever0 +orione +vol +28081983 +198726 +pilots +nanayaw +steven08 +eric69 +11111m +singsing +sanmartin +nokia11 +termite1 +joemar +bitchplease +weed23 +buttman +apple25 +smiley11 +harley23 +tiffany21 +041987 +blue72 +100300 +thuglife13 +21021994 +070686 +backoff +bisola +powerrangers +omotola +090885 +dragon91 +050709 +198901 +thewho1 +17071993 +09081987 +cobalt1 +negra +suns13 +djkrjlfd +bariloche +jeepers1 +140579 +tissue +fender11 +spiderman12 +hannah24 +04061981 +123456ww +vfnhtirf +blackwell +looper +pollita +squid1 +already1 +bellota +challenge1 +analuiza +staff123 +121206 +faulkner +gears1 +milk12 +polosport +skate22 +delta5 +tattoos1 +sexygirl3 +cartoons1 +mike143 +kurama1 +oioioi0 +199210 +24021984 +booman +seabee +0220 +nestle1 +bigal1 +tuxedo1 +speckles +24111983 +morningstar +aaron14 +hounddog1 +folder +bobina +broncos2 +wwjd +elpapi +adidas22 +chu +camille +lle1234 +ijfrnhf7yhcy54bhy0cd +sandiego61 +twentytwo +july03 +rfkmrekznjh +shutdown +modest +kuba12 +killer20 +iloveu08 +swastika +11071981 +nicholas22 +monkey67 +11061982 +irocz28 +paranormal +payaso1 +bluegreen1 +heydude1 +booper +240993 +nano +babyboy9 +aaaaaaaaaaaaaaa +23021982 +colores +addiction +engel1 +manu12 +hans123 +270779 +millers +23101982 +150994 +170581 +240382 +cthlwt +sarah18 +monkey29 +owen123 +number1fan +mau +16071983 +mango12 +07121983 +smilesmile +frannie +24081993 +030186 +141989 +56chevy +sometimes1 +king18 +onelife +241985 +johngalt +jennifer15 +05091992 +dakota! +afireinside +fucking2 +23031982 +07111986 +260293 +1807 +nivedita +dagreat1 +montana12 +rosedale +demon2 +mexican3 +yazmin1 +sandy3 +ilovedick +100278 +james26 +cool45 +adamson +herbal +dominos +withgod +magician1 +ryan2008 +bill89 +aaliyah12 +sloppy +chester +flutterby +linda10 +barron1 +stevo1 +150379 +231989 +superstar6 +pookie22 +banker1 +122007 +angels27 +cntgfirf +100378 +jolanta +reset +d654321 +myspace? +rachel5 +tosin1 +10102000 +gayassfagpastebinleaks +mostar +cfvehfq +12071207 +yeahbaby1 +123poi +chris95 +asher1 +shubhangi +240281 +qazwsxqazwsx +chris +01041981 +dezember +1qa1qa +omega2 +rac +schalke +nigga14 +harley14 +cocoa2 +200182 +alyssa03 +25091983 +sveta1 +07011985 +090692 +crip +jobs123 +03091989 +181094 +lily1234 +190580 +d-block +uthvfy +13101995 +220181 +redeemed1 +120476 +06021985 +willian +jude +ybrbnbyf +quepasa +falcon2 +cutie24 +010693 +daniel90 +121209 +puebla +zephyr1 +210696 +dtlmvf +justin26 +cris12 +03091983 +afterlife +michaela +266469 +johnny99 +elvina +yummy! +fatcat123 +06061981 +salsero +eagles! +xthtgfirf +property1 +kitty09 +222333444 +katie6 +chevy08 +22051980 +04071982 +100979 +w1956a +honda08 +anu +malakai +abpbrf +0809 +yankee23 +19051982 +18031983 +tiger18 +1177 +22041981 +15031995 +kacperek +070285 +ronin +16121993 +monica7 +juice123 +kaboom1 +jameel +cute101 +141985 +barbara +99mustang +submission +17081986 +210879 +thomas33 +darren123 +angel2005 +pink12345 +395009 +290791 +links234 +jujubee +sara22 +300791 +egoist +dodo12 +08081994 +cinema1 +winter77 +billgeitslox +pic +maggiemae1 +cookies13 +hindustani +140140 +assistant +literatura +avengedsev +tt1234 +99bottles +07031984 +evertonfc1 +october +abbigail +kevin8 +soviet +030582 +jihoo +gibsonsg1 +12031995 +tata1234 +minnie13 +270581 +25111982 +251277 +mimi10 +bibby10 +14071982 +121972 +nigger6 +09011988 +260494 +pod-fif +wrxsti +needle +220695 +matches +hunter1 +dragoste123 +sunshine00 +love75 +380054 +05111990 +warcraft +230279 +bandana +ferdinand1 +kdwcnpa362 +031183 +20052007 +willow +fuckme5 +barbarella +hai123 +4242564 +maimuta +12345ty +061281 +29061983 +666222 +242628 +disney365 +abelardo +limited2 +maryjane12 +ryleigh1 +mercedes1 +ttttt1 +110023 +run +bicicletta +alyssa05 +myname12 +123489 +sara01 +081192 +wizard12 +emily15 +maryjane7 +dylan06 +070584 +hummer12 +pridurok +1941-1945 +14091983 +070983 +09021991 +malik12 +masmas +240283 +04071983 +mubarak +28091983 +bitchpleas +sabrina3 +kakashi123 +union +050292 +stacey123 +richard8 +170579 +fener +11041995 +bowie +m1ckey +008800 +sruthi +tutu +baywatch +punk4life +haveaniceday +160693 +bignose +1benjamin +andrew98 +hunter45 +240479 +08041991 +dances +awesome13 +donkey69 +peewee13 +admin123456 +chelsea16 +thirty +gun123 +booger3 +march09 +070490 +310394 +140279 +twins22 +23101995 +carlee +mickey9 +moondog1 +nicholas! +1tigers +0852 +20011995 +10081981 +chef +amor69 +145 +alpha06 +25012501 +19841020 +bailey02 +killme123 +iloveme21 +venom666 +aslan1 +finley1 +200379 +jose19 +lalo13 +eduardo +1twothree +jacob05 +superboy1 +.: +pimpin10 +200479 +orlando3 +wilson01 +docteur +sandie1 +nad +monoxide17 +090889 +14111992 +joshie1 +koikoi +whitewolf1 +garion +master17 +stoned420 +020187 +080685 +snoops +bugsbunny2 +manutd01 +010808 +23562356 +william17 +chippie +gracie07 +ljhjuf +daisy101 +babynames +appleton +yaseen +vanshika +pussy14 +jose69 +ranger22 +hello07 +kayode1 +jack05 +sexbomb1 +198518 +diana11 +keith12 +sandys +brandon20 +26031983 +therapist +bismillah +goldengirl +blahh1 +xfqybr +upgrade +3155530 +jacob8 +06121984 +bingo2 +sum +21011994 +020883 +040285 +05061993 +15081981 +allahswt +edgar12 +21041981 +01081981 +kissme22 +dylan14 +22091981 +123ewqasd +monstr +severino +maria08 +bitchface +qnxe66l7or +747400 +delete123 +castrol +pineapples +nicol3 +buffer +elmo14 +01121980 +nikki15 +reaction +thinkbig +060678 +wanita +benny2 +18121980 +290183 +110493 +02021978 +w12345678 +26081982 +heather8 +cyberonline +thisisit1 +taxi +whitney2 +301292 +040681 +0258 +041182 +gracee +bartek123 +cutiepie01 +castelo +180981 +lars +18051982 +2905 +iloverock +number25 +110877 +willie3 +tamara123 +fastcars1 +animator +pretty08 +130678 +bear14 +23051993 +stormie +789456123m +15091993 +john77 +maria8 +15031980 +password@1 +040185 +18011993 +naruto00 +526526 +vieira +16121980 +020481 +carter11 +swimming2 +angel001 +gotcha2 +gangster5 +30071984 +tonka +eusebio +lovelost +aryan +141279 +eric23 +300892 +rosarosa +10071981 +farting1 +452010 +tomasko +eagles24 +agamemnon +jhoncena +chris420 +leelee123 +fucku6 +12121996 +chrisi +vitor123 +16101981 +markymark +sexpot +ohio +27011983 +calvin2 +cooper24 +cookbook +230395 +fordmondeo +password111 +christina0 +butternut +pyramide +160793 +nick99 +pimppimp1 +kwiatek1 +maggie69 +seifer +rockstar9 +cbcntvf +samsung21 +thomas00 +10661066 +081292 +charlie0 +140980 +erlinda +brittany4 +bailee1 +montessori +alcala +god4me +hesloheslo +kinglove +michael87 +16081984 +tomoko +buster1 +forgotit +dragon93 +elektrik +cassidy2 +devin11 +arowana +060286 +macintosh1 +smokey4 +pumpkin13 +310182 +251078 +qwerty098 +granada1 +130879 +fatal1ty +bugsy +rockabilly +lilgirl +corazon12 +090491 +leeanne +lovecraft +0208 +eduardo2 +danzig1 +p7678287 +chiken1 +17011701 +777555666 +1й2ц3у4к5е +saravana +26041993 +1472 +08111987 +220477 +13041983 +start123 +swarna +tallinn +030682 +300880 +20071994 +18031984 +francis +samsonite +lilmomma +ranger69 +ace101 +spartan2 +chika1 +081084 +qaz111 +dudes1 +0408 +swordfish +809 +081184 +rod +dreamcatcher +rawr11 +081191 +sapana +nick24 +petruha +smulan +07121991 +011185 +karateka +080490 +13021993 +120376 +turkey123 +michele +23121994 +02121989 +moveme +04011986 +qazwsx123 +toulouse1 +johndeere2 +chen123 +040880 +creosote +jackson! +lucy10 +albion1 +27051983 +15101981 +gaara123 +popcorn13 +number69 +070779 +dima2000 +290284 +1234126 +050693 +greatone1 +greenday. +qazsedc +saputra +shikamaru1 +jimboy123 +bitter1 +0508 +040784 +shadow12 +09021986 +zaqwerty +muscles1 +amor11 +sumatra +140480 +3005 +booby1 +bajskorv1 +grandma +10101975 +jaspreet +cum +spongebob123 +789654321 +695847 +09021992 +assinantes +transform +piligrim +04031985 +jessica89 +08011992 +admin@123 +33223322 +smack +february2 +26021993 +061293 +130293 +figure8 +boricua2 +jamel1 +basketball11 +110377 +20121993 +paul13 +extra1 +100379 +09031986 +hfrtnf +00233 +pooper2 +fender +cfymrf +24051994 +freiheit89 +030287 +050880 +whatever23 +crabtree +boots2 +top123 +290993 +fab123 +chester! +magnum357 +mike05 +vaishu +ben1234 +senegal1 +08051984 +oscar1234 +babydoll13 +juggalette +bionic +190393 +deepspace9 +cuthbert +mee +199510 +oldham +0506 +butter4 +junior1234 +19231923 +29011989 +270892 +defense1 +cheesey +180982 +wang123456 +gnocca +kalash +01061981 +isaiah3 +zse4xdr5 +dad1234 +brianna9 +catracho +sexosexo +260379 +richard4 +david2010 +hollywood9 +bruno2 +www222 +fruitloops +brittany6 +010105 +shadow05 +steven6 +1qazxsw@ +270181 +100977 +gorges +matita +propaganda +circus1 +sean01 +mylove5 +northstar1 +slider1 +cesar12 +goober123 +boby +letlet +password50 +morgan05 +simpsons12 +chris00 +vince10 +antonio01 +10011994 +alteclansing +paulin +number1 +prostreet +hotmom1 +060682 +frolov +27121980 +jahjah1 +tucson1 +985632 +050679 +enterprise1 +ankit +eszter +chivas17 +petpet +eastcoast +brittany21 +160479 +211280 +reallove1 +ediz27v1kq +dominate +260193 +sweetlady +161078 +lamination +12261226 +huahua +microsoft +zaheer +schneider1 +lilromeo +ilovehim09 +solotu +casio1 +nguyen123 +charlie101 +eindhoven +qwertyuiopasdfg +211180 +mpower +040287 +pogoda +moomoo11 +ojitos +plop +23121980 +radha +247365 +9ac9hb7vvx +kelsey7 +danielle19 +fj5tx19hit +raven11 +jimmy23 +59fifty +oscarito +tigre1 +1church +falcon01 +abigail7 +681774 +dsk4r9bskh +21101982 +stormie1 +check +tweety17 +198727 +nextage +nagel +jeremy5 +righteous +marokko +bitches. +081185 +anna2009 +qwer0987 +password10 +120179 +chicken101 +stinky2 +030882 +12021996 +frankzappa +shadow27 +090484 +martin14 +09121983 +spring10 +211988 +mumdad1 +0lhhnw3v +haters12 +pakpak +batterie +tonto1 +sunshine06 +bike123 +snickers7 +24091993 +06011984 +idiot123 +89moocows +prada +vfiekmrf +12031980 +fhbirf +guruguru +deluge +acapulco1 +stern +akshat +hellodolly +qetuo +bnfkbz +andzia +1sarah +023023 +persija +blackfire +chicano +francesc +number32 +daddy15 +olayiwola +casper21 +111195 +famous23 +hatfield +090784 +mickymouse +samir1 +eitaeita +poppin +09051989 +hayward1 +barbra +syl +austin95 +060591 +undertaker +songoku1 +bliss1 ++ +helper1 +snakebite +220478 +algarve +37213721 +dell23 +fucku11 +hoodrat1 +101102 +r4evc8d8vs +newlove1 +080894 +freetime +121212qw +xsplit123 +smother +mario1234 +nichelle +botany +johnrey +perry123 +100295 +peterbuilt +senna1 +hawaii50 +toyota +181080 +flavor +alejandro9 +ctvtyjdf +myles +jackie69 +precious1 +30033003 +cameron05 +texas713 +newyork01 +mama2009 +2522 +pacheco1 +mybirthday +death7 +160580 +290780 +torrie +shopgirl +mustang90 +charlotte +powerstroke +windy +westgate +horses22 +150181 +teatime +vincenza +daniel94 +welcome9 +02101992 +02051981 +horny123 +bella17 +banan123 +billybob2 +31031984 +ssssss +pinky22 +310593 +04091984 +reliable +080586 +18081993 +08041989 +benhur +ball4life +161985 +guapo1 +jamesbond7 +soccer31 +ingres +honda92 +update +gracey1 +godgod1 +ilovecock1 +number19 +theboys2 +281278 +jacob21 +055001984 +vanquish +22111993 +0122 +198516 +kenshiro +24041994 +loveboat +princess* +210379 +monica23 +penis. +loveland +240293 +powerrange +vinograd +pearson1 +toyboy +linked4me +201077 +snowboarding +bhabykoh +omgwtfbbq +dudu +raja1234 +31415926535 +school22 +shaggy12 +sexie1 +stroke +19461946 +271179 +landon07 +babygurl20 +iluvme123 +sophia11 +hollywood! +sidonie +lanie +1juggalo +199800 +blender +030184 +nazarov +june2005 +kurwamac1 +sparky10 +il0vehim +sexy87 +torrie1 +karolek +gepard +150494 +daisyduke1 +gamegame +198456 +29051981 +shadow20 +looking2 +alkohol +14love +casey3 +400018 +methos +15091982 +07041984 +07071981 +chopper123 +sexylove2 +lipgloss12 +191984 +30111993 +esperanto +ville666 +blessed5 +moncheri +kjyljy +shivaji +011283 +070386 +senior05 +cuevas +789632147 +1mercedes +kumara +114411 +200382 +gummy1 +jazzy14 +12111980 +27091993 +vampire3 +blue30 +manfred1 +johncarlo +147895 +booboo09 +190892 +actros +we1234 +aston1 +marthe +paul69 +qwerty456 +141991 +sunny13 +lax123 +110195 +richard21 +apple12345 +11071994 +240181 +casillas1 +lauren69 +tiger16 +654321k +astronaut +113 +08011988 +250379 +pimppimp +loveheart +110779 +198614 +brian +pokemon123 +spider5 +honda23 +rjcnzy +eager +280581 +bodrum +196565 +nintendods +david33 +09051992 +alekseeva +reina +elijah06 +mothers1 +andrew77 +deere1 +hawthorne1 +rc95kzbj1v +19011983 +landscape1 +braindead +121098 +darien1 +maria25 +james123 +198415 +boulogne +saya123 +24101995 +chynna +nascar29 +lauren17 +tigers15 +winston12 +bhumika +bailey8 +crunchie +chris55 +pimp90 +durian +mandarine +shade1 +lantern +070391 +focused1 +patti +gfkmvf +070286 +diamond69 +071091 +wakefield +imgay69 +04101985 +volleyball1 +kitty17 +1adam12 +111294 +210978 +molly07 +281294 +forgetme +brian7 +shandy1 +13111983 +11223456 +22224444 +realnigga +fquekm +runescape123 +oliver4 +150280 +vanessa22 +nico12 +stepup +02111985 +znt,zk.,k. +021095 +198023 +easymoney +kookoo1 +131178 +alex1978 +portishead +whateva1 +wildone1 +brooke4 +1woman +fastrack +tur +b654321 +010580 +beth12 +240291 +gbolahan +kropka +ilovekayla +henley +sunshine0 +modesto209 +solita +ilove21 +crystal1 +schnulli +01041994 +justin27 +nikolai1 +mustang97 +198307 +dragonmaster +santo +kpkp1ee9w +basia1 +cornelia1 +coconut123 +love57 +frontier1 +040389 +aishah +haha13 +hell00 +kingdavid +farmers1 +lalala7 +dragon06 +ramses2 +111111r +seneca1 +verunka +123456789qqq +mets1986 +unlock1 +2n66xg2ziu +15021995 +thechamp +140693 +lazarus1 +30071989 +daniel87 +pendulum +lillo +oyekunle +elfenlied +babi +mishutka +13051994 +speedy13 +14051984 +snowsnow +marymary1 +moneytalks +styles1 +nicole98 +clarity +buster88 +bodyguard +yozgat66 +sweet08 +020482 +tommy6 +remix1 +arthas +suspects20 +sally2 +dbyjuhfl +jerseygirl +alterego1 +260980 +cutiepie7 +danielle16 +albert01 +mania +08101983 +31031983 +bros4life +030285 +010293 +scrubs1 +winter2011 +texas214 +a00000000 +jaimee +giants11 +asdfghjkl! +davido +kimberly3 +11081994 +defiance +mizio970 +wee123 +011191 +justin33 +whites +freddy13 +rdfhnbhfyy +anthony0 +krypton1 +anto +froggy7 +rubberducky +molko24bog +28071982 +genoa1893 +060485 +freddo +08101989 +clusters +newyorker +24041982 +boston33 +011292 +joey69 +husqvarna +mamabear1 +chevy12 +020894 +luchito +staind1 +jaylon +santarosa +phone2 +crazy18 +121270 +dana12 +01071981 +kev +spagetti +bella18 +118218 +honduras12 +hotty2 +02111992 +b55555 +krystyna +18021982 +198303 +precious +bigsis +luckystar1 +help1234 +purple00 +jujuju1 +babygirl30 +andy22 +16121981 +29041983 +tazzie +eu +vvvvv +kingme +alloallo +buster24 +magic101 +28121993 +131294 +brunswick +kelsey! +golf69 +aston +todd123 +shannon! +ville +partner1 +billy01 +mo1234 +ayesha1 +comcom +14081993 +raymond3 +tattoo13 +autumn01 +united01 +oliver21 +3215987 +globe1 +brian3 +nissan350 +aq123456 +blessed01 +01091993 +22011982 +23061994 +peace420 +dogs1234 +icecream4 +dil +janica +peterburg +040289 +21031995 +190500 +smukke +callie12 +bluebirds +dance08 +jonas! +290580 +22051993 +jose25 +london06 +09061989 +080691 +malgosia +1chicago +pinkerton +urmom2 +123iloveme +051280 +rangers +hayley123 +10111994 +wester +lombardi +theresia +eastside21 +married08 +mj123456 +lasers +3012 +darkfire +220677 +hungary +meemee1 +thuglife12 +obiwan1 +peanut9 +gladiador +snowboard2 +caillou +critters +souvenir +king33 +21021983 +jiejie +extensa +preschool +peruano +121211 +pa55wrd1 +design123 +adoption +phatty +17011993 +13621362 +13111981 +skanky1 +vbvbvb +030792 +cheese +sweethoney +frankie4 +181092 +alternativ +201295 +1rebecca +cookie77 +1house +fairies1 +cayang +100grand +motocross2 +peabody1 +123456789qwertyuio +bebe15 +lostsoul1 +death +olasunkanmi +091291 +040493 +toolman1 +jamie69 +skateboard1 +avadakedavra +26061982 +rainbow21 +l1o2v3e4 +pink26 +220494 +isabel2 +anemone +safeway1 +other1 +free23 +shrikant +112300 +25041980 +240694 +fourtwenty +platini +198817 +sagarika +green +adrian07 +190979 +spiderman1 +000000j +cojones +ford69 +lockhart +welcome99 +anthony26 +portillo +jarek +123wee +sandro1 +laura5 +daddy9 +landcruiser +virtual1 +21021993 +pirouette +p.i.m.p +chelsea25 +edmundo +090999 +pretty18 +jose123456 +aneczka +germany +christine +grunt +greatwhite +wachtwoord1 +081186 +berta +28011984 +260594 +mickey06 +parsley +iamcool123 +abby13 +17021995 +tubby +06041985 +ilovezach1 +streets1 +pickle3 +moonstar1 +10061981 +270781 +070291 +blackbox +blue +cuckoo +alfaromeo1 +sarah07 +dereck +negrito1 +zack1234 +100577 +parana +boss11 +09121984 +tigger55 +10021994 +040781 +011080 +17051994 +newhouse1 +sierra +080687 +09081991 +15051982 +500009 +cartouche +lthgfhjkm +onion1 +carthage +hana +17081982 +251983 +power1234 +steven09 +merry +lenard +jamesm +lyalya +waheguru1 +260881 +mike26 +britt2 +zachariah +stanly +mvick7 +scorpio +13021995 +rainbow10 +john25 +microbiology +220295 +115569 +bratz11 +chili +101998 +17101982 +hulkster +100494 +010393 +asdfgzxcvb +alison123 +ridebmx1 +dimond1 +1601 +crystal10 +31121981 +alexalex1 +spicy1 +may1991 +chase11 +090386 +211178 +boston22 +bench +19201920 +124001 +redrobin +23021995 +daniel93 +gigante +reverend +27101983 +lagoon +heehee +midnight! +skippy2 +yagmur +mantle7 +29101982 +161293 +111971 +090781 +italiano1 +sweet24 +270283 +197171 +adarsh +07011989 +bruninha +julias +261093 +asylum +laundry +sialkot +shade +francisca1 +summer25 +08121984 +fernando123 +28071993 +1london +enter2 +hugues +mibebe1 +slasher1 +070708 +ava +boomer7 +sportsman +moneymike1 +sexymomma +021193 +061181 +13461346 +08061983 +loveel +aaliyah22 +2doggies +devan1 +03111984 +lothlorien +linkedin22 +xinxin +jordan77 +20041981 +maxime1 +nogard +iloveyou90 +07011990 +198909 +010982 +1qazxsw@ +again +дмитрий +orpheus +231980 +240579 +alibek +jackson07 +barbie4 +chaucer +dreams2 +warszawa1 +09031983 +shingo +198416 +robbie +26121994 +dragon78 +310881 +240581 +chomper1 +080587 +fourkids4 +stephanie4 +yupyup1 +element! +lolade +575859 +bwfqjpf +encyclopedia +lucas13 +jacob1234 +08031993 +swagga +godtime +dodgers12 +290482 +hebrides +bob123456 +my6kids +putita +frankie5 +lovely15 +dilemma +curtis12 +16041982 +earnhardt8 +tot +maricela1 +261987 +trouble123 +star00 +198305 +maconha +valverde +sexo +hyphy101 +azizah +blader +06111987 +berlitz +mayara +jamesjames +mexico20 +sadiedog1 +everton1878 +150893 +steven07 +sabrina13 +mike34 +bebe23 +angela69 +chupacabra +emily8 +cute08 +jamaican1 +380007 +makulet +gearsofwar2 +080383 +888333 +donthate +azerty69 +brahma +lafamilia +290784 +lunetta +03101992 +angie13 +ladybug8 +catdog7 +070883 +eric14 +07101990 +bartsimpson +cuteako1 +twinky1 +mitchell12 +flower15 +merkur +honda90 +akoito +vfhufhbnrf +gothica +cre8tive +310382 +lolo11 +121271 +morgoth +vitalya +hollydog1 +friedrich +3sa8xk4xdz +28zxrpunfa +167167 +danijela +021065 +zayzay1 +iluvjesus1 +dance5678 +7676 +241988 +denise23 +pichon +cowboys69 +hagrid +columbo +29011982 +bugbug1 +1597534682 +oriane +arnaldo +bob420 +technics12 +boo1234 +dani13 +senior2011 +david27 +29011984 +250493 +fyfnjkmtdyf +wolf69 +carlos09 +dis +030881 +birds1 +valentina2 +dianochka +131094 +051180 +070482 +kolya +antonio. +09091980 +punks +0123123 +snow11 +milord +mama20 +chicana1 +killa6 +linkedin123 +09061983 +2608 +alex29 +missey +apples. +ilovehorses +sharpe +15111980 +050191 +getit1 +go1234 +arturito +diesel12 +antalya07 +09061985 +99999a +itiswell +081082 +photo123 +hajime +151293 +sugar13 +kokopelli +300993 +29121982 +24081982 +125000 +261278 +35793579 +blue82 +310780 +loca +archived +love52 +numark +joey21 +goodstuff +rowan1 +061080 +peterson28 +matthardy1 +198527 +sammy09 +061985 +051985 +chris111 +chelsea6 +080790 +maggie24 +uthvfybz +26081984 +rowell +dicksucker +12091981 +310381 +felix2 +flicker +290880 +volker +sully +213243 +jadzia +031081 +commodore1 +esther123 +123asd88 +montana7 +tenerife1 +1rachel +seaworld +1oliver +bigbro +yourm0m +megmeg +anderson2 +swordfish7 +jojo01 +100600 +101975 +oldskool1 +casandra1 +16031983 +010593 +fuckya1 +marie33 +honey09 +newhope1 +hermanos +258046 +batman007 +26031982 +shivangi +samantha18 +tink07 +miley2 +30081982 +driven +lucky20 +mercado1 +753951852456 +mallorca1 +papaslexzy +toscane +antilles +02011980 +jess22 +travel123 +11331133 +unitedstates +homers1 +290981 +azucar +kamara +29091995 +roxy14 +relax +210979 +wiosna +westend +max666 +13081981 +whyme2 +123321abc +cathedral +021080 +buffie +roots +d1i2m3a4 +scoop1 +cherry18 +sunday2 +suicidal +coldfire +steffen1 +021293 +300581 +11071995 +091282 +karlee +berries1 +crystal +milestone +pangit1 +11011982 +14071995 +jesus247 +love1984 +423456 +110296 +danny08 +imback +rafaella +charlotte1 +middleton +bmw323 +fatman2 +600044 +mexic0 +m3tallica +faith101 +prisoner +13031980 +gabriel8 +7758991 +enters +300392 +sandra23 +198708 +06121982 +12111981 +vasilev +13081982 +123mnb +26071992 +6031769 +munch +200579 +160193 +outlander +okay123 +waller +19011992 +cocoa12 +axeman +1609 +pacman123 +ripken8 +342001 +angell1 +luckyboy1 +010209 +alysha1 +arevalo +310380 +briones +1234567890k +mamanjtm + +sexygirls1 +g1nger +jesus2007 +rhfcysq +oreooreo +27021984 +01081980 +03021983 +281094 +jaspyb1990 +jake06 +300481 +passion12 +aa11aa +30031995 +280893 +kc1234 +411016 +jabulani +20061995 +rainb0w +281293 +11081981 +iwantsex +5101520 +robert123 +prestigio +carlos07 +996699 +justice12 +maxtor +ufhhbgjnnth +angel32 +2409 +dickens1 +colombia2 +namibia +011082 +1155 +houston12 +42069 +181195 +apple33 +bobby10 +pinoy1 +jake5253 +12041981 +sobriety +190392 +beasty1 +vale123 +beebop +fenice +parool +year2009 +29031993 +destiny22 +30624700 +nesrine +625625 +joemalyn15 +170592 +050391 +charlie88 +peter3 +olivia99 +easyrider +susi +190482 +1234567887654321 +ashley94 +deadline +201278 +hunter44 +love76 +letters1 +zxcvbnma +060880 +10021981 +clavier +741369 +wambui +xfiles1 +fucker6 +loveyou21 +280281 +forever01 +dayday123 +tsv1860 +11november +131076 +nfbcbz +independiente +200793 +whatever6 +alexa12 +nastya1997 +jagr68 +jp123456 +toupie +cute22 +devante1 +hahaha7 +trafalgar +humaira +butterfly12 +firehawk +02111989 +nayeli1 +01051981 +zepplin1 +f12345678 +180808 +felicitas +190881 +bayer04 +cats11 +konfeta +hjvfynbrf +mystical1 +batista2 +booty12 +trece13 +sweetie11 +banger1 +broken123 +forget123 +beautiful. +boober +soldiers +13041981 +under +usher123 +william18 +sunsh1n3 +nokiax6 +5647382910 +phatfarm +investment +123321k +01121991 +hamzah +rfvxfnrf +gizmo7 +nikki9 +love4love +texastech1 +trueno +chick123 +hotrod2 +penguin5 +pootie1 +29071984 +030993 +sempurna +080686 +210477 +nissan12 +12300123 +brandy7 +pooh17 +090808 +199711 +271987 +kaylee01 +samantha20 +14071994 +skyhigh +26011983 +farfar +andorra +trinity1 +marko123 +6cs2huaulf +oliver08 +vanessa23 +151179 +babycakes3 +nifemi +kjkjkj +petete +100794 +123456hh +johnson7 +winner2 +100279 +gangsta21 +creative2 +yellow09 +year3000 +111094 +nigger13 +mcqueen +bonjours +burunduk +babe69 +dochka +iloveyou66 +kirkland1 +fuckyou20 +daedalus +master123 +brooke08 +happy +sponge123 +himera +280680 +pimpin8 +degree +kansascity +taylor93 +123test +rosalinda1 +abdul123 +shippo1 +190182 +campione +shellie +arseniy +langlang +chris45 +newlife123 +070795 +papa11 +lovely07 +teamjacob +sexyblack +theboys1 ++ +310880 +060693 +luckygirl1 +081180 +15061981 +riley3 +18111982 +teresa +230994 +kon +01061995 +040386 +frank11 +screen1 +raiders08 +12071995 +tanman +ihateboys +222223 +bianca01 +280381 +khongco +hotdog22 +kot123 +kiki14 +27031993 +21011982 +black77 +121970 +15031994 +booman1 +doom123 +sweeties +navneet +beans123 +logan06 +090489 +too +060982 +allah786 +020480 +chigozie +sherrie1 +lanegra +270493 +drink +michell1 +worldpeace +04021983 +malick +20302030 +nam123 +junito1 +copperhead +denise22 +ctht +kiwi12 +101073 +soccer100 +vball +10121995 +scooby! +241989 +mickey99 +ginger8 +cupcake21 +1800 +monkeys11 +danger12 +122008 +woodwork +charles11 +306306 +150281 +03051993 +gfhjkm1998 +iloveu16 +ilovejon1 +17031995 +sasha2000 +gallery1 +111079 +joker777 +290391 +bigbass1 +dagwood +holla12 +popcorn4 +irish2 +110180 +hawaii07 +mahoney +sameer123 +packers1 +14051993 +070685 +heather10 +marquette +troubles1 +ethel +fatima12 +qwerty85 +wedding08 +dolphin9 +fuck77 +borneo +snookums +iloveyou45 +050392 +serduszko +crystal4 +grey +isotta +mcflurry! +270992 +mama09 +coastal +kelsey01 +lingling1 +200679 +peanut05 +imissu1 +zxcvbnm. +270980 +070186 +raptors1 +hakeem1 +billygoat +717717 +18071994 +hopefull +number41 +aaabbb1 +nigga6 +09021982 +pepper08 +cory12 +maxwell7 +280593 +110696 +debra +speedy11 +asd222 +zouyong +single21 +death! +123star +19861122 +160680 +capitals +elessar +cherry09 +samrat +13101980 +kiss22 +babygirl55 +family14 +23111994 +theking2 +01121982 +football37 +gia +yankees01 +goodbullet +lasagne +tujhjdf +38gjgeuftd +number44 +forever24 +awesome1 +reno +201078 +bmw328 +snaiper +skinhead69 +101297 +1chester +as123456 +fucker22 +glassjaw +acting1 +income +enemy +12031981 +sexylove12 +orange55 +210494 +199017 +corrado1 +ball11 +babygirl29 +joseph99 +governor +poppin5 +45674567 +delta2 +lov3m3 +03021993 +ruffryder +3108 +serval +provider +kipelov +naruto97 +sillygirl +logan08 +imrankhan +marty123 +raptor22 +davidg +198802 +titty +partyone +mira123 +asshole0 +loulou12 +120676 +ferrari7 +liberty +lovelife12 +030592 +77585210 +odunayo +1lovemom +brilliant1 +padova +iloveshoes +summer09 +rosered +sonic5 +bolbol +mobile123 +0011 +23111982 +220595 +28051981 +kings10 +556699 +charmin +snappy1 +mary23 +199110 +rubies +komarova +09011984 +crystal9 +06071993 +19021982 +maravilla1 +160579 +papacito +taytay11 +romeo7 +archery1 +alex45 +23011993 +02031994 +free2rhyme +ellaine +letmein +f00tball +larry33 +06101990 +12q12q12q +shumaher +explore1 +skrillex +091182 +10041981 +allstate1 +180595 +calvin01 +tammy2 +wasup1 +loveme4eve +sassy6 +13031981 +whoareyou1 +drew1234 +chelito +19992000 +spook +seaweed1 +delima +evangelina +200981 +panther123 +bimba +fatkid1 +linkedin7 +sanders20 +26041994 +fuck12345 +connor13 +saitek +tulips1 +fuck09 +silent13 +123056 +13031994 +25071980 +midnight5 +789456321 +29011993 +gaypride1 +jimmy22 +210679 +kawasaki +gregory +steamboat +120278 +lilsexy +061280 +andysixx +smile1234 +130494 +all4jesus +240495 +warriors12 +kukareku +280692 +28081993 +mazdamx3 +07061983 +emma2008 +justin77 +jesse101 +serina +pookie23 +awdrgyjilp +210180 +roberto12 +reggaeton +entrance +bigdog3 +tripoli +120475 +basketball +lildude1 +business12 +honey! +#1sexy +821128 +myspace197 +nandita +killerboy +1shelby +wilton +holycross +micros +fatman123 +qw +wuchun +omega13 +christian. +gerard! +yfcntyrf +winnie01 +030982 +01011968 +dopeman1 +713713 +saiyuki +loomis +broker1 +molly08 +holyghost1 +sebastian123 +bradley12 +harryp1 +secret23 +suleyman +cooper08 +250181 +smile21 +cronic420 +wat +270393 +131988 +221277 +vfvekmrf +shelly12 +dick1234 +160280 +02081981 +craiova +panthers11 +nascar09 +jarell +krishna +23101980 +17111981 +090906 +zadnica +050780 +may2005 +karina +odin +abacaxi +mellie +13101994 +gibbons +29061993 +886886 +browneyes2 +160594 +080788 +beauty01 +240979 +milky +110794 +televisione +o +eatmenow +1country +natawa +verity +kitten +miller69 +001907 +puppyluv +hecate +28041983 +07011986 +gintonic +280395 +sexybitch0 +alonso14 +instrument +raimundo +#1angel +hillcrest1 +240879 +11281128 +leonardo123 +051080 +legolego +rico12 +denise +morangos +visions +boston24 +280693 +19841025 +190283 +m3lissa +reindeer +030893 +dustin13 +ethan08 +serafima +myspace87 +197311 +08091993 +hund +hwriwxwc76 +billionaire +123q456 +1death +moondance +mimi23 +richard10 +katie69 +seznam +tiger17 +4077mash +legia +201987 +christian123 +elvisp1 +25892589 +maria9 +12091995 +flowers +musicislife +tekken3 +100877 +01051979 +element8 +198027 +lovelylady +millan +christin1 +12071981 +050680 +peewee11 +munira +alex78 +holiday1 +brigitta +11011993 +moneyman12 +crip12 +1hater +always2 +02021973 +iloveyouda +success11 +lea123 +methodman1 +vergine +141988 +verto00q +uliana +151078 +packers2 +190692 +froilan +antrax +wonka1 +bella16 +pimpshit +tbaby1 +080189 +dressage +kelly10 +fuckfuckfuck +danny16 +080387 +000000p +30061993 +04041993 +mama69 +nono123 +kitten22 +rockman1 +ami123 +qwertyuiop123456 +301078 +jason33 +mega123 +twilight22 +dundee1 +rattlesnake +getaway +qwer56 +220878 +kasimir +sepultura1 +140294 +qwerty1! +apples4 +realtalk1 +zebra12 +boombox +wanjiru +281180 +15121995 +040292 +21091994 +fenris +23011981 +blaze12 +moppie +sonne123 +brianna8 +ganteng1 +26101980 +renault5 +dominic12 +20011980 +2801 +6point +121194 +xxx000 +alexandru1 +09111990 +moscow1 +chris93 +syndicate +joker101 +191982 +pilgrim1 +22031982 +samoa1 +myspace02 +june1994 +??????????? +vampira +08081982 +starwars10 +ilayda +yflt;lf +shopping! +hutch1 +070589 +18021980 +zcfvfzkexifz +slaughter +gandolf +18041980 +antonio22 +max2007 +ladder1 +080984 +sweetlips +vantage +iloveyoutoo +lucky33 +10121978 +felix12 +buster06 +spacebar +26041992 +wewe +erreway +books123 +haseeb +hunt3r +jenna2 +noaccess99 +treetops +119900 +wonton +841029 +killerman1 +vermillion +03031979 +aggroberlin +4password +260393 +13579q +majmun +huggybear +999991 +as12as12 +291093 +doordie +quagmire +ilovetaylo +luciole +lame +mossyoak1 +260678 +keesha1 +diplom +america22 +dakota21 +yousuck12 +tatarstan +400102 +q777777 +blackdevil +guitar +hercules +12qwert +lacrosse3 +mydogs +13051980 +01091994 +ratrat +draconis +blue94 +lisa +nittany1 +25031994 +01011966 +bizkit1 +300681 +elvis1977 +navyblue +30011993 +alan1234 +knuffel +chanel123 +prank1 +godrocks1 +ilovebilly +210378 +birdcage +not2day +010694 +191081 +sasuke +klmklm +1809 +killas +jessica05 +162636 +300180 +divorce2 +oscarwilde +400025 +600094 + +shameless +ganggang +madison23 +200505 +kan +saysay +221969 +020185 +123181 +p@$$word +crystal8 +ryan101 +prov356 +aachen +bhargavi +neymar +dream12 +ginuwine1 +091092 +231095 +wanglei +290193 +morgan8 +davidh +06111985 +1sayang +baller6 +09121990 +151278 +19091979 +suckadick1 +15081979 +211986 +05052005 +kiss69 +nerissa +littlestar +demi +jacks +18091982 +shedevil +kaylyn +1justice +bootleg +theedge +redtube +sasuke10 +kartoshka +charizard1 +backflip +meltdown +johnny +170580 +milenka +9999991 +meat +01061979 +12280202 +little3 +xavier08 +020295 +baby +ouk29q6666 +wtpmjg +ihatehim1 +robbie01 +08121982 +sasha7 +matt18 +1sweety +290692 +killaz +ccccc1 +gibson12 +aabbcc1 +giggles13 +123411 +111996 +fynjybj +190281 +danny101 +14121979 +12347890 +13091994 +123mama +anders1 +jitterbug1 +canito +27011991 +blue95 +1qaz2wsx3 +skate23 +raf +fakebitch1 +tramp1 +softball27 +151177 +bentong +brunette1 +hahabitch1 +base +nathan18 +children6 +bubba6 +tristar +12345tgb +wcdd93h9pq +moonraker +rhfcyjlfh +0070 +poohbear19 +111111t +svadba +pratham +danielle08 +1929 +21021981 +24011984 +080592 +10071993 +sexy78 +butterfly1 +lolita12 +m0t0r0la +rockyboy +adrian14 +murcia +zelda2 +klizma +thebest2 +monisha +fernando10 +20011981 +bomb +katastrofa +loquito +827ccb0eea8a706c4c +thunder! +honey25 +04031990 +0708 +24101980 +faget1 +198320 +happynewyear +070991 +luka +chance3 +19101910 +poltava +iceman +elanor +the69eyes +verify +twilight. +02091993 +lazarev +whatever21 +crack123 +july1987 +060983 +59635963 +ifycjyhekbn +captiva +nubian +utjuhfabz +nascar123 +600083 +0105 +hasan1 +irish7 +thehulk +gioia +mustang91 +123qwe4r +13021980 +081083 +icebox +jahoda +001969 +bobby23 +kirana +spanish2 +freedom23 +135791113 +220978 +jokerman +manitoba +hilda +271293 +16071982 +frank22 +linda11 +kimani +131095 +10041980 +0507 +j000000 +110108 +dairymilk +pepper8 +02021996 +mandalay +boy1234 +zenaida +29091994 +timebomb +happy777 +poopy3 +040683 +1child +qwezxc123 +shaggy2dop +050183 +07071980 +connor05 +steffy +cocacola0 +446688 +19980621 +kalashnikov +eryyv588 +honolulu1 +forbidden1 +060405 +6868 +0611 +purple45 +kurwa123 +jason17 +200380 +291178 +alabama123 +adeniran +881988 +rich1234 +vanessa4 +scheisse1 +harvey12 +esposito +19372846 +110596 +455445 +parkview +william24 +18011983 +markel +09021984 +kingswood +werdna1 +elguapo +15021994 +hiroyuki +vegeta123 +271292 +grant123 +ivan1990 +33334444 +120896 +041280 +300783 +12041995 +311279 +secret21 +198418 +bayern +rana +delonge +jesus88 +sp00ky +jackal1 +198306 +moon11 +alyssa99 +pippa +df +karaman +031987 +caocao +ilovecock +rayray13 +1fish2fish +10061977 +flyfish1 +pohekale +penfold +love2002 +nevaeh08 +emily09 +donkey11 +hothead +08121991 +florida07 +13031303 +10101974 +198801 +duc +papi12 +30111992 +reuben1 +sriganesh +clermont +jazzy3 +sw0rdf1sh +pjkeirf +maryjane3 +ceasar1 +lineman +turbos +mishmish +sydney10 +28061993 +11011980 +pp123456 +jamess1 +baudelaire +people! +123passwor +pornostar +angelina12 +reo +myfuture +password79 +nokiae51 +bigblack +labella +lfif +fender7 +050575 +jayjay23 +alena123 +clelia +carter +osho +1love4u +leo123456 +emily9 +creepy1 +elijah11 +070797 +17021982 +samisami +24021994 +080693 +laszlo +deeter_1 +160480 +ch33se +squalo +classics +01111988 +candra +boniface +nigga22 +zak123 +18011994 +meline +july1990 +30061994 +butter! +giggles2 +040893 +terrace +fcbarca +alize1 +eminem10 +1olivia +adnan +fluffy7 +imaslut1 +julia13 +farming +jessica101 +senerity +223qwe +rigger +maria20 +sandy5 +13081983 +2smooth +kevin24 +qwepoiasdlkj +iceman22 +350350 +insecure +011284 +080785 +260280 +070487 +coolman12 +arsenal08 +pippone +pinky101 +cheer15 +carabinieri +timetime +natalia +280480 +peace69 +keys +valente +m1dn1ght +candido +1357902468 +carmella1 +luna1234 +pumas10 +140694 +barney5 +amanda00 +lexa +090682 +timon +784512963 +matthew03 +v12345b +11114444 +191990 +ranger00 +woshizhu +juan22 +meandu2 +merritt +remark +enjoi1 +hallo2 +said +просто +555555555555 +lethal +georgia3 +eternel +20111993 +salcedo +0112 +050882 +030709 +jayson +vera123 +13681368 +samples +olivejuice +rabbit01 +03041982 +leo12345 +deville +23061981 +221199 +123boy +cooper5 +130995 +1346 +mason3 +198528 +22031995 +140893 +jennifer18 +justin96 +melissa15 +20021996 +cjkjdtq +internet1 +black! +cfhfnjd +everyday1 +jeremiah12 +rocky1 +loveu4 +checking1 +playboy +16051994 +allahoakbar +giddyup +hotboy3 +saurav +120101 +25031982 +12061981 +daking +decode +050289 +peachtree +loreta +ronaldo2 +2q87xi3vfx +jasmine05 +palmetto +rosebuds +oswaldo1 +soccermom +121232 +qwertyui +sandee +chloe4 +19851216 +farts1 +190700 +lordshiva +volcom69 +06071982 +eraser1 +211094 +07101992 +24101994 +sheppard +gemeni +220979 +asdfghjkl7 +ashley27 + +mounia +080188 +louanne +11031994 +paramount1 +cristy1 +100795 +avm6ubdunj +kesha1 +02031979 +bing +player24 +delrosario +yellowdog +3008 +mazda323f +alfaro +alberto +021986 +21051981 +manila1 +gamecock1 +goheels +deaddead +soccer87 +byabybnb +bonjour123 +iloveme18 +tools +19841007 +123645 +money27 +kahraman +15071981 +yandex.ru +mammoth1 +29111982 +08091982 +poops1 +17031982 +starwars13 +awawaw +fkbyf +cutiepie5 +blackie +springbok +pocoyo +john123456 +asante +papamummy +jack101 +pumpkin! +millioner +311092 +chrisbrow1 +060882 +13561356 +raindrop1 +060695 +william99 +24hours +hayden07 +hoang123 +ad +1926 +stinky123 +repsol +21041982 +08121993 +020396 +cerberus1 +ilovejack1 +159654 +tanushka +11081108 +panda10 +deerpark1 +qqqqqqqq1 +jamal12 +firstborn +redd +28011980 +mama777 +homedepot +josh24 +23081980 +spider22 +franklin +ethel1 +11301130 +mohsen +kigali +26051982 +smellycat1 +ignition +naruto666 +scooter! +coccodrillo +teapot1 +040391 +199811 +fuckthisshit +29091982 +jack09 +123001 +1516 +mytime1 +tigers24 +zippy123 +200606 +brittany22 +hollowman +matveeva +juarez1 +15101510 +jolie1 +13041994 +19061982 +arsenal8 +11101994 +11091109 +monkeys5 +020394 +141421 +plm123 +090584 +fantasy8 +transit1 +14021978 +sparda +peace14 +17041983 +02061979 +vipvip +051987 +station2 +400079 +mahmut +ryleigh +midland1 +sutton1 +yourmomma1 +050385 +aaaa12 +18041981 +andrea09 +bond0007 +140181 +ashley98 +school. +retail +dragon123 +matt24 +hotel1 +03061993 +2500 +boquita +khurram +mehmet123 +valdez1 +tyghbn +071082 +redsox22 +struggle +fgh +dakota14 +mckinney +13041982 +dcshoes1 +tinman1 +12091982 +ninja5 +anabel1 +180679 +manuel23 +26011994 +010382 +ireland7 +prayers +28101981 +beach12 +130794 +iloveme69 +youngbuck1 +bigbitch1 +shelby14 +31031995 +daisy6 +25242524 +librarian +20071981 +helder +nitesh +klavier +250280 +1amber +poop14 +160183 +205205 +jada12 +051193 +iloveu01 +thug123 +solace +flash3 +punksnotdead +bananaman +452452 +nikoleta +honey24 +060291 +haylie1 +kamina +frisbee1 +curtis2 +08021993 +12061982 +100895 +smallfry +cruz +1kimberly +2523 +charles4 +27091983 +rambler1 +gvqjvxvb76 +400099 +oddball1 +dakota04 +261279 +jarred1 +220893 +2609 +premium1 +01071994 +05011986 +07121992 +09041992 +tarragona +kondor +1bastard +tickles +fucktard +03061982 +21051982 +030579 +cradle1 +jacob99 +15935700 +nandhini +lialia +15121979 +powerup +0011223344 +198508 +dunno +cnhjqrf +080385 +madinina972 +libellule +keshia +041282 +timothy7 +eusitu +331331 +olympics +s00000 +050485 +wizkid +1935 +skittles11 +policja +fragile1 +gznybwf13 +sergey1 +selma +mmmmmmmmm +161279 +jonathan20 +23051995 +ortiz1 +sexybitch3 +140879 +nikita1997 +220777 +tomasa +globe +maddie10 +hph2n89qif +elijah7 +110395 +nichole12 +21101981 +imgay2 +genetics +budlite1 +amber! +sexme69 +sweetass +151077 +lauren09 +15243 +x72jhhu3za +09123456 +takeiteasy +sweety7 +31081982 +britton +3578951 +830830 +01021978 +slim123 +loveyou10 +24122412 +090391 +ilovenick! +23081982 +16021994 +lupe12 +er2sizo241 +231277 +kaylah +majka +290782 +clinique +221982 +29091980 +lexie123 +nike14 +zacefron12 +mypassword1 +soc +shitass1 +2425 +lover25 +31103110 +june1980 +rachel18 +lildee +150978 +frederick +1a2b3c4d +270780 +america09 +shit22 +199416 +18street +13091980 +janeway +jackblack +cassie22 +dragon28 +221194 +technician +roro +bryan13 +26041982 +10191019 +070982 +rachel16 +holly7 +090791 +momentum +babygurl17 +mayfair1 +270680 +interest +29081983 +linkbuild + +tokyo +121415 +angels21 +030992 +280679 +miguel15 +18031982 +560048 +281279 +38383838 +france123 +edgar13 +112008 +madison99 +21071982 +19041995 +jacob15 +20011993 +17041993 +school6 +cameron09 +cakes +octavio1 +bebert +bulldogs11 +06041983 +1hollywood +optiquest +250895 +rocky8 +rockout +2326 +17061982 +ilove10 +nijmegen +bosshog +volodia +sing +23021981 +subaru555 +laverne1 +071181 +19041980 +kisa +041082 +praisehim +bhavesh +bienchen +22041980 +lombard +150293 +cowboy3 +11091993 +apollo123 +pooch1 +h80lsa +littledog +dog111 +poiuytrew1 +vanessa21 +sasuke3 +gopack +flowerpowe +kevin101 +class2006 +020982 +minecraft12 +teamodios +02071993 +08101984 +181180 +runner12 +a66666 +haylie +ilikeyou1 +topman +sanderson +270383 +sp1der +260693 +anthony28 +110778 +261079 +241277 +171988 +15091983 +nopass1 +516516 +hotboyz1 +198215 +punkpunk +kate11 +17081994 +polo11 +060482 +bellagio +0907 +asas1122 +cherrybomb +love2003 +fujitsu1 +198504 +mommasboy1 +1snickers +edvard +sommer09 +270193 +tyler24 +1234ss +181279 +brigitte +28071983 +ferec +babygirl04 +27091992 +irene123 +richard22 +skooter1 +boring1 +davidbowie +270793 +alexandros +kenny13 +babajide +lovebirds1 +lucygirl +070185 +ginger07 +strummer +25101981 +iloveme8 +sutenm123456 +qq123123 +nosferatu1 +teamwork1 +080491 +ars +fuckoff8 +mohammed123 +beauty7 +jake17 +190284 +am +buffalo66 +babe1234 +camryn1 +mommy14 +master09 +sometime +201277 +andreika +16051982 +190681 +omsakthi +juventino +lavina +imaloser1 +240194 +honda88 +edward101 +kurtis1 +asdf45 +25081982 +offline +heinlein +docinho +iluvmyself +rincon +plplpl +black20 +quasimodo +pickles3 +snoopy4 +136666 +okinawa1 +javajava +harrystyles +missy101 +quintero +sports10 +gadget1 +king +cachondo +01031978 +eightball1 +14111982 +ring +colorado +11111979 +nana07 +bella69 +11011981 +duffman +cle +loveme20 +ponyboy1 +040884 +060782 +12011995 +hated1 +09011992 +mangal +demetria +vtufajy +kuchen +kaduna +samantha08 +siddhi +ch3rry +school08 +jamie5 +isaiah01 +300595 +omaromar +130978 +tartan +quigley +041084 +bambam13 +171193 +chelsi +07031992 +090978 +ebay +pepper. +osvaldo1 +defleppard +160777 +gotmilk2 +pablos +vampire7 +barnes1 +02011992 +haiti1 +missmolly +05111985 +hottie92 +jlbyjxrf +thomas27 +151989 +fasttrack +2369 +120798 +feuerwehr +chris87 +iloveyoual +jackass4 +021984 +kittykat12 +23041981 +makcim +lero4ka +rufino +dartmouth +pissedoff1 +19071981 +babygirl31 +02081979 +pattycake +19101981 +buster8 +cacatua +kangar00 +mamanjetaime +775577 +250978 +jordan1 +lilylily +raven7 +alecia +141008 +230195 +shelby69 +nicenice +ybrjkftdf +claudita +mason01 +babe22 +240894 +hooch +05111988 +310592 +maria19 +lawrence +moneyboy +anna15 +mistigri +phiphi +barbie21 +bhutan +munkey +26111982 +201094 +shelby5 +silviu +200779 +qqwwqq +160381 +norwood1 +smokey6 +zamorano +090188 +acdcacdc +tina01 +taters +breanna12 +041279 +shreeji +098098098 +fordford +falcon11 +budweiser8 +shelby22 +rianna +mistery +fine +goodlooking +anna69 +mkomko +pe +granit +july123 +coqueta +victor21 +18031981 +superman27 +joshua1 +curtains +ocean12 +isabel01 +plaster +1penguin +lena1234 +291181 +123itsme +kings5 +fuckoff0 +151983 +fruitloop +29011983 +segreta +sexy4ever +andres13 +05081993 +cheeseball +marcial +parkway1 +041283 +20021995 +morgan69 +mc123456 +veneno +qwertyqaz +loser55 +09121992 +aggies12 +pecora +laposte +ilovebob +sweetsweet +girl23 +camello +jayden23 +270893 +supergirl2 +160893 +f1f2f3f4f5 +selamanya +geelong1 +panthers09 +230877 +bernabe +pennys +dheeraj +261985 +sinclair1 +160379 +lizzie2 +justforyou +twilight5 +17071982 +looklook +xh246aigun +98765a +queen3 +1290 +mathieu1 +bball8 +ribbon +dallas +panatha +player9 +abc123321 +noncapa09 +21021995 +pamela +filthy +hiroshima +maslo +codeblue +131278 +stars13 +13579000 +oakwood1 +angelica2 +nirvana3 +852456852456 +spooky2 +333123 +display +888222 +police +kenneth +football59 +pet123 +jennys +pizda +02071979 +barley1 +030508 +kitty24 +vbnmrf +empress1 +08081981 +060694 +050185 +221078 +260878 +lena2010 +198807 +ell +bears2 +poontang1 +baller07 +police9 +240380 +luqman +devildriver +emergency1 +babyjane +spears1 +realmadrid1 +vermilion +sparky3 +09081982 +pimentel +joshua77 +sweetie5 +paperboy +22021995 +cheat +rose24 +skeeter2 +antwan +06111984 +kangkang +rosenrot +mariposa11 +230694 +tyrone2 +games12 +234234234 +141178 +music88 +figment +zimbabwe1 +douglass +krzysztof +dylan4 +301179 +robert33 +101996 +joelle1 +carrie12 +precious01 +lool +school8 +170693 +arthur +martha12 +ryan1 +briana12 +21111981 +198124 +troll1 +honeydog +texastech +arschloch +popcorn22 +katita +ponies1 +temitope1 +160293 +25021994 +audrey2 +familia4 +sq8hm7l4 +enter12 +180693 +terrie +04061993 +ylenia +britty +1237890 +nightmare6 +touareg +7734 +$hex[687474703a2f2f616473] +mhinekoh +admin1213 +gastone +28011993 +john99 +231176 +splodge +maruthi +06121983 +00070007 +manikandan +qwerty65 +600096 +21021980 +salinger +tinker4 +sam111 +seth12 +godrocks +master1 +guitar21 +24081983 +190480 +beckie +help12 +1234567890v +13121979 +lollipop3 +monkeybut1 +scotty12 +minako +jinkazama +asian123 +020892 +mystere +zaqzaqzaq +alyssa04 +elnumero1 +29061981 +240677 +wiley1 +28121994 +jess21 +jonbonjovi +nicole84 +sesese +nolwenn +090185 +garth1 +180380 +moskow +31051995 +one111 +ercole +linda +999999999a +081280 +texas07 +hoho +112311 +gaston1 +cocoon +271093 +fynjy +06101984 +artistic +marie92 +21091981 +17071981 +rocket11 +matrix13 +janosch +brussels +jesus19 +mistrz +lex +luis22 +blomma +gabrielle2 +22081981 +hen +mark18 +gangster10 +cookie25 +harlee +110994 +0741020 +19021983 +tiberium +royroy +19121980 +doriane +4xeaxr653e +monster101 +180482 +activate +pussy8 +011081 +crazzy +alex44 +acissej +170493 +baloo +cowboys07 +mamang +dragons +aimee123 +deeper +nonoy +snoopy6 +ghjghjghj +drama123 +blake7 +11121994 +killer187 +45 +king45 +halo3 +pooh18 +180479 +pangetka +hotboy23 +24102410 +1granny +andy21 +1zxcvb +vinoth +nicholas6 +decatur1 +8181 +199214 +230578 +deamon +29041982 +090886 +dri +spring2 +31071983 +270381 +kovalev +29051983 +291293 +141179 +fuck08 +joecool1 +foxfire1 +ginger09 +salento +tane4ka +kabuki +poser1 +tinker14 +secured +10011981 +aaaaaaa7 +130677 +marine123 +harika +jackie14 +therock123 +blackpower +011093 +jennifer09 +henri +miller22 +c0l0rad0 +eggroll +alex1975 +neutron +nathan9 +aleluya +123zxcvbnm +020993 +260480 +habeeb +gangsta. +nevaeh07 +1706 +lenin +doom666 +spider +jonathan18 +joker6 +naruto25 +lilypad +ramani +080291 +240877 +16021995 +050792 +robin12 +cricket12 +110808 +alina1998 +140382 +mahesh123 +lagartija +051986 +sexy04 +thunder01 +bubbles0 +060586 +cyclops1 +diana15 +panic123 +ilovematt! +star56 +schweiz +101993 +112009 +bochum +mikki +tony18 +clarinha +120176 +nikki16 +michael30 +fuckstick1 +estrelas +mack12 +0306 +pen123 +celestial1 +leon1234 +onelove! +160881 +nicknick1 +sweet20 +090187 +mateusz123 +beach2 +state +rockit +159159p +30111983 +rockstar8 +pissedoff +131990 +fatso1 +mirtillo +1234566543 +jasper3 +7410258 +09011986 +mnbvcx1 +faceb00k +apologize +pamela2 +500047 +kometa +08041990 +hornet600 +500073 +dollarbill +access12 +killa187 +ruger +brittany19 +24051982 +z11111 +130195 +13051982 +444222 +270281 +crossbow +ahmet123 +sonicboom +26011982 +jackie +271271 +28031993 +love900 +400074 +luis17 +jacket025 +2titties +helene1 +200979 +december07 +music +sparkle2 +pookie10 +13031982 +party69 +victor23 +friday2 +chloe7 +prdelka +sagopa +golfpro1 +matematik +kara123 +liberia +10021980 +botswana +boob123 +randal +tomfelton +23111980 +qwerty80 +vito +gangster7 +loveme +10111995 +22121995 +vengeance1 +2pac2pac +handicap +198417 +nikesb1 +734992 +070190 +loveya123 +yellow1234 +30041982 +159753258456 +gilmour +shinee +misaki +bigpimpin2 +270883 +edward. +winter11 +csillag +hondaaccord +poopoo11 +doggy3 +dinky +snowball3 +bigpun +iloveandy1 +0101010101 +159369 +141195 +manu4life +143baby +darby +isabella +fredo +maluco +humboldt +30061982 +seema +steelers01 +17031994 +arsene +050893 +biotechnology +deleted1 +frankie13 +230978 +london77 +tigers14 +julian08 +28101993 +julian3 +weed14 +chalupa1 +june1993 +101994 +260580 +alyssa02 +malaki +teddybear4 +bungalow +surf4life +sagara +bonethug +dejavu1 +010992 +qaz12wsx +rhenjq +songohan +baster +skills1 +iloveyou91 +bluecar +alyssa09 +04111989 +sweetwater +maffia +1vagina +holiday2 +moulinrouge +combat18 +711101 +gioconda +rousseau +christina8 +05031983 +200393 +marina10 +dixon1 +carrera1 +piaggio +goldie +1cecream +030981 +180780 +260181 +pass@word1 +mentari +nissan +banana +haritha +h2oh2o +291177 +891011 +grace13 +speedy01 +extension +andrea07 +bhebheko +thc420 +nike24 +panthere +250993 +scampy +paulo1 +london3 +vampire69 +xyj44pe3gv +woody2 +111199 +buddy06 +baldeagle +belova +andrian +70707070 +carolina10 +cambodia1 +boarder +chris34 +cherry08 +hung123 +akash +scary1 +nelly2 +15061994 +fishing1 +130979 +pene +gloria2 +ortega1 +bnbnbn +fiddler +budlite +sasha22 +libertine +dominus +37373737 +negative1 +niallhoran +hottub +seattle206 +kingdom12 +091180 +highlands +011184 +matt07 +220202 +werty12345 +23081994 +man123456 +eminem88 +11223344556677 +281193 +shamar1 +anissa1 +tinker22 +101071 +edhardy +valerie +03041980 +radiator +thando +aastha +fastlane +bettyboop3 +drink1 +thejoker1 +balls12 +060487 +bob1 +butter7 +amber17 +theresa +201177 +rainfall +200010 +1butthead +assmonkey +bellamia +01111987 +marcell1 +йфяцыч +coolpix +beezy1 +10091980 +031180 +120408 +pussypussy +goliat +oldtrafford +tel +jza90supra +roland +tippy2 +130695 +omgwtf1 +huggies1 +lidiya +090583 +fuckyou +160281 +2030 +20042008 +19031980 +beaner12 +14051982 +beasley1 +planb123 +01477410 +wilkins +08101992 +hammer69 +27051981 +bricksquad +fabian +nokia6280 +brutus12 +500036 +mariami +181293 +311277 +tumbleweed +130194 +2602 +cherrie +29031983 +topmost +198101 +20152015 ++. +19101994 +cassie7 +shanks +1hateu +080992 +1kingdom +070691 +yanks +funhouse +england12 +mamaia +wethebest +nsync1 +laurita1 +probation1 +922i4deebm +hiphop13 +aaa999 +061081 +shabba1 +01051994 +280791 +videogame +04081993 +200181 +lovechild1 +sivakumar +macbookpro +11041981 +03111982 +pass4me +avril123 +oficinag3 +938271 +parker3 +050879 +270282 +blue98 +friend3 +145236987 +peaches21 +demond +55555r +hyperlite +summer12 +prettyboi1 +naruto92 +260676 +09061992 +fdfdfd +01061978 +smooch1 +wolf666 +danny17 +ibrahim123 +stinky12 +bigred2 +ambiente +two +miami2 +piggy12 +1hiphop +bizzy1 +rocking1 +willie11 +happy111 +hammer11 +ajay123 +brutis1 +123chris +230595 +tee123 +151980 +mumumu +mariah01 +140380 +patches01 +password2011 +03091993 +butterfl +fifa11 +jazzy01 +lisa23 +131077 +2580852 +did +liverpool1892 +uni +sandra7 +maxthedog +bruninho +220995 +23101979 +gf +jonathan. +ancuta +123qwaszx +ourson +rap4life +261179 +19121982 +jerica +pancho13 +maria. +270993 +charle +05071993 +180594 +yankees08 +121998 +ionutz +whatever +panic +050384 +pumpkin11 +dfdbkjy +18031980 +daisy! +kinderen +nobita +28091982 +fatcat12 +cassie4 +05061981 +211985 +jerome12 +141078 +3kitties +cs1234 +290181 +cabriolet +jason16 +school101 +08081978 +philomena +weezybaby1 +lyric1 +mrcool +destiny21 +goldwing1 +11111111111111 +print +fantik +jakers1 +football#1 +flashman +19861020 +dallas99 +lthtdyz +fishka +saab95 +27051982 +kirill123 +viorica +maggie15 +playaz +daisy14 +secret007 +larrybird +simone01 +nitin123 +201279 +battleon +allezlom +24041983 +worker1 +coolbreeze +9yue27ri +04121982 +dannys +290680 +230295 +evil13 +654321t +goodison +16061981 +kungen +brandi12 +ghjhjr +lordjesus1 +tinkerbe11 +brown3 +21081982 +06041982 +frank01 +inlove3 +april2009 +kemper +ihateu123 +recherche +eugenia1 +ephraim +030482 +ninja9 +adebisi +1lovelove +forest +chains +mouse13 +bricks1 +208001 +connor06 +261294 +ivan1980 +050483 +pantera +09091994 +280181 +19851212 +joschi +pepsi7 +friends4li +nascar9 +04111992 +cassie! +24091983 +tiger123 +thereisnospoon +islandgirl +giacomino +03061994 +09101989 +guntis +charles1 +malamute +mooseman +161095 +gilligan1 +naruto77 +edition +lukaluka +lamer +curry1 +meme13 +vivamexico +gracie13 +dipo01 +efrain1 +cowboy +vitesse +abc987 +crf150 +krishna +tamie +thuggin +kerrigan +taffy123 +victor5 +260479 +527527 +040392 +300380 +150477 +24081994 +21121980 +leipzig +dispatch +27041982 +carlos8 +luigi123 +180294 +cmoney +tylerb +noggin +1password +as12df34 +rafal1 +517517 +09111988 +301177 +jesika +max2009 +lutscher +cjrjkjd +sushila +010582 +16881688 +552233 +hakuna +180393 +reception +kl1234 +denhaag +zorglub +7070 +201095 +angel78 +25031980 +maryjane4 +220180 +sheva7 +muddy1 +machin +scorpio3 +sawdust +joseph05 +keroppi +lynsey +mollymolly +messages +150979 +cassiopeia +fgdfgdfg +700017 +suman +ak47 +01021996 +twenty7 +barnie +pippo123 +lisichka +liberty123 +wise +kanpur +08031980 +050486 +levani +sardor +kawaii1 +mercedes123 +sallyann +250194 +stefani1 +viktoriy +1488ss +asha +nick18 +23061980 +borris +shadow94 +our3kids +partsites +1911a1 +mama08 +yankees9 +pupp!e +kyle10 +dogmeat +pepsimax1 +fuck_off +25081983 +steelers! +24021983 +daniel33 +bitch44 +porsha1 +matthew04 +three11 +iluvhim2 +emmalee1 +4043vd +300679 +200400 +021988 +jose24 +123786 +24041981 +sonoma1 +tumtum +84848484 +hotstuff69 +martinez13 +ciaooo +loveline +123456hi +orbit1 +lover4ever +23051980 +198728 +20092008 +8wwh19duyj +ilovepaul1 +050393 +q112233 +kira12 +seo21saafd23 +28011983 +progamer +courtney14 +hailey3 +14041981 +pianist +mustang64 +louise13 +zaharova +mississippi1 +cyclones1 +14021981 +temidayo +miniclip1 +projects +22091980 +ladeda +jak +sexy +gangsta01 +amor23 +walker2 +18011982 +moncho +pizza1234 +yoyo1234 +lady22 +cnjvfnjkju +marie +playboy4 +prettypink +170695 +natalie4 +casa1234 +shorty +bling123 +pavel1 +diesel01 +13521352 +andrew26 +chomik +crazy9 +mike89 +1982111 +09031992 +galaxy123 +lorenzo +mario15 +112500 +rachel23 +duncan +june1985 +barcelona0 +lenny123 +1sandra +asdf321 +uis9zdgysn +190777 +258013 +djkujuhfl +1188 +tevez32 +061987 +zaxscdvfbg +yoteamo +pinkpanthe +pawel123 +shannon +schmetterling +sergey123 +arabia +puppylover +alexandra7 +travis21 +050992 +jkzjkz +littlered +latinlover +090685 +vfkmxbr +lollipop11 +mypass123 +surabhi +danny07 +lucie1 +pisser +jimmy10 +loll +psycho13 +220577 +october06 +babyg +zeus123 +bebe14 +charger21 +bubblegum7 +11071107 +17061980 +thanos +divers +06011985 +buddy111 +pineapple7 +171179 +wenger +redneck13 +210596 +morgan02 +teddy10 +08011986 +summer10 +frogs123 +poopers1 +19851225 +280681 +11111994 +paola12 +minimoto +11051995 +251176 +200707 +8i9o0p +peperoni +hiphop11 +112112112 +310579 +journalist +ghb +gangster! +175175 +sweet1234 +m2ydegkdws +110000 +04051982 +candy18 +carambola +kimberly11 +amor01 +narcisse +sasuke22 +rayyan +lechuga +24031993 +jacek1 + +dkflbdjcnjr +usnavy1 +260180 +ramone1 +craven +254254 +fish13 +pathetic +god1234 +25111981 +vsevolod +floare +04071984 +anaelle +kis +nordic +october07 +seppel +shredder1 +between121 +victoria4 +dashboard1 +romeo13 +sloboda +canyon1 +gunit12 +winter2010 +241293 +081282 +030780 +brainstorm +05mustang +abbygail +silky1 +mother21 +bloodline1 +27111983 +1982gonzo +gollum1 +paul22 +211294 +rezeda +lilmama23 +toto1234 +miercoles +198428 +blond +baby32 +130295 +4949 +10051980 +wawa +777jesus +spike7 +fashion12 +z1122334455 +higher1 +disney411 +gjikbyf +221294 +1samsung +ballin09 +chicken +22021980 +bulldogs10 +babys +wahaha +jayman1 +getfucked1 +angel1995 +ladybug! +derek12 +amber6 +jenny16 +harerama +add123 +02111983 +kittykat2 +brindle +tiffany22 +secret6 +04051993 +fluffy3 +sarumi101 +nd2ia8v8az +nelson2 +02061995 +197222 +3009 +24101993 +hyrule +timothy1 +eliana1 +24101982 +06051993 +folk74 +crossword +3366 +192939 +naruto08 +domi +sims +20031995 +lovepeace1 +zach11 +040792 +26051981 +12011981 +10051005 +amber18 +belize1 +heart3 +121074 +180792 +punk11 +goldie123 +2xtreme +otherside +198816 +0000011111 +240678 +deerpark +fldjrfn +ateneo123 +babyluv1 +500044 +190193 +kaydence +greenie +121205 +grace4me +emeralds +james420 +200577 +lyndsay +06091992 +booboo16 +333eee +david28 +fbobh_ +chivas18 +eagles81 +111175 +alma123 +danger2 +150993 +lucky19 +17061981 +blackblack +semperf1 +kanwal +27021993 +nabil +jasper7 +1320 +likemike +kallie1 +apollo +br00tal +batista12 +gnu +nikki08 +sosodef +1323456789 +192000 +0o0o0o0o +20462046 +04031982 +dagestan05 +andrea6 +mcgregor +050981 +753214 +witspass1234 +1lovelife +ilovemaria +041092 +leumas +batman25 +040477 +spiffy1 +11071982 +mikimaus +zxcdsaqwe +iceman01 +prueba +swimming12 +15041980 +jayne1 +car1234 +jamila1 +rdxyd43hca +kitesurf +2706 +nathan17 +shadow93 +dethklok1 +rahrah1 +121176 +toy +lawless +playboy18 +bigboy15 +061093 +051281 +chummy +25091981 +03091982 +rbrbvjhf +boscoe +jorden23 +05111992 +19091980 +maitai +eric15 +napoleon +mybaby! +twitch1 +kalinin +aishat +pou +14051981 +060780 +210707 +helives +mars123 +alejandro0 +inlove09 +10041979 +volvov40 +370000 +spiker1 +happy4ever +brandon25 +220794 +020780 +naruto88 +rupesh +25091993 +123456789az +goldenboy1 +lynn01 +666666d +qwaszxedc +deer12 +nirvana +151193 +mentiroso +hunters1 +zkexifz +vlasova +george14 +040393 +masterplan +666777888 +gri +love2001 +ja8yc7txs8 +31031982 +mariah11 +maggie00 +notrust +getlaid +mario14 +1samuel +43434343 +princess86 +ilovejay1 +amitkumar +chicken14 +cutiepie14 +huseyin +010480 +198923 +memek +yesica +1001001 +vicvic +5251410 +050793 +080985 +raiders22 +120295 +trixie12 +theboy1 +jezebel1 +diversity +160160 +sexygirl14 +ascona +050782 +coffee3 +trouble +doctor123 +03041995 +bowman1 +korokozabr +vfvf12 +neversayne +812812 +8282 +roberto2 +30071993 +jessie14 +28081982 +michael92 ++ +110331rahili +cloudy1 +leeds123 +25101994 +bullet12 +jazzy11 +131995 +katkat1 +06011992 +physio +farah1 +darker +bitch66 +030781 +02051994 +lucka +shearer1 +flower101 +199314 +otters +wildcats2 +281280 +jaylyn +redsox23 +151984 +alina1997 +cheekymonkey +warrior3 +maria12345 +ilovedanie +usuario +guwapo +sp +sti +sebas1 +huawei +luis16 +271279 +passing +ricardo +dancer8 +adadadad +godloves1 +mobster +amor21 +21031982 +27121994 +seagull1 +n1rvana +travis22 +free22 +jerrys +22121978 +honda05 +zach1234 +lemming +charly +chayanne +wasabi1 +lindsey12 +louise3 +29071993 +cambria +05061980 +gecko +2909 +070287 +11121980 +jackie4 +tomtom2 +lover55 +05021983 +danie +250281 +cheering1 +skin +noproblem +1234anna +5121472 +18041994 +grace08 +norman +24021982 +011282 +reed +shadow91 +arianna2 +libra123 +1softball +08081993 +junior20 +17041980 +13091982 +k.,k.nt,z +080286 +barbie14 +290994 +020893 +zarema +hlubkoj1 +alicia3 +fabian12 +ugly12 +malina1 +neslihan +cupcake23 +username1 +14031980 +janssen +0610 +wrestlemania +sombrero +bigdaddy01 +belial +springsteen +brenton1 +anita12 +marylou1 +good123456 +180000 +13qeadzc +141980 +gixxer +chiva1 +jes123 +saad123 +cheese1234 +14011993 +camels1 +15091980 +tylers1 +100195 +25041994 +gmail123 +linux123 +280994 +hfytnrf +110996 +hydro +peppie +anvils +200593 +forensic +valentin +skates1 +ludmilla +060608 +sledge +daughter2 +04200420 +mary10 +mahalkita +cvcvcv +avocat +miller3 +161179 +faggot69 +denisse1 +alex85 +arsalan +vanessa15 +weed21 +nigga21 +michelle0 +komltptfcorp +r2d2 +filipina +19121995 +karens +220875 +shenlong +69qd5cgxhu +daddysboy1 +15071980 +180193 +sexi12 +godzilla2 +collect +161984 +teamo3 +artwork +lakeview1 +gilang +muffin69 +040992 +260679 +cypher +140677 +sex69 +pepsi13 +cute01 +harmony2 +super23 +kushal +loklok +chris32 +brebre12 +mawmaw1 +doors1 +thatcher +261177 +biteme3 +81818181 +postcard +010309 +21111980 +curtis123 +greater1 +060781 +babie +250979 +jabroni1 +15071994 +jack00 +1myspace1 +lakers5 +fenton +hannah69 +nicusor +120996 +jump23 +d666666 +prince5 +annamarie1 +annea +99990000 +happy16 +peanut. +mommy06 +28021993 +renae1 +vinter +gamma1 +230678 +inuyasha123 +logcabin +manuel22 +lab +athina +dave69 +220994 +vinod +blacky +031181 +titouan +karabo +junejune +ilovehim14 +17121994 +020679 +050884 +1934 +198128 +glock +hayward510 +prateek +divino +flyleaf1 +147896325a +smoke14 +22051994 +monkey12345 +kayak1 +garnet1 +nathaly +blbyf[eq +20021994 +discipline +910910 +may1994 +fredy +thunder69 +++ +ilovejosh! +a321321 +playing1 +prerna +12091993 +peter1234 +25111993 +westbrom1 +greatgod +chula +800020 +denver3 +17061993 +harley98 +brat12 +bigdog01 +11021995 +tanner10 +zack11 +1jessie +161093 +milo1234 +walton1 +070492 +cola123 +nathan00 +chewey +cinderela +smasher +brebre123 +chiquitita +branson1 +hippos1 +12340 +1night +25121995 +010579 +lamejor1 +shimmer1 +babyboo13 +24101981 +lensois +050578 +rfktylfhm +181989 +rising +190992 +sophie99 +291180 +maxim123 +400007 +110793 +10071995 +qwerty4321 +turtle21 +201193 +02051978 +lebesgue +johnathon +ялюблютебя +301178 +20031981 +erine! +16051993 +290579 +121204 +corinthian +05031981 +wolfgang +johncena13 +shaka1 +swiss1 +mindy123 +197412 +lauryn1 +daria1 +120800 +koko1234 +savannah01 +shilo1 +blabla2 +08041983 +getmoney! +authentic +slipknot1 +starwars +230477 +1325 +brayden2 +amber07 +bakers +robina +white2 +sakic19 +argento +03061980 +farthead +cerebro +mariana +240393 +150894 +kaspersky +tweety9 +a444444 +repbyf +hammer +jughead1 +free13 +140477 +250578 +gemelos +130279 +point1 +petike +mary15 +southpole2 +10261026 +mike27 +fy +sealord +10071994 +030583 +grinch1 +hbk169 +20000000 +sponge2 +03101983 +cannibal1 +dragon2000 +081295 +130596 +3.14159 +semen +tony17 +omglol +maramara +seafood1 +kickit +crapper +ginger. +pepe1234 +doggys1 +lkjhgfds +coco15 +tryme +nicole90 +eggnog +moneyman2 +kevine +wexford +130595 +25091982 +188188 +ross123 +marvin01 +chester13 +pockets1 +riley08 +champ12 +carneiro +kamal1 +bigred12 +denilson +040984 +bullet2 +190492 +candy17 +hollywood0 +14121995 +joey14 +pass_rrr +worcester +bernard +frantic +november07 +ras +mmmmmm6 +171983 +pimpdaddy2 +michael200 +plato +19031994 +love888 +rani +stephon1 +diosteamo +250178 +20022003 +spirit7 +bebe1234 +azure +elefante1 +pumpkin +blue1 +fanny123 +angel321 +987654321l +141177 +2912 +110179 +tigers05 +091987 +busdriver1 +boludo +elephant! +2021 +lily11 +111968 +290182 +jonas11 +sekolah +ooooo0 +07081982 +barton1 +nikki07 +bit +bella8 +1eagles +yoohoo1 +matias123 +sd123456 +wisdom123 +fenix1 +bcgfybz +1523 +080786 +cool90 +fangfang +26021982 +bebe22 +111176 +13081994 +alex1979 +26081993 +19081982 +bbb111 +azbuka +irfan +county1 +paris13 +150278 +14701470 +toots1 +oluwaseun1 +123w123 +inlove13 +dakota +197610 +recoba +mariomario +fatema +july2801! +vologda +interesting +biteme11 +boluwatife +batman33 +rfvbrflpt +iceland1 +29081982 +love2004 +kyle21 +blueangel1 +bvgthfnjh +pac +9632587410 +chelsea26 +cinders1 +insomniac +05021981 +140979 +ninja3 +hollywood4 +19411941 +041181 +aristide +flapjack1 +301079 +nokia73 +220778 +полина +lillypad +06081983 +roger12 +102080 +adriane +margit +qwerty34 +090387 +loveme143 +nintendo12 +14091994 +20051993 +141079 +sukkel +270382 +07101962 +mellisa +huguette +19031982 +pattie +19831984 +ckflrbq +vjkjltw +kanchana +july2006 +200780 +creative +naruto98 +05101981 +cookie33 +merced +sparky22 +scott13 +831220 +mollie12 +mari13 +torrents +hotdog5 +incomplete +evh5150 +0712 +chip123 +280879 +armyman1 +fabric +press +groucho1 +woo +121273 +141077 +phil123 +universitario +parker9 +nita +hooters69 +generallee +damien666 +pentax +release +ironman123 +611611 +winky1 +choice1 +080683 +180481 +playboy10 +artemisa +child1 +anna1999 +gesundheit +shop123 +gothic123 +goodgame +prestige1 +bubbles07 +thug101 +pooka1 +25041982 +harleyd +panthers10 +270480 +bhagwan +feuerwehr1 +jake05 +lilo +boyz2men +p0kemon +09121991 +families +gfhjkm13 +102090 +colts123 +daisy07 +june1991 +101110 +the1ring +sexydiva1 +12345678910a +150478 +15081980 +jamie7 +27071993 +smurfette +199202 +karlita1 +8thgrade +supersexy +thunder6 +darinka +designdeal +david2009 +scooter22 +bigbucks1 +nyyankees1 +strauss +frighten +magic8 +gumdrop +dreambig1 +922i4ceebk +poop33 +danny18 +04071994 +poopstain1 +homedepot1 +padmini +greg1234 +7777777m +271983 +jasper22 +cowabunga +sayang12 +hello2you +kisses4 +198828 +archimede +240779 +niceguy1 +superstar0 +he +feedme +16091982 +daryl1 +19921993 +nala123 +catsdogs +k123123 +24121994 +baby2005 +student2 +19861987 +08091994 +jeremy14 +031293 +buddy99 +innocuous +magic23 +drinking +020981 +111111e +jinky +sillygoose +billyjoe1 +cutiepie4 +brandy +27101980 +edi +hatred1 +ravenclaw +marijana +thanhtung +scooter10 +summer18 +240578 +010991 +010794 +031985 +fallenange +jeannot +020694 +garrison1 +240180 +runescape5 +saltwater +damn123 +24041993 +valerie2 +sasha3 +090892 +roma1234 +emily21 +daedae +sweets2 +lovebaby1 +purple95 +19071980 +spider23 +1521 +223856 +loki123 +210478 +mother13 +snoogans +heather9 +198301 +marmaduke +pregnant1 +christmas! +diediedie +patti1 +minemine1 +lilly01 +tumble +1357924 +geranium +07111991 +31051982 +anna16 +30121993 +sweetone +qwertyui9 +trupti +shakir +madcow1 +dude14 +jeeper +mamamama1 +anthony77 +spongbob +lovebug7 +canddcard1 +01101981 +kingfish1 +zahra +darth1 +abd123 +june1995 +miller5 +horse3 +tinka1 +rolly +stargate +nokia7210 +180878 +freedom77 +malcom1 +hailey06 +moh123 +120806 +765765 +perfect7 +seahawk +123456da +papaji +amauri +king20 +jamie23 +brittany9 +negro123 +deangelo +love65 +3kids4me +booger5 +hanahana +123321l +vishenka +sasa12 +quetzal +6060 +251988 +redsox15 +sanane1 +07031983 +marinero +kiklop +remy +baby321 +ventana +27061992 +070182 +020493 +colacola +david1 +holly11 +010394 +0666 +66668888 +sl1pkn0t +skater. +231990 +kayla21 +16111993 +05031982 +170879 +302021 +060793 +angel420 +allstar123 +070880 +brianna1 +17021981 +ara +akucantik +25021981 +florinda +191983 +20091981 +advent1 +clara123 +brittney12 +rusty11 +robertson1 +sissy12 +sayangmama +010882 +belle2 +anjinho +kevin20 +route666 +baker12 +09081983 +13061995 +melissa6 +030483 +090684 +eric10 +caneta +171990 +taras +purple66 +22011981 +619619619 +240793 +191280 +cindrella +mugwell15 +260493 +1casper +071084 +tangtang +fisica +knight +frog13 +sanchez123 +katushka +august04 +uandme +woshiwo +angel84 +pavani +kajtek +amelia123 +tamiya +fifi123 +ghislaine +19822891 +titanic12 +melissa16 +stardoll1 +riders1 +050507 +miguel22 +fktirf +toy123 +layout2 +190882 +elendil +20081980 +nikki18 +mate1.com +03101981 +jay12345 +blackass +sports23 +notice +sugar01 +molly +sayang89 +07021983 +zcfvfzrhfcbdfz +xxxyyy +logic +shireen +alb +lilmama08 +fouzia +victoria21 +gooner1 +07011991 +address1 +fines +65432100 +vladivostok +foodfood +17071980 +01011969 +plonker +chile1 +0307 +261094 +0406 +junior03 +thiago123 +zxcvbnm123456 +shearwater +210677 +anastasiy +dreamer12 +aaaaaaaaaa +yorkshire1 +1joker +jacaranda +courtney01 +saxman +060679 +26111981 +140180 +130977 +player6 +18051980 +miko +fandome1 +180280 +199610 +keke11 +manorama +burgers +forest123 +favola +04021984 +loser08 +21071980 +satya +17041982 +andy1999 +god12345 +200477 +qwerty1991 +heyhey! +sammyboy1 +goonie1 +aa1122 +cjymrf +020408 +skater17 +master! +dylan05 +morocha +bum +199122 +12304560 +qaswed +moonie1 +fernando13 +caren +darling123 +21121981 +310879 +berkley +19061995 +379379 +catwalk +lorena12 +panther11 +shorty19 +killa11 +monkey86 +buenavista +010280 +swim123 +091192 +cuddle +pounds +mantap +orangejuice +010174 +08021983 +25052505 +albert5 +yomoma1 +491001 +121099 +12091980 +acer1234 +22101994 +vangogh1 +28061982 +danilova +fubu05 +110977 +mirjam +sugarray +mountain2 +helium +angioletto +090284 +alaska12 +2607 +051279 +s1lver +toyota +singer123 +amruta +nurul +pancho12 +dominguez1 +belinea1 +20101979 +fantacy +sabrina1 +01031995 +chrissy2 +140393 +020881 +enculer +coquelicot +060285 +anthony200 +199219 +1607 +rvd420 +117711 +zion +280781 +020381 +mk123456 +290380 +annie3 +assmonkey1 +jessie5 +pink87 +20101978 +bpvtyf +zhangjian +anjing123 +samreen +miranda +george99 +phoenix5 +chucks +240404 +leonidas1 +121969 +22111981 +scarface69 +15051994 +santos14 +daisy8 +samatron +nigger22 +112123 +missy22 +ethernet +karpov +caramelito +oscar23 +isaiah07 +141978 +15251525 +02111982 +andy23 +traxxas +karate12 +biggy +viktoria1 +cheeba +09111983 +bball101 +orchestra +mazda123 +allmine2 +05081982 +112277 +beerpong1 +justin89 +bohemian +classof2010 +nantes44 +yaya12 +teresa2 +03071993 +22041994 +assault +pusher +alaska123 +wright5 +acer12 +1979pool +vulture +070187 +0206 +stjohn +210779 +azerty00 +caridad +millenium1 +cookie45 +cheesehead +raiders8 +211177 +124421 +evan11 +whatever01 +keri +23081981 +13071981 +mortadelo +150793 +treehugger +tink09 +260478 +black19 +random! +peace4me +meme1234 +daulet +12011980 +20081994 +1318 +170793 +determination +tripod1 +2803 +galinka +siete7 +teamedward +rashawn1 +30011980 +daniel30 +10fingers +20111980 +adam14 +azeqsdwxc +jordy +kak +monimoni +08081979 +redmoon +football48 +zaharov +kenneth3 +newyork1 +keagan +198925 +timeless1 +18061980 +020278 +paige3 +boston13 +anytime1 +02022002 +jacoby1 +060593 +yourock1 +numbnuts +030782 +198629 +yatra +a1234b +stanley123 +marshall12 +twista +2roh8tl433 +greenday4 +gfhfyjz +loveyou6 +machete +220296 +bootcamp +150677 +solcito +jalen +12121975 +140493 +14031993 +shasha123 +sk8erdude +011985 +jaychou +bigdog23 +100476 +caballero1 +srisri +leah12 +june1989 +luciana1 +lorenzo2 +streets +universum +7171 +eagles4 +beatles +luckyy +140203 +gabby10 +oxymoron +9uzp9jek3f +dolphins +160178z +31011994 +babyboy16 +ranch1 +230593 +freepass +godzila +041081 +pilipino +brent123 +081293 +mikejones2 +1357913 +18091993 +vfnehsv +spartan300 +bubby123 +15231523 +barbie8 +walkers +brina1 +26101981 +jackass23 +17101995 +milos +09110911 +xavier23 +060185 +160394 +21051994 +playboy09 +syncmaster +buttermilk +lawnmower +wertyui +blast1 +290493 +goncalo +killas1 +evan12 +sweet07 +02101995 +driftking +marc12 +dolce1 +27081993 +traveler1 +matthew19 +flower16 +fenrir +sumitra +ll123456 +katharine +tiffany8 +261077 +p00pp00p +cdtnkfyf +konichiwa +0207 +198204 +bubba1234 +100196 +sweetness3 +28051980 +maverick1 +besties +basta +burlington +dro +220396 +hater12 +michae1 +02081977 +lowlow +lightblue +26071993 +niceass +moosehead +081283 +kenny3 +fungible +130696 +elixir +totoche +dimaraja +199022 +19071996 +buddy16 +mishanya +vaz2110 +james03 +18101994 +games2 +teaser +kanishka +jake16 +fuckingshit +alayna1 +darkness7 +150394 +mul +casino123 +mother10 +101200 +valentines +2587758 +babyjack +dreamer8 +sexme +dal +mate123 +b123123 +pappa +honda91 +june1982 +lola01 +sleeper1 +zabava +harvey01 +lover33 +sunnyside1 +12051978 +13061981 +tomass +141277 +2thick +bebegim +manjusha +adrian15 +vanessa! +sonic10 +salas831 +dank +xzsawq +james02 +cabaret +froggy5 +frenchfry1 +lovehurts! +joshjosh +triple7 +solomon123 +sandeep1 +mini12 +compaq6720 +djamel +1love1life +champion12 +kingdom123 +abu123 +19031981 +stacy123 +hotti3 +01061994 +02051979 +060584 +olololo +klaipeda +gangsta9 +angels10 +dragonite +sergio +101275 +80808 +bazuka +karla12 +030479 +jaguares +geoff +140679 +dateme +poipoi1 +eadgbe +buddylove1 +musicas +260978 +25041995 +banana. +0302 +papoose1 +tonio1 +roza +sigmachi +mariah13 +myspace91 +281988 +196600 +10271027 +198408 +020980 +blackdeath +utrecht +271177 +kristina12 +220279 +david02 +polochon +04061980 +kx250f +091988 +marie26 +hayden11 +raju123 +fisch +bobby21 +aladino +0p9o8i7u6y +mario01 +farmers +252 +thunderbir +sportster1 +usman123 +010780 +topography +shanda +elmo22 +napolean +05011993 +sidewalk +promise2 +valiente +marcel12 +steffie +sravani +shanker +d2xyw89sxj +bahamut0 +joker10 +swed420 +vagner +01111990 +miranda13 +caspar +honeyhoney +denver +18081980 +16091994 +sonyericson +grocery +marimba +merlot1 +smalls1 +chris2007 +ohsnap1 +john19 +gamestop +redneck101 +like123 +kimberly13 +z1x2c3v4b5n6m7 +marinochka +160292 +05011983 +1yahoo +kolo +furious1 +13051977 +rosey +coondog +aman123 +04081982 +426426 +1248 +madsen +080792 +patrick09 +luansantana +552211 +lecturer +cindylou +kamel +antonio4 +gigi12 +joker420 +1animal +flash2 +stratton +jayjay10 +cardona +190192 +spiderman. +jumanji1 +coolme +30031981 +gemini5 +xiaoqiang +mickey101 +touch1 +reese123 +magistr +yesiam +151294 +jason06 +mama33 +lost4815162342 +nasigoreng +bogey +katie16 +17051980 +december09 +sonic11 +annaliza +281194 +987654321p +161992 +kimberly7 +27101994 +781028 +329210b +kevin19 +sp0ngeb0b +adolfo1 +slipknot10 +300980 +jumeaux +mission2 +cardio +sebast +564564 +08031982 +pass2244 +fuckstick +pumpkin8 +300879 +mark15 +missy10 +surinder +celebrity1 +samsung. +jackie21 +canadiens +kisses13 +070582 +240182 +hubby +jazzmine1 +comet123 +sexi +shadow66 +meatwad +190880 +hell12 +medvedeva +666aaa +25011995 +healing1 +starbucks2 +876543210 +lovinlife1 +12e456 +metallica666 +thunder22 +charmedp3 +fadila +785412 +290392 +08011993 +puppy9 +k1k2k3 +gouranga +griffey1 +serser +03111991 +xpr4bf29ux +dima1987 +adela +padmaja +21071994 +150678 +a1z2e3 +29071982 +1924 +bear2327 +mamateamo +123451234 +31415 +swiss +02051993 +da1234 +a123789 +period +kamilek1 +justice3 +000000l +qwerty1 +froggy3 +sss333 +montez1 +iloveboys! +jeremy07 +ricardo +juliya +texas817 +newboyz +ghzybr +coracao +firewall1 +skate15 +medusa1 +12345678999 +jordie +katerine +sexygirl5 +jenny +1029384756q +210594 +04111985 +28011981 +june2003 +rjgo7we138 +18121995 +calgary1 +801018 +uyqlvip773 +huy123 +joyous +valeria123 +nirvana13 +brooklyn10 +casper23 +lissa1 +30031994 +jeremy08 +shoe +020579 +mykids123 +01011967 +halfpint1 +261292 +max1992 +tomislav +sunglasses +cali22 +timelord +08061984 +sassy69 +naynay12 +toonarmy1 +270191 +nowayjose +guru1234 +1savage +housing +ilovejen1 +kickass123 +140297 +cocky1 +28011994 +kayla06 +balerina +081080 +gardening +killa21 +bigdave +hello08 +040882 +rebekka +dsmvssq955 +life1234 +cuddles123 +elijah05 +computer0 +200978 +1234aaa +eeyore123 +brooklyn4 +moon13 +kristen123 +cubbie +gaysex +25081993 +loveyou69 +bunker1 +gunner01 +safiya +271986 +george08 +seba +renee11 +25632563 +burn +dnflwlq +kal-el +steelers13 +audiq7 +05121981 +25052005 +woshishei +250479 +271295 +smelly123 +handy +198313 +311079 +jess14 +yellow18 +19081980 +gordo12 +11111w +veronica13 +e6pz84qfcj +pinoyako +playboy8 +bffl123 +061294 +cubanito +040983 +15031982 +fofinho +love74 +cameltoe1 +030306 +100177 +14041980 +198688 +azert123 +mur +31121994 +maximus2 +aen: +alpha12 +fucku666 +tomcat14 +star27 +070283 +440022 +steph11 +chelly +mandie1 +teleport +bluebear1 +bassbass +bluejeans +music16 +spaceship +pookiebear +sanchita +godblessus +1234567890. +link11 +02031978 +boricua12 +ranger13 +pachuca1 +070687 +240679 +cdexswzaq +08011985 +791028 +198308 +cutie06 +drummer7 +enzyme +sloneczko1 +12021995 +seashell1 +59595959 +nusrat +js123456 +maxwell11 +danielle09 +600006 +min123 +100377 +purple34 +nino123 +unfaithful +lalo12 +27121993 +040693 +shannon69 +killer56 +14785 +2525775 +crazyfrog1 +13121995 +neville1 +050186 +03111990 +zamboni +cunt12 +060392 +krasavchik +babymomma1 +cutie +041184 +vander +fatboy5 +hello89 +centrino1 +081182 +3stars +ss23081937 +dragonbal1 +beccaboo +amazing! +24252425 +angeline1 +dravid +310893 +12345678a +16041981 +jennifer08 +norfolk1 +candycandy +20071995 +mimi15 +hotmails +14031981 +130180 +251077 +11001001 +mathew123 +w1lliam +icanfly +tempus +colgate1 +ohyeah! +170979 +031080 +apple16 +17101980 +kamari +royal123 +asher +rodolphe +21061995 +23121996 +060386 +amylynn +130877 +aggie +scareface +babyblue3 +stillwater +15021981 +diamond16 +john88 +281990 +20121981 +louann +mememe! +16031982 +icecream10 +31101982 +scubadiver +baobei +patches3 +huckleberry +kbpfdtnf +happy18 +buster00 +meow11 +090384 +edward09 +aniya1 +270380 +mouse3 +111111prof_root3.sql.txt:, +monolith +qwerty000 +tattoo69 +markanthon +feefee1 +junior99 +habib +danny! +phantom +leoncino +anarchia +amazing123 +laura21 +prieto77 +adelina1 +france +abcd11 +seychelles +redhead2 +270280 +emily99 +trustgod1 +guayaquil +firman +bulgaria1 +q8a74ippxd +23111981 +230878 +monster88 +1289 +coolchick +250495 +30111982 +cat111 +zxcvbbvcxz +lucerito +schwanz +kokoloko +pink03 +22111980 +02011993 +robert27 +hartford1 +robbie2 +rascal11 +gianmarco +price +fencing +130694 +what11 +cuban1 +fairfax +hortense +katie8 +112001 +straight1 +25362536 +brenda11 +squeeze +14091982 +vipera +cardiac +qawsedr +pass99 +28031981 +hellya +07081983 +virgola +411030 +toolbox1 +141094 +norcal14 +170395 +david007 +menthol1 +luscious1 +mansfield1 +040780 +secret4 +nikita01 +herminia +221295 +werthvfy +kubus1 +huhu +mallrats +020378 +jack2008 +300480 +emirhan +czarek +henry5 +theater1 +bqktqqn844 +touchme +asdfghjkl;' +bitch05 +dragon32 +champ2 +09111986 +lilly07 +530016 +120474 +petrol +delano1 +1element +170181 +tamarindo +sur1313 +081187 +050980 +drumandbass +oskar123 +67chevelle +teresina +match1 +kokowawa +points +anna2008 +marhaba +devilboy +mylove10 +dirty69 +198213 +040608 +040387 +diamond15 +volvofh12 +2234 +kaligula +290393 +dylans +marvin2 +patrick18 +psycho666 +garret1 +budwiser +antonio8 +sasha1999 +110196 +hgxnewx11 +india@123 +matheus1 +jazzbass +david777 +13081980 +georgia7 +shoaib +june1992 +310194 +checking +rock21 +peugeot307 +amin +daddy24 +imfake1 +1runner +ivanko +number16 +godsgirl +070383 +199121 +31081993 +pizza4 +daydream1 +dillion +concert +270681 +tigger03 +23071980 +samvel +110295 +ast +19061980 +230896 +courtney4 +mai123 +trollface +veterok +xswzaq +tucker10 +310195 +chamber1 +227722 +04121983 +mcfly123 +brooke14 +665566 +100178 +yfnecz +gabby7 +caroline1 +oilers1 +silk +isaac2 +gemini3 +323 +purple0 +diva10 +06121993 +seduction +400400 +dogdogdog +12041996 +vincent1 +barbie09 +12071980 +06041993 +grad09 +wheelchair +0910 +jackson21 +12061996 +salvador13 +righton +miguel3 +09876543210 +amaral +orbita +mylove12345 +hottie33 +lucylou1 +katyakatya +040479 +damir +1211123a +varvar +mk1234 +13051305 +sandara +09031984 +law +080991 +fkkjxrf +anastasija3010 +ridley +samantha09 +pussy24 +nika135 +24051995 +doggydog1 +froggy! +21031981 +redsox18 +271094 +inmaculada +iloveu09 +061278 +mynameiskhan +pulsar150 +04051995 +09121982 +sunshine89 +tyler +chase3 +pippi +alexis18 +sydney99 +mollymoo1 +200101 +23051982 +080489 +cancan1 +valent +130693 +vincent3 +selassie1 +sakura +kyle14 +poooop +281179 +sadie7 +matej +trewq +211179 +jeck23 +071083 +iloveshane +cannonball +marvin +gemma123 +18041993 +asdf1 +clare1 +julieta1 +freewilly +allstar7 +sucker123 +010680 +kaname +kaycee1 +19841012 +dcshoes +3e4r5t +ceramics +183183 +271985 +06061979 +150381 +brian10 +25101980 +tibia123 +goyj2010 +fff111 +salina1 +swamiji + +22051981 +meena +woof +tabaluga +beanhead +sexsex123 +bauer +persempre +elcamino1 +buddy24 +shadi +baxter11 +yvonne +scoobie1 +130179 +070483 +janina1 +matrix22 +passwort123 +09091979 +super9 +ferfer +asdf22 +ppp111 +simple23 +jewell1 +cacaca1 +mychildren +spices +28031994 +janek +sleeping1 +040390 +savage123 +cassie14 +ichiban +madhavan +party! +fake22 +14111411 +sweetp1 +verde1 +louna +newme1 +rattler +sneaker1 +0609 +05021982 +bos +katrina123 +111174 +211295 +280579 +03031977 +monica21 +denise10 +mortis +dodge2500 +chivas19 +pinkstar +maggie33 +mybaby08 +jamaica12 +kaydence1 +alexis24 +domina +12011994 +icehouse1 +amor18 +sucka1 +timileyin +angelidis +241077 +buster55 +oliver23 +29031995 +joedirt1 +laura7 +jayden5 +stacey12 +fuckyou92 +keren +fishies +matrix99 +070882 +joseph06 +eazy-e +peace21 +bitches4 +21101980 +2910 +200908 +money32 +400070 +daniell +261178 +9009 +missyou2 +banana23 +jasmine99 +14071980 +227227 +g-money +jh1234 +a4s5d6 +08071989 +jennifer17 +kexifz +merveille +capricorn2 +jayden4 +10011995 +iiiii +guadalupe2 +123 +aishiteru1 +0407 +27041994 +220377 +joseangel +120375 +cupcake14 +juniors +lalelu +paul +peanut16 +salimata +321789 +mother02 +bluesea +150505 +16031981 +omowunmi +obama2008 +llewellyn +hello666 +1472583691 +nikita13 +mariah3 +otter1 +gato12 +derrick12 +andrew101 +30091994 +joesph +chola13 +khmer1 +travis23 +nikita1996 +alisa123 +bratty1 +babeth +ac123456 +larisa +rocket2 +gage +20121204 +bakekang +bringit +12345ta +woodchuck +15101994 +arsen +pepper07 +angelfish +28111980 +110807 +jordan92 +september21 +2loves +shenmue +cowman +nicholson +ellison +iwonka +ghbrjkbcn +2521 +270579 +07111985 +sizzla +01081995 +michael93 +nonlaso +dog4life +sorokin +seeker1 +trouble12 +marcin123 +15031981 +090292 +weed4me +numlock1 +ramzan +donomar +22021996 +16031994 +sexymama13 +boncuk +frenchfries +aigerim +eyecandy +120576 +meghna +tomate1 +atharva +08111986 +freak101 +cooool +reggie01 +01091982 +230179 +dumbass123 +natalina +ballin69 +rebecca13 +260579 +laura15 +batangas +lj +aurinko +belfast1 +yayaya1 +snoopy8 +samuelito +phoenix11 +lorene +rfvbkf +122100 +vikings11 +omari1 +candybar1 +argentum +orange25 +zebedee +hatter +skate. +dream7 +audrey12 +frqnj0zf5p +hawaii5 +deedee3 +ulysse31 +181093 +hector13 +naruto69 +lydia123 +180493 +610610 +111211 +070485 +babyboy06 +moonspell +hellbound +kayla69 +010809 +3825 +197410 +starshine1 +debby +taylor20 +dodgers2 +560070 +sprocket1 +booboo15 +tino +script +kikito +dragon05 +dkflbvbh +albert11 +aaaaa +ed123456 +omshantiom +qqqaaa +matt101 +3odi14ngxb +251195 +friendofearning$1 +has +pickles7 +faggot2 +gracie06 +170380 +666666666666 +zucker +carlos08 +biskit +iloveme08 +matrix69 +peaches8 +imcool! +123231 +22081994 +orangutan +100994 +090385 +bulletproof +lucas11 +thirty30 +huang +pilar +booo +olimpia1 +sole +10091981 +trewq1 +allstar3 +7things +chaos2 +daisy21 +131992 +alicia +salamsalam +windows95 +blood59 +27101993 +filthy1 +schuyler +strela +stiffy +princesse1 +devon2 +parovoz +telemark +agriculture +31071982 +180480 +anamarie +chilango1 +peapod +party101 +210377 +anacarolina +casey13 +kolovrat +010894 +glory123 +god +shadow44 +monique13 +proute +queen11 +petrenko +jack12345 +asas12 +katie101 +cogito +micorazon +flower99 +travis69 +06111983 +29041980 +megan22 +369123 +fgntrf +total +02041979 +12gage +april02 +blackgirl +crjnbyf +barbie15 +mylove07 +iloveallman +281986 +buster33 +1345 +idon +080706 +bulldog10 +cradle666 +cashmoney3 +przemek1 +ernie123 +bluejays1 +280294 +co2006 +bree +novosibirsk +mike2008 +jason9 +bartok +maggie1 +356356 +fucku8 +20011979 +ilovechad +kupa +14021996 +16031995 +michigan2 +ilovegod12 +i4ifbinfyu +10161016 +beatrice +katrina2 +jennifer16 +tanmay +philip123 +deadspace +30081994 +170195 +surfer12 +iloveyou34 +chivas4 +a99999 +darkdark +sanmarcos +sadako +wipro@123 +falcon +suzy +5times +vacaciones +19861120 +fuckaduck +wallace3 +ihatemylif +ethan04 +tigers8 +coolboy123 +blade3 +holaquetal +dimdim +ajnjuhfabz +137955 +scrapbook +ftrcvh5732 +06111992 +tirupati +interface +mina123 +june1984 +151988 +asad123 +pearls1 +09071989 +alyssa23 +ranger5 +tennis23 +pinkys +11121995 +aenima +paolina +pinklover1 +maggie02 +nafanya +sage123 +captain2 +goonsquad1 +pimp32 +apples13 +verona1 +44 +071281 +rostislav +cancro +nokiae63 +amos +mercedes3 +jesuslord +ksyusha +bermudez +123@abc +sundrop1 +misato +cdtnf +051292 +chris94 +ashok123 +january01 +jose12345 +071985 +wendy12 +granville +diana10 +леночка +281178 +dummies +11091981 +loveme89 +400610 +pilsner +holybible1 +domini +afdjhbn +arnie +biglove +yaorqw12334 +m0ther +1930 +puppy4 +rainey +180782 +disturbed2 +tipsy1 +mosdef +likehouse +030809 +narkoman +gypsy123 +050809 +marcus07 +:lol +capri +27121981 +lelele +gibson2 +29101994 +trevor +tracks +master24 +400026 +deathstar1 +171992 +lorikeet +darkdragon +papers1 +megan14 +storm12 +catracho1 +221077 +denis1998 +pacers31 +jazzer +wewewe1 +ohmygosh +forum1 +1adrian +23071981 +alemanha +coffeecup +12021979 +17031981 +lucia123 +qwer5678 +pinheiro +500017 +principe1 +greenday21 +zebra3 +neelima +brittany. +chelito19 +13061993 +14081981 +020380 +milford1 +ploplo +vlada1206 +181179 +gabriel9 +elrond +03071982 +whiteangel +01081978 +exi +sprint01 +guitarist1 +svetochka +messier +cheer16 +howard +stephanie6 +peace15 +220977 +mermer +monster24 +7777777d +151194 +250195 +30031980 +kasiunia +19111993 +getreal +aol1234 +151276 +091280 +fred13 +fish01 +yfl.irf +wiggins +star1 +12061995 +jimjam +maggie9 +guinness +iloveme10 +yellowbird +booba +managua +130394 +miguel21 +12121997 +godsgift1 +13061980 +soccer56 +bitches7 +281177 +198915 +poolpool +mustang86 +qureshi +tooltime +chatty +411013 +010695 +perritos +loser0 +isabella7 +frankie11 +love213 +mickey77 +1hotmail +yelena +chile +lilmama14 +1q3e5t +cherry17 +rickross +shootingstar +1234567890abc +boomer22 +bintang1 +bubblegum! +220479 +330033 +rebirth1 +puschel +fortytwo +123123t +protected +cable1 +jetski1 +17101993 +arjun +brandonlee +tretre1 +colby123 +14101994 +kittens123 +pollard +giovanni123 +popo1234 +300391 +nikki101 +mirjana +000023 +initiald +viktory +24071983 +hailie +crawling +skater1234 +polaco +makarenko +sunny3 +ambers1 +myemail +061180 +24051980 +astaroth +ace1234 +03071980 +laughing1 +160894 +ghost666 +shovelhead +dirtbikes +nascar17 +steph3 +18071981 +jeffrey12 +21081980 +coolcat12 +thenewozer +gatubela +gladiolus +198517 +29121994 +munchies1 +borrego +anatol +chris91 +boondocks +$hex[687474703a2f2f777777] +17111993 +070583 +computer6 +alex4ever +blinkme +whatnow1 +shotgun2 +konfetina-kis +meesha +nokia12345 +geujdrf +qazwsx3 +barracuda1 +fester1 +79641777070 +nothing7 +xavier10 +lulita +198001 +ferrari1 +15041981 +musicislif +sillyme +110279 +dasher1 +cyecvevhbr +natala +060193 +love121 +killer94 +pus +ganesha1 +nintendo2 +chandler12 +duisburg +scott23 +hunter19 +v00d00 +01071977 +pukimak +sukabumi +bashiru +guitar23 +1a2345 +potato123 +anna1985 +february13 +barbie16 +tralala1 +010409 +pixies1 +juicey +010578 +jack77 +fannie1 +270794 +conner12 +151277 +omgomgomg +mullen1 +professor1 +22111979 +pollos +crowley +daddysgurl +26121980 +mikki1 +pepper101 +afbic +tafadzwa +afreen +050894 +iloveyou87 +madden11 +001971 +pigs +qweasdzxc12 +holdon +iloveashle +070993 +03011983 +wales1 +brandt +quan123 +elsie1 +crapule +birdy +17091981 +judyann +317317 +molly14 +iamsocool1 +washington1 +nnenna +himawari +money4life +surfer2 +654321r +izmir35 +murder187 +21091980 +manojkumar +nadroj +03121982 +mustang200 +mariana12 +230394 +mama1 +k654321 +radiology +com123 +mangos1 +3107 +loveyou +122017 +woaini1 +01011961 +qsefth +thailand +margarita +jimmyboy +221076 +flores123 +jealous1 +12041978 +dragon94 +victoria19 +leet1337 +120796 +pantat +javito +250179 +dannie1 +270693 +jordan28 +papoose +123eee +enrica +summer2012 +maverick2 +fam +desertrose +uruguay1 +121315 +amalie +laura23 +hammer01 +612612 +manuel21 +legaspi +maggie16 +torrance +proutprout +martel +orange20 +delicia +41563445 +sexton +120573 +grandchildren +spencer5 +delacruz1 +500060 +redlion +060583 +nika123 +theanswer +samantha69 +villanova +h4ck3r +killaz1 +21102110 +jesse10 +qwerty26 +fountain1 +130177 +!@#$%^&* +basketba +ru4real +skullcandy +110120130 +1sophie +humanoid +14725 + +140277 +happy2day +unclesam +090891 +qwas +fresh13 +vatoloco13 +pookie5 +05101982 +lover19 +9xx7c8gseb +110699 +rangers01 +ibookg4 +angie01 +jessica27 +tiffany6 +198903 +candy24 +boutique +june2010 +qwerty2009 +tony08 +heccrbq +meerkat +triforce1 +efsane +321478965 +130878 +250478 +armyman +rockstar6 +fordfocus1 +2517 +lablab +070807 +070992 +duke3d +chips123 +122016 +kitty99 +junkmail1 +140878 +soccerboy +omsainath +820919 +hardcore88 +eulalia +26011980 +popov +1q3e5t7u9o +197211 +lakehouse +untitled +pimp89 +tawanda +199321 +spaceship1 +forfun1 +cherise +zxcvbn2m +191193 +bella24 +ghghghgh +whiterabbit +19021994 +orange1234 +21011980 +althea1 +14011982 +stuntman +baseball45 +qwedsa123 +driver8 +imposible +dance07 +180295 +dotdot +cobaka +ladybugs1 +julia +pillar +mikey23 +gabbana +vfrcbv123 +longlegs +06091993 +140577 +mckayla1 +bouba +michael94 +160395 +3007 +ready123 +080187 +14011981 +smokey14 +bunny22 +pussy08 +sur +pouetpouet +rey +assassin +boriska +babaloo +qwerty83 +astra123 +rushmore +01101980 +tranny +bandit600 +hea +161989 +241095 +09111989 +050283 +haynes +gotmilk? +adewale1 +auggie1 +010104 +myfriends1 +02091978 +regency +amitabh +buttplug +rastus +barret +mcintosh +354354 +28031982 +020877 +saphira1 +17011983 +sakura13 +chicklet +101100 +vyjujnjxbt +leoleoleo +112567 +needles +04031983 +ashley91 +211078 +johncena7 +260194 +candycane2 +sheltie +jupiter7 +27051980 +260281 +movement1 +1golfer +411045 +220877 +slapshot1 +angela23 +carinho +myhoney1 +shadow123 +30081993 +petrovna +20051997 +roxy21 +mester +samsung23 +231983 +musa123 +koketka +198209 +scissors1 +surx13 +october09 +richboy +hammie +heaven! +amanda89 +lily01 +pete12 +applemac +taylor94 +giggity +lkjhgfd +cocopuffs1 +150881 +29031982 +rodman91 +dragon85 +supported +lax4life +bloodbath +dfymrf +233391 +tiffany23 +philips123 +123qwezxc +king123456 +jack2007 +fowler1 +manuel3 +yesican +198913 +balzac +babyboy8 +ratfink +remi +melanie3 +21081993 +fantastico +mes +zmodem +classof13 +shrooms +210396 +stars7 +boner69 +31101981 +iluvhim +230777 +hophop +q654321 +beatbox +joanna2 +yeayea +butter22 +march06 +fatjoe1 +blues123 +badgirls +calvin23 +maruja +fgtkmcbyrf +031986 +080487 +ashley96 +06051984 +123321r +17111994 +asdfghjkl3 +misia +scotty2 +trista1 +9000 +y3p32ftrqj +0308 +shrestha +sarahi +ksenya +26101994 +190380 +170182 +starship1 +quinten +130994 +mommy02 +pookie21 +hipolito +supersexy1 +zhangjie +quatro +100277 +010893 +trailblazer +nastya1998 +1willie +19011995 +wee +kulot +mulligan1 +060384 +jeeves +massilia +bootymeat1 +robin2 +vvv +zapata1 +bubba15 +sarahj +1233215 +brooklyn +jman123 +13021996 +shorty06 +121268 +10111979 +30041980 +ggunit1 +justin28 +doherty +011987 +okmijnuhb +dickhead12 +200693 +selfish +2legit +fnaf +v1ctoria +mondeo1 +16061980 +rose18 +160181 +billabong7 +playboy07 +fyfrjylf +liverpool08 +!!!!!! +wicked2 +alvarado1 +testaccount +michelle27 +dell13 +azxcvbnm +234wer +iloveyou1234 +bigbig1 +darrin1 +sexymama3 +cole1234 +dctvghbdtn +337337 +ladybug01 +070692 +wannadupe +serega1 +myspace1! +28111992 +asterisk +somewhere +boubou1 +perpignan +241094 +28041982 +lovely17 +fernando +belladog +killer92 +20052008 +thirty3 +fhntv +11021978 +fuckya +dan12345 +siesta +05081981 +katie23 +010995 +papa01 +bubble! +tina13 +041180 +dakota09 +smile6 +primavara +linkin123 +22031980 +5tgbnhy6 +burbank +ddd111 +loving12 +martin16 +sayank +uk7860loans +140695 +qazws1 +081985 +03081982 +maratik +fuck33 +abhi123 +070385 +06061994 +187211 +a1z2e3r4 +michelle33 +marsbar +melanie1 +15101996 +katie07 +170394 +reanna +31081983 +110576 +qwertys +rjpkjdf +compton13 +fred69 +jazz13 +270395 +leprechaun +150377 +power123 +tolik +lorrie +allalone1 +jumping1 +water! +skeleton1 +halcon +everquest2 +azert1 +hotboys +22061980 +123451234512345 +giorgio1 +08111984 +20051995 +27081983 +190493 +farah123 +111111prof_root2.sql.txt:, +26021983 +260793 +081281 +dewey +vorobey +182blink +plokij1 +22071981 +h0ttie +regret +kristen12 +07860786 +chardonnay +silencer +q12we3 +purple94 +cookies22 +cristhian +gotmoney1 +twister2 +calvin +scoot1 +cabbage95 +32503250 +gemini01 +kobra +esperanca +sprite123 +passworld +dawidek1 +12101976 +16031980 +/.: +arrahman +cabral +isreal +500020 +rianne +05111982 +21041980 +stylist +legal1 +kenji +lauriane +030283 +21061981 +vanita +lemon2 +251096 +nathan69 +280293 +ma123123123 +014014 +payatot +lucky123 +schoolsucks +821016 +021179 +youcef +widder +0607 +haohao +vacuum +muffie +05091994 +++ +123454321a +daniel91 +bluenote +buthead +theband +bogus +dthjybxrf +07111983 +mare +butchy +bigcat1 +teamo18 +shoot1 +mavs41 +mm12345 +071292 +afi123 +juan21 +lovelyn +conker1 +katie21 +jenny6 +terminal1 +angel56 +27071982 +kyle23 +fighting1 +ghblehrb +bsd +edward16 +russ +31071994 +powered +rooster2 +publicidad +chopper12 +k111111 +dfktyjr +080980 +bonilla +17091994 +adam1 +fuckyou +dooley1 +garrett12 +genoveva +770770 +011182 +redboy +121255 +rockyou1 +debbie2 +dany123 +happy55 +second1 +kazakov +dolphin1 +network +blue93 +bigdaddy7 +good11 +chaman +sparky +14411441 +mironov +07121982 +goldie12 +westham123 +240594 +123654z +26011981 +bunny10 +silverfish +01051978 +rehjxrf +punk69 +buffalo +apolo13 +valerka +170280 +bianca13 +leszek +jiggy1 +22221111 +chris30 +hayley12 +ihateher1 +faith23 +19061983 +samhain +mahatma +101068 +cupidon +micky123 +blue2000 +19851120 +jasmine24 +gofuckyourself +ooicu812 +hg +andrea20 +howie +070292 +selfish1 +qwerty84 +200595 +joke123 +babyboy18 +200180 +05101993 +corn +tolani +pillows +sasuke7 +slava123 +minakshi +120908 +10111978 +mmmmmm +playboi1 +16081993 +051984 +170780 +iceman21 +351351 +fazer600 +nj9st4ye3f +fatma +robbin +swati +master33 +vega +jmfxl78phe +13011995 +198029 +cm1234 +denise21 +fukyou +hola123456 +carnell +snoopy101 +womanizer +110976 +elmo23 +naruto07 +chablis +yjdsq +aaliyah01 +14111980 +vodolei +1234567qq +gandakoh +alivia1 +concerto +151990 +micheal23 +201303 +joanna12 +rocky07 +20061993 +4shizzle +hershey123 +mp3mp3 +kiki09 +flute +cheer05 +14081982 +120296 +mamani +linda5 +060383 +andrea88 +matrix007 +hall +eastside02 +babykitty +19041981 +brooklyn71 +24041980 +15011980 +kevin12345 +240295 +andy69 +baby78 +bombay1 +envelope +comment +footie +year2008 +glaiza +130379 +tormoz +mariza +fagg0t +aprils +master. +290480 +kasturi +a111222 +dani11 +04061982 +master08 +fish23 +19091994 +shortys1 +28031992 +squad1 +parish +15101979 +february23 +flower24 +belgrano +miyaka +060284 +mullins +asssss +saviour1 +drizzt1 +30091980 +15161718 +suppandi +alegna +cmpunk1 ++ +king4life +nbvehrf +butterfinger +edward18 +fan123 +rfnfcnhjaf +12041977 +applepie2 +cooldude2 +210994 +solidworks +popo00 +cassie5 +idk1234 +040186 +locomotive +rainbow. +1472583 +110119120 +camila +darren12 +24692469 +peewee3 +joejoe2 +maria09 +020695 +anatomia +0000aaaa +printemps +06061995 +platypus1 +kingdom7 +peter13 +rooney123 +4forever +barcelona1 +mediterraneo +090884 +frasier +07011992 +adam2326 +schlampe1 +esercito +rockstar09 +daniel123 +eddie01 +30061980 +martin18 +deadwood +minimo +13011981 +sexy321 +0liver +bigger1 +bobbi1 +23012301 +1418 +kill1234 +shanny1 +marwin +javier10 +dylan22 +keyword +18081994 +11101980 +000000d +100202 +tty +heaven17 +10101970 +tribunal +gladis +schoolboy1 +14201420 +123kdd +123456789abcde +rafinha +135790a +dessert +ilovekelly +livewire1 +09021993 +sheep123 +08061993 +091984 +letmein. +banana99 +jadawera +monster09 +200994 +turtle10 +flavius +chicago11 +20091995 +fatboyslim +marifer +jarek1 +bonita2 +imabeast +1savannah +mybaby01 +bubbagump +cheetah2 +court123 +footloose +220808 +1internet +kitty77 +skank +policeman1 +commrades +bradley7 +nikka1 +life11 +erik12 +kaliman +change09 +19871010 +7thgrade +westbrook +liljohn1 +flashpoint +calderon1 +pornos +lauren88 +lilly7 +09041983 +13061994 +w2w2w2 +spacey +mark16 +boromir +group1 +trigger2 +280793 +keeley1 +talavera +london1234 +mylove. +1111117 +haddock +1um83z +011186 +javier01 +rachel6 +rundmc +12061994 +21021982 +buster77 +tiffany +restinpeace +vikas +cessna1 +doomdoom +197888 +kotopes +teamo16 +270479 +maryam1 +sevilla1 +ivonne1 +harry13 +shawshank +crystal23 +password100 +tarasov +michi123 +blackjack21 +091082 +noah01 +alice2 +latvia +toots +zoom123 +amber101 +wade123 +fuckoff21 +26061996 +forever07 +1932 +552200 +dancer18 +hallihallo +computer23 +kayla9 +briana123 +14091995 +pimenta +28061994 +trinket +eminem14 +hipopotamo +211079 +blacklight +7fxf3jaa7u +eggs +chocol8 +sonic7 +baller44 +coneja +dianadiana +karadeniz +familylove +takayuki +beaufort +tiger44 +livia +serbia +desirae1 +180781 +planta +snickers1 +кирилл +qwerty1987 +ursula1 +vanness +james111 +felix +leoncito +killer123 +hayate +cnhfyybr +j55555 +518888 +see123 +bonnie10 +joesph1 +28051983 +guessit1 +adebayor +neopets10 +141200 +olarewaju +favourite +mama88 +broomfield +manuel14 +patrick08 +holden01 +04081981 +babydoll69 +daboss +babygirls +lampung +thespian +mecca1 +tami +miguel +5633634 +islam123 +ja8xb7txr8 +brunito +28051982 +justme12 +malinda +050881 +bigtimerus +riverview +lizzy12 +champion2 +wisteria +bangla +lovesyou +lilacs +siddhartha +thechamp1 +superman32 +snook1 +master25 +qwerty7890 +essential +girl1234 +coconuts1 +erikas +zoezoe1 +12041979 +lucatoni +arwen +zaq147 +26121993 +may2000 +denise7 +coolie1 +ass666 +iphone4s +paris10 +22091995 +240880 +booboo08 +stiffler +rajinder +andrea99 +shell123 +jaykay +number88 +triplet +131991 +shamar +credit1 +maganda +31011995 +farmall +frontline1 +balla12 +daffy +papercut1 +280479 +150279 +166166 +mondieu +vasanth +2bfree +15111994 +20041995 +180793 +sonumonu +password75 +olaide +31011981 +nomercy1 +25061980 +2night +scooter8 +24031982 +titanic1912 +mango2 +rayan +derrick123 +220278 +spider10 +nutter1 +241278 +11041979 +slimer +albertina +brenda10 +210893 +erica2 +040495 +plants1 +esteem +kittiwake +chula13 +jake24 +yogita +tintin +turtles2 +reinhard +okmnji +luda +wowowee +victory +ncstate1 +03051980 +titititi +joojoo +198906 +coolkid2 +porsiempre +master8 +pink28 +xingxing +tucker13 +02031977 +100976 +dallas4 +lm292979 +butthead12 +080981 +210878 +jonathan9 +abc-123 +dorotka +totito +rusty7 +racecars +airmax95 +golfr32 +parkway +14051405 +johnwayne1 +05011992 +jessica87 +yakamoz +hope22 +09071983 +////// +hulkhogan +minister1 +leslie01 +ja123456 +obvious1 +compaq3 +18031994 +retype +canucks1 +080285 +696 +lambchop1 +291986 +natanael +080908 +tigger20 +sorcerer +3211 +leomessi10 +mike007 +redsky +matt08 +barclays +goaway! +emma2004 +080682 +lal +nana21 +daddie +600015 +thug12 +06031994 +silly12 +vishal123 +sunder +badboy08 +fillmore +chalet +paintball9 +josh06 +sabre +keneth +tiffany14 +longwood +12271227 +vaz2114 +longlive +210578 +versatile +bakabaka +superman89 +schnauzer +keith2 +gracie7 +010103 +sarahm +1horses +kelsey3 +grisette +blueman1 +biteme13 +mamka +cupcake8 +jackster +maldita1 +rick12 +31071981 +15021980 +jessica02 +301279 +123454321q +blood15 +waterman1 +197070 +lovelove +filles +diggler +auto123 +nana16 +scooby +squeak1 +05121982 +giovanny +cody17 +bridgett +fvcnthlfv +lalala5 +arsenal23 +31011982 +masterman +lacrosse7 +crf450r +celtic01 +18061982 +tigger44 +kostroma +14101996 +dutches1 +elijah +doodle123 +15061980 +060580 +cancer12 +o0o0o0o0 +05091981 +090383 +nacional10 +cheese99 +200995 +270881 +church12 +19841024 +manson6 +roxy23 +joshua26 +olivia04 +sasiska +chris96 +fucklove7 +homer12 +dvd123 +21111982 +february21 +555aaa +renato1 +angel1994 +123698745a +060481 +q1a1z1 +jamest +jenya +whale1 +22061995 +february22 +scooter9 +n2deep +playa13 +snapshot +wer234 +love123 +amigas1 +protector +hampster1 +makarena +tulane +237237 +protoss1 +danser +batman89 +airmax1 +loser07 +kendra12 +011001 +daisy08 +princy +speranta +031983 +lindalinda +carol12 +montero1 +29061982 +nar +yanis +bitches5 +06081993 +2134 +masakra +patr1ck +john55 +potter2 +stthomas +scammer +hunter95 +guest1 +kelly23 +pedro13 +09101992 +ben101 +march123 +qwerty79 +balbes +08071982 +150977 +july1989 +sasha21 +lacrimosa1 +08111985 +wqwqwq +intrigue +1597532 +street2 +oogabooga +nathan24 +icecream. +lakshmi1 +devastator +graveyard +chris007 +austin17 +55555m +23041994 +061193 +04011984 +010169 +09123456789 +giulia1 +travis10 +030284 +toggle +spooner1 +drumset +himitsu +bnm +071280 +16091993 +lookingforlove +nunu123 +abella +praisegod1 +christina9 +1080 +electrician +11041996 +gunit5 +yusuf123 +pussyy +socom1 +yesman +taytay3 +taylor25 +24061981 +1441 +gatt +martin15 +metal69 +30051980 +toymachine +pennies +molly1 +cattle1 +founder +zulu +23021979 +1dipset +ou812ou812 +181985 +tigger19 +theking23 +goodie1 +30051994 +trezeguet +19021980 +sydney13 +marie94 +demond1 +gazeta +040684 +campion +08101993 +german123 +2481632 +121195 +kissy1 +mokong +panache +biscotto +perfume1 +bassam +u +storm2 +arnie1 +198905 +120976 +casey5 +snickers5 +08121983 +mima123 +123456: +08051983 +21081995 +caboverde +26121981 +1a1a1a1a1a +motorrad +dominga +hello100 +bradley1 +ra66it +whiteman +oscar14 +maryana +220179 +stjude +123rty +123456asdfgh +capsule +ltybc +handbag +asdqwe12 +fresca +amistad1 +treble99 +cute21 +speedo1 +dave11 +28121981 +thompson +master45 +251989 +271195 +170294 +langston +pwd +indiglo +cologne +050193 +love72 +pretty101 +codydog1 +queen5 +lastchance +360modena +22071980 +hockey29 +123you +keepit100 +sequoia1 +cnhjbntkm +manny2 +cs123456 +yumiko +vivemoi +mckinley1 +cracovia +110477 +070580 +murdock1 +12345678bj +cheerful +1199 +rohan123 +fuckme23 +50cent50 +06061993 +madisyn1 +people. +091281 +01041978 +kathie +fackyou +142 +evilone +connor08 +sassy22 +m00nlight +viking +ginger77 +8484 +07021980 +080684 + + +pigdog +babybird +150594 +lowes48 +221002 +dolphin22 +30091981 +bumhole +jujitsu +empty +bobbyjoe +nigger23 +31071980 +dbnzyxbr +10041995 +lynn21 +131993 +saints2 +250977 +sanket +kristall +profit1 +kaczka +bigdad +zsxdcfvg +daniel86 +muhaha +married07 +251992 +zero0000 +02041994 +05051975 +190981 +karena +famous7 +realdeal1 +villamor +nigga9 +nyasha +tanner3 +blowjobs +babydoll3 +16041994 +1234500 +iloveyoufo +sakura11 +stupidbitc +molly8 +305miami +crunchy1 +090483 +bellydance +07101993 +04041979 +16081982 +190781 +1lovebug +goodguy1 +09031993 +1234567812345678 +20121207 +covenant1 +downunder +bball30 +03111985 +200594 +cashcash +dustin11 +truelove12 +breitling +kamini +221275 +brewer1 +monster15 +snickers11 +160180 +ximena1 +wonders +lkjhgf1 +411018 +e65r82mnj2 +111078 +toosweet +coco101 +snowfall +landon12 +bonzo1 +funtimes1 +327327 +21041995 +orlando! +123abc. +23051981 +render +chachou +chapter1 +cyprus1 +westside10 +07111989 +lakers#1 +13111980 +200396 +07081993 +123456789zxcvbnm +houria +james28 +bailarina +190595 +michelle05 +121212121212 +cr250r +060879 +151991 +golf01 +081108 +destiny05 +26031981 +16081980 +ilovemicha +nano123 +burak123 +chante1 +lun +198429 +dazzle1 +ghbjhbntn +zachary4 +sierra7 +annalyn +19121978 +baranova +19111982 +28041980 +isaiah06 +goomba +banana4 +1scorpio +rafael +angel1996 +bukkake +junior! +09031981 +joker01 +panathinaikos +alouette +lupita123 +160595 +domino +261984 +06062006 +chivas8 +orange18 +fkm +mesha1 +psalm119 +swaminarayan +jamesc +242242 +12191219 +600100 +obama2009 +chosenone +vanessa1 +da1andonly +200193 +280695 +password80 +masood +julia10 +popcorn23 +molly9 +conair +saints09 +mylastfm +consuelo1 +k.ljxrf +wicked12 +nephew +mexico101 +18071982 +dixie12 +spoons1 +xt +misterx +241990 +joint +tamtam1 +knitter +koolaid2 +evgeniy +rinoceronte +overtime +200877 +4554 +tamila +christ2 +fuckyou27 +marie03 +brice +ilove... +nfnmzyrf +abbydog +chester4 +dethklok +141994 +mastiff +star06 +071081 +198827 +sandy4 +desiderio +thunder10 +canibal +papasmurf1 +mahusay +140478 +catherine +27081984 +wabbit +grad2008 +hommer +010395 +davide1 +onspeed +15091981 +11071980 +pandapanda +prajakta +omar11 +dr4g0n +happy17 +15081993 +slovenija +angel911 +рїсђрёрірµс‚ +wumeiyun123 +jag123 +comanche1 +060184 +210778 +aliona +saltlake +210280 +xray +asshole1 +fender5 +09051982 +levi123 +lilman13 +ritchie1 +playboy08 +akinto +purple92 +18071980 +ch1234 +daisy23 +fishing3 +jesse21 +0102030 +grace17 +brooke23 +141295 +261989 +bby123 +22041996 +15091994 +31071993 +ashes +3l3phant +18061981 +ginger88 +ujkjdf +220379 +ruslan009 +samantha07 +makavelli +neznam +biabia +bitch100 +72chevelle +muhtar +021093 +fuckyou55 +imafag1 +17081981 +231196 +mitchell2 +1american +bvb1909 +linette +farmboy1 +scrappy123 +jamajka +090186 +tiana +555151asd +ilove15 +passwd1 +angelika +091989 +nightfire +martinha +ravi1234 +198806 +sasha15 +dennis10 +06081980 +taryn1 +wethebest1 +rollercoaster +260694 +danielle18 +super! +17041981 +tink21 +vaz2108 +poptart2 +playboi +muschi1 +promo1 +snowball11 +md2020 +elaine123 +131193 +040593 +anthrax1 +08011989 +tomtom12 +09041980 +private2 +sigaretta +linkedin1 +dharma1 +okiedokie +walter01 +cancer22 +wolfteam +090994 +culo +070907 +asdfghjkl5 +febuary +karencita +steve11 +turntable +16101995 +sexxi1 +040581 +andrew89 +011187 +16051995 +qazw21123 +isabella5 +19121981 +zahara +broncos07 +29021980 +stringer +080692 +1greenday +jake09 +guitar666 +zzxxccvv +290793 +victoria9 +mataji +iloveme9 +hifive +drums123 +091181 +scooter69 +raksha +30031979 +steelers06 +getpaid +hello777 +qwas123 +andrew28 +ferrari355 +bigdaddy +ghjuhtcc +1437 +09041993 +300777 +playboy9 +myspace29 +xbox3600 +290595 +sab123 +leonhart +maiale +anna2002 +asdert +samba1 +algernon +pimp19 +27061982 +werty7 +bunny23 +260896 +5bhc2v875z +flashy1 +pieisgood +saibaba123 +qwertytrewq +pilot123 +120399 +oldtimer +090995 +lochness +shanae1 +rea +veracruz1 +avanesov +spanky01 +69bitch +asdf +cretino +scrumpy +weed22 +17011995 +dylan08 +24061994 +8x2h4eddan +iloveporn +270595 +bulldog69 +28051993 +libellula +america08 +crystal22 +600002 +411015 +123456zxcvbn +jupiter +johnny14 +240394 +gohabsgo +invu4uraqt +1thing +302017 +martina +jamezerazz +murtaza +mary14 +27081982 +238238 +nixon +mustang5.0 +nightjar +lindsey123 +prowler1 +morgan16 +jacob04 +welcome8 +mommy33 +in2deep +xyz789 +rayray11 +beachboy +finest +michael98 +deuce +nerd123 +hershey12 +max2006 +newlife3 +160676 +jabba1 +underwood1 +palacio +20212021 +140794 +kubicek +19831010 +opeyemi1 +aa12345678 +see +ihatemylife +181986 +bay123 +garnett5 +garcia +juan18 +johncena23 +bobby1234 +140278 +monkey007 +philippa +cowgirl2 +lulubell +felton +qwertyz +linwood +654321c +karlson +vanessa9 +gabby3 +01111983 +14561456 +thornton1 +narcis +scotts +romantika +0174426 +080893 +palma +28101994 +sarajane +nurbek +alyssa6 +19888891 +super22 +69dude +selfmade +knuddel +linden1 +media123 +jogabonito +femme +bonny1 +130478 +carlinha +echoes +bubble5 +syyrrqbe70 +cultura +15081995 +10081995 +300183 +jasonlee +lauren06 +arsenal07 +090285 +lindau +unicorn123 +defcon1 +julietta +savitri +myspace#1 +voodoo2 +150294 +juicebox1 +rajini +lindona +myspace199 +lockheed +liv +13551355 +abcdef. +198026 +vodka123 +dude21 +fuck-off +gulmira +240294 +tree1234 +639374 +airbus380 +0810 +damian2 +271294 +gloria +masseffect +favoured +tigercat1 +pizza22 +sasha1992 +kursant +020594 +bagel1 +vixen1 +qwe058058a +ragini +sandeep123 +snake3 +fatboy7 +29061994 +111119 +raylewis52 +pokemon100 +003003 +jasper5 +babi12 +sexii123 +marinette +bonus +1234 +140777 +3pointer +1470 +grandkids7 +masana +breana1 +fortunate +010895 +anusia +210795 +foxy12 +0321654987 +erikerik +111222333444555 +manga123 +ioana +fishing101 +rayban +perfect123 +akhtar +19091981 +celular1 +231096 +loveumom +15081994 +albacete +energystar +199797 +renee22 +28011982 +luvya2 +26071994 +070684 +26021981 +ilovejessi +sergio2 +lastborn +moritz1 +131292 +24091982 +stevenash1 +7142128 +cheeze1 +babygal +barbarossa +us4ever +23091980 +22132213 +rafael10 +genius +alanalan +cody23 +blahkg321 +tyty123 +199417 +chris31 +cinque +26111993 +orwell1984 +g12345678 +zk.,k.nt,z +livelove +bdfyjdbx +babycute +281991 +babys1 +160694 +fuckbitch1 +tassadar +171094 +secret99 +250694 +klondike1 +melanie +psalm121 +09011983 +isabella01 +holly01 +zombie69 +11051980 +69pussy +mark08 +james04 +198020 +dulce123 +diesel +bethann +myprincess +31101995 +berry12 +jojo16 +19111911 +monkey90 +020277 +noumea +140200 +080983 +pimp05 +letitia +missionary +madison21 +summer1 +mets123 +toocute +olivia09 +12345678x +hannes1 +281078 +1phoenix +3579 +11101981 +machupichu +freetown +198788 +blue31 +eating +27091982 +alamierda +ivan2010 +goodwoman +bulldogs3 +13031995 +famous5 +kelly6 +gangstah +honey17 +23021996 +19861225 +voices +16101980 +anjelika +231094 +mickey88 +models1 +major123 +15261526 +kaila1 +kenzie11 +380006 +27021983 +molly23 +301001 +l1v3rp00l +boss23 +sydney7 +19841016 +19101995 +omg1234 +09051981 +080582 +seabass1 +susieq1 +softball06 +2r97xj3xex +connor04 +19051979 +sunshine66 +billybob12 +ajtajt +consulting +meme22 +25071982 +music +170180 +030580 +eoce59cl9u +dragon98 +brooke07 +111967 +834002 +190680 +2702 +broken! +thatsit +teacher123 +21011981 +usman +27031982 +3345678 +200279 +depression +25212521 +chancho +tecumseh +dance09 +jag +horse11 +dekalb +cybernet +edu123 +250377 +carter10 +tracie1 +abs123 +sophie06 +bird12 +100696 +herbie53 +123jkl +03071981 +stephany1 +givenchy +bobsmith +naruto100 +khan786 +sym_cskill1 +sydney2000 +hotpink2 +smiles12 +corazon123 +lilwayne11 +180001 +dakota02 +sue +hailey05 +melendez +samsung8 +vane123 +babilon +150895 +q1w2e3r4t5y6u7i8o9 +eduardo10 +cj123456 +devilman1 +bogdan1 +oralsex +serenity12 +thurman +raven5 +sex123456 +jordi +candygirl2 +computer21 +kosher +montana3 +23011983 +informatique +agent0 +magicaroma +1250 +jamari +vitamin1 +19011994 +bodyboard +06111989 +hailey07 +judson +hunter97 +2809 +ilovematt2 +dodgers99 +redouane +ilovejess +topnotch +hollywood6 +salmo91 +covert +usa1776 +grapeape +how +jak123 +qqqqq11111 +freddie2 +ricardo13 +alina2010 +121010 +grandmaster +tommy23 +1590753 +1986123 +qwerty888 +arcenciel +dance14 +yamaha7 +manuel15 +27041995 +23121995 +alexsandra +190792 +santiago2 +babygurl6 +schatz +21051996 +dasha1998 +15051979 +пїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕ +flanagan +my +chance7 +cameron22 +elaine12 +909 +sasha1991 +oooo0000 +boyzone +28101980 +brandy69 +karkar +88888a +fluffy22 +219219 +411044 +198704 +170495 +198902 +sorry123 +240395 +stapler1 +miska +gr8one +ranran +moocow2 +hello1234 +lakshya +time2play +chevy03 +chikis +sb1234 +4f51eijvif +hennie +claire01 +daddycool +evelyn12 +spade1 +iop123 +pakistan2 +stars11 +225577 +22081993 +05091993 +azkaban +aprilfool +victor14 +latasha +20121995 +andrea06 +whatever +13051981 +layouts. +28071981 +article456 +11091979 +556556 +west23 +jenny4 +100800 +luv2sing +191080 +300780 +char +salade +charlie77 +hotline1 +gandalf1 +kalani1 +sh1thead +080282 +080392 +090492 +snitch +26061994 +playball1 +zerkalo +dawgs +soloman +mario21 +270880 +browny1 +euamojesus +130477 +27101981 +katharina +maharaj +freitas +flatron +kasey123 +mikes1 +ortiz +spooks +221171 +1brenda +123456po +lineman1 +vika1998 +061279 +lainey +147456 +090582 +16071981 +total1 +eclipse3 +2709 +020593 +spo +07081980 +200293 +teamo5 +thelord1 +sheree1 +silver4 +batman16 +gtivr6 +buzzy1 +030378 +leroy123 +shah +juanluis +strokes1 +1chopper +jamais +rudenko +barbie9 +limonade +19977991 +051278 +phones1 +21061980 +bennet +kaylee3 +kianna1 +030593 +1doggy +silver8 +rockstar08 +hotshots +190578 +20121978 +040580 +3113 +sarah09 +austin512 +lawliet +ranger21 +stratovarius +pappa1 +dindon +spania +asdewq123 +150179 + +tambok +molly21 +010481 +tiger100 +bacolod +091986 +freya +moe +sweett +goodpussy1 +261078 +hellgate +reiner +121968 +logans +ruby01 +flyaway1 +030192 +turtle23 +perros1 +bella2008 +blacksun +17061994 +loveme19 +18111981 +roofing +baritone1 +jaycee1 +310894 +14091981 +partyof5 +srinivasan +videogame1 +kitty88 +222222222222 +030694 +justinlove +tia +123pink +gone +richard9 +antonio15 +student +07071995 +070881 +086421 +love1god +zenith1 +03121980 +airbus320 +pax123 +sweater +love80 +140779 +hades +14041995 +654987321 +sticker +michiko +wii123 +barney +hallombn001 +1patches +01092007 +vergil +lbvekmrf +campana +idspispopd +231295 +candice123 +franklin12 +300793 +060881 +microlad +legend12 +minkia +charlie25 +meangirls1 +160979 +26071982 +18091983 +401105 +10081978 +denver123 +sierra10 +11111j +levent +littled1 +sarasa +1232580 +1bella +rossonero +230378 +ulises1 +1bigfish +4097870 +black45 +green12345 +india1947 +april03 +hannah19 +03051995 +rhtdtlrj +cjdthitycndj +goodmother +blackfoot +stocazzo +assmunch +bruno10 +cute09 +korolev +murano +0309 +fresh5 +251295 +4evermore +music24 +roslyn +191180 +090887 +grahm +dallas33 +bibiana +dfasnewa +bigboy09 +1natalie +andreyka +123211 +123045 +sunset123 +mary21 +joseph02 +kalle1 +04101982 +bikers1 +jessem +165432 +100402 +007james +michelle28 +141990 +asdfgh5 +keke13 +260893 +16081994 +sexy96 +takeda +under0ath +studly1 +sugar10 +1597532684 +capricho +biochem +ramesh123 +nicotine +cimbombom +302015 +121110 +brandy22 +obituary +segura +1821 +dragonheart +gunner +jasper! +emmanuel2 +roxydog1 +reynaldo1 +power9 +30091993 +01111984 +takataka +010993 +sopranos1 +regis +schastie +02121994 +tiffany69 +julian07 +gabriel06 +mikes +neguinha +mvp123 +joshy +roadstar +spots +sarala +14031982 +proverka +scott01 +brittany69 +19841023 +12342234 +barrios +eagles14 +pollution +bleble +pete379 +ixrhx2xc87 +quovadis +toomuch1 +151992 +gunner2 +5959 +ingenieria +10121997 +1234567qwerty +19851230 +500049 +wildlife1 +vikings +03061981 +tilley +gthtcnhjqrf +wilcox +serdce +123312 +19841021 +pankaj123 +westpoint +windowsxp1 +nike15 +260578 +02061977 +07111990 +phone12 +20091980 +popcorn9 +stars3 +cb123456 +camilo123 +justine +surrey +oli123 +160380 +11081980 +taylor19 +060809 +awesome4 +21052105 +peterpeter +25091980 +twocats +jelly12 +levente +ronaldo11 +jamesh +airbusa380 +200478 +241194 +sat123 +casada +florentino +af123456 +13111311 +focus123 +superdog1 +280594 +sladkaya +cdj: +sexy!! +bolinhas +12081995 +elvislives +fukyou1 +devante +010980 +mason11 +swanlake +tootie2 +1knight +stuttgart1 +raymonde +jesse4 +tab123 +microsoft2 +icecream123 +charlie04 +lagrange +171980 +lisa21 +jollyroger +121100 +trompette +shaney +candy07 +290882 +dranzer +jamshedpur +kumar1989 +300781 +150578 +1525 +30091982 +phenom +windowsvista +annarella +slniecko +toothpick +grapevine +11081995 +kendall2 +wedding07 +cheng +pit +skate08 +pats12 +stefancelmare +sarah9 +240577 +bff4eva +280779 +zsxdcfv +browncow +dresden1 +fishfish1 +louise! +lauren9 +28021982 +alexsander +190593 +haihai +101003 +jaramillo +03051981 +sempron +230977 +200695 +winter13 +lexusis300 +kickboxer +makayla3 +122333444455555 +nenalinda +speedtouch +disney08 +71717171 +199021 +010879 +peter7 +stockings +corvette2 +blazing +carolina7 +flo123 +13121996 +ildiko +karen11 +1stclass +hehe12 +sossina +sharona +hay123 +robots1 +laruku +portocala +2babygirls +sparky! +cooki3 +girls5 +goodnight1 +tarnay1 +noah1234 +240193 +ahojky +tardis1 +trompete +210777 +simone +gallegos +081986 +aa3030316 +sahil +130777 +gracie10 +lampara +06101993 +airedale +222www +140379 +rodel +offroad1 +mannie1 +04031994 +filbert +121245 +toratora +retard12 +aa12345 +drachen +041985 +jerkin +loveme25 +natalie! +soufiane +25031981 +goon4life +chicken0 +pinkey1 +rangers94 +08011984 +09120912 +heroine +ford99 +t1ffany +11031995 +vijaykumar +pramila +srirama +1q2w3e4r5t6y7u8 +squash1 +marek123 +110276 +honeys1 +dreamer3 +puppyluv1 +241195 +nesakysiu +jenica +augustus1 +chevy06 +booboo99 +280382 +170980 +daisy1234 +230478 +040595 +goldsmith +rigoberto +warior +700020 +96impala +abricot +lorelai +iluvu4eva +04011983 +felicidad1 +kisses5 +borntowin +070778 +sexgod1 +100475 +manutd12 +andres10 +040981 +superdude1 +grandma8 +bitchez1 +00000000001 +06021983 +frankie01 +100575 +thrash +plover +cristina12 +dare123 +slippers1 +25232523 +ricochet +matthew20 +011293 +261990 +1122333 +slowpoke +rfvtgbyhn +oops +041982 +xyq7xcewqk +161983 +261988 +denver12 +10point +chunk1 +28041981 +nissan2 +1234567890o +25091995 +nikita2000 +blessed123 +jamilah +juancito +chronos +july1991 +bourbon1 +deuseamor +job314 +casa12 +cerf +030880 +211989 +iamsam +160593 +sammy06 +ilovelisa1 +marlou +hockey91 +masamasa +kuku +ilovemegan +sofie +freak13 +parisparis +251076 +061984 +orleans1 +michelle26 +08021982 +wasd +08101982 +bigdick123 +020879 +gramma1 +19441944 +06111991 +2520 +714714 +l0v3m3 +amiga1 +987654q +1ballin +nerd +110054 +lucretia +cocoloco1 +misty11 +shannon4 +pugsly +bubbie1 +raymon +071080 +flames12 +becky2 +xiaowei +baby30 +password74 +041080 +oneluv1 +hockey07 +colony +music000 +jb12345 +porsha +199615 +cockroach +400008 +140977 +121500 +klo123 +maggie03 +hassan12 +mysp@ce +chloe05 +30101981 +jackbauer +101007 +raven3 +volcom22 +cuteness +ariel12 +brethart +halcyon +171982 +03041981 +gabbiano +222233 +070683 +25111994 +merlin69 +tunde +isaac12 +jasonx +abc234 +loverman1 +120012 +1478963258 +gaby13 +apples23 +sweetie13 +truelove! +slonce +jessie4 +sweety11 +sweetie4 +290576 +vulcan1 +naufal +090792 +relationship +vfvecz +dope123 +whistle +18211821 +c0mput3r +yeayea1 +december06 +colours +ashly +tampan +jenny17 +020305 +301294 +july1993 +livelaughlove +newshoes +300678 +qwaszx11 +madlen +fizzle1 +100294 +veverka +m3xico +sammie11 +5555555tl +050678 +penny01 +110396 +290980 +motion1 +090883 +forget2 +basil123 +05091980 +pazeamor +bell12 +homesweethome +2442 +ray1234 +250894 +brittany08 +180979 +ds1234 +rhyzza +ferrara +recruitment +hooker2 +purple32 +alyssa +192837465a +gabby01 +daniel29 +broncos +newlife12 +poypoy +gladbach +cagiva +cleo12 +190980 +09061993 +mateo123 +melly +gumdrop1 +oviedo +28041995 +090291 +dublin16 +penthouse +04031984 +jacob101 +cortex +08071984 +wrestling3 +rachel4 +manmanman +liu123456 +lonely2 +ike02banaa +kamikazee +austin18 +thomson1 +080484 +social12 +020184 +senior2009 +omegas +lala09 +09121989 +sasuke14 +travon1 +140678 +18021981 +benjamin5 +12345678as +24021995 +mykids02 +041986 +cross123 +coquin +re-enter +picchio +bulldawg +yfdbufnjh +emily +arbeit +ginger15 +brandi123 +musa123456 +cshrc +school23 +redskins2 +100900 +roofer1 +818818 +10051979 +connie123 +lickit1 +tucker3 +118720 +lilmama10 +250494 +cheer21 +codycody +09071981 +poohbear22 +08081995 +11071979 +chelsea17 +junior04 +ltr450 +summer20 +jgordon24 +sourav +888444 +owned123 +21002100 +27071980 +mahal +bushido +honda02 +caliban +uraura +400089 +fischer1 +128 +z1x2c3v4b5n6 +saprissa +wife +tennis5 +samm +danielle9 +liberal +090580 +buckethead +30041994 +010781 +google01 +londoner +21051979 +nose123 +tevin1 +slayer! +070184 +198414 +alyssa21 +blythe +05111989 +zsexdr +rocker13 +26061981 +dorine +ertyui +soloyo1 +annie01 +pimp34 +nikolaevna +15011981 +walther +palawan +112233s +98766789 +pooch +shadow95 +heather6 +17101979 +poopey1 +kayla8 +kanabis +hellogoodbye +animale +mama25 +tiger20 +tender1 +lovemenow +1victor +dragon56 +worthy +bradly +aiden07 +reaper12 +bilal123 +ilovehim08 +dorsey +sheraton +shaine +marlboro20 +16021980 +2wsx +giants12 +ventilador +beautiful +michelle89 +ginger16 +goodgood1 +aim123 +felony +301277 +cruzazul10 +ivan1991 +252252 +db1234 +holla! +montella +callie2 +savannah11 +demeter +211200 +decembrie +ilove24 +perras +221175 +chinatown1 +a999999999 +pebbles3 +atelier +genius12 +michael95 +sonnyboy1 +peace08 +babyjay +050383 +gudrun +251991 +080791 +19821010 +monkey76 +rednaxela +roulette +tanzen +fam1ly +dennis13 +herring +marseille +travieso1 +fartman +06121992 +1spider +razorblade +kimora1 +18091980 +z23456 +ruby22 +m123098 +emma05 +marcus7 +03031978 +outdoors +greener +javi123 +shorty25 +isabel +31031994 +semsenha +teacup1 +sexybitch9 +holley1 +samiksha +gateway1 +ktnj2010 +.kmxbr +123212321 +lakilaki +genesis01 +newyork +neighbor +140395 +20021979 +ghislain +06091982 +140000 +125412 +211077 +100875 +samantha17 +larded +callie01 +01031977 +kaya +monkmonk +gracie4 +gabriele1 +lucas22 +careful +k11111 +emiliana +alexito +amber09 +benedetto +02061994 +27121995 +travelpack1 +malakai1 +03110311 +111111p +tkachenko +score +brosb4hoes +gucci12 +gamboa +nocturne +teacher3 +759123asd +sing12 +andy10 +kinglove1 +jesica1 +cooler12 +ilovesara +vida +fupyuxta66 +bailey03 +flint +blackops1 +aikman8 +joseph20 +carolina13 +redheads +cookies101 +mazatlan +complex1 +bunny! +13011994 +aaron08 +14011994 +tyler18 +teentitans +israel12 +simbad +meltem +301077 +maryellen +brittany09 +sandrina +loser24 +claudi +jesus99 +456852a +santiago +16081981 +31101994 +05041994 +banjaluka +alessio1 +ovechkin +smalll +silver25 +freelife +hoosiers1 +matth3w +twilight23 +desi +nastya1996 +corrine1 +znirpnl744 +080185 +adana01 +nissan01 +bun +monica14 +kattie +031279 +19011981 +25121978 +444111 +charles13 +02071977 +arshavin23 +130795 +asdf1234 +zombie12 +hope13 +cr +jesaispas +amber1234 +rajan +240595 +lovely25 +080485 +xavier +240179 +291987 +detroit2 +карина +dpetrucco2 +1qaz2wsx +roflrofl +star2000 +h12345678 +daisy1 +rocky9 +1gemini +laureen +marcoantonio +500600 +single7 +sexy35 +loveyou09 +lol1 +aliya +girls101 +jeremiah3 +blackadder +kinshasa +abdoulaye +tuesday2 +1qaz2wsx3edc4rfv5tgb +flight23 +kleenex1 +asmodeus +123.456 +147963258 +020994 +280980 +120600 +iiiiiiii +10091009 +tecate +130395 +april2007 +310594 +160978 +briana2 +09071982 +maksat +britney123 +marcello1 +bubbles24 +simon01 +lucky06 +011291 +erenity +monster0 +villalobos +03111992 +28121995 +190181 +11091980 +141194 +0123698745 +2701 +vanitha +phoenix +morocco1 +ricky11 +animax +myschool +monkey321 +fedex1 +148814 +karina10 +120108 +babou +150794 +03041994 +18051995 +wiseman1 +crazylady +y6p68ftrqj +pumpkin01 +samanta1 +blondie13 +trustingod +flowers11 +truffles1 +awesome. +apoorva +ff123456 +8933959 +natasha7 +123321as +weedhead +thumbs +troll123 +050577 +52xmax +ramayana +bailey15 +199015 +vision123 +amp123 +marley +rosine +lucky111 +aikido1 +vulcano +1jacob +061986 +doug123 +08061982 +cinghiale +nickjonas2 +love214 +dipset7 +merlin2 +deonte1 +tunes +lolo99 +trader1 +random11 +holdem +jimmyd +170881 +600037 +arfarf +lesbian2 +rabbit +korina +06061996 +fuerte +honest3 +johnnyboy1 +mozilla1 +annie11 +njhyflj +14051980 +101196 +0502 +hello!! +i98xb7sxr7 +jetbalance +snoopy88 +17121995 +nathen1 +boobs12 +lucylu1 +100496 +020809 +flavor1 +666666k +scooby6 +180580 +160780 +25282528 +x2x2x2 +volvoxc90 +kartoffel +slavia +thrice1 +19081994 +110695 +020793 +200977 +welcome10 +ping +beagles +jakey +e65r82mpj2 +delosreyes +doeboy1 +charlotte7 +chrystal1 +sean13 +docent +pink91 +moneybag +19811982 +chinonso +lokaloka +17121979 +topina +zxcvbnmasd +rugby15 +george07 +10711071 +180494 +lovekids +noahsark +babyblue7 +watup1 +maggie. +people22 +23061995 +lera123 +passward1 +botbot +lianna +1515151515 +19861025 +6feetunder +eeeee1 +4xebxr653d +121967 +newgame9 +isabella10 +arsenal13 +hahalol +pickwick +klimenko +pokemon15 +sla +james32 +correa +cheating +breton +bonzo +tiger1 +deerslayer +skate666 +henson +money89 +animales +dicky +29111993 +zoology +260995 +americas +puto123 +joker4 +xpeygeh934 +meme23 +hocuspocus +150479 +socute +summer66 +blubber1 +020479 +nigga101 +banana9 +1love4ever +flor123 +picaso +ancient +520521 +25081981 +катюша +13467982 +02041977 +joseph25 +lilweezy1 +bajs123 +john06 +softball. +molly! +redrum187 +deutschlan +shakuntala +karlie +ford11 +sedona1 +newyork09 +130894 +h87va5rtp6 +granat +cane +141983 +faith10 +34416912 +omar10 +alpha7 +slapnuts +010406 +tornade +emolover +nepal +stephen3 +300182 +spirit12 +aku +rebecca! +25081980 +170194 +pincopallino +gratis123 +rachel15 +fresh3 +chevy99 +english12 +gro +barbie. +hello007 +program1 +tingtong +kadence1 +070192 +090783 +beegees +23011995 +hellokitty123 +310379 +hansi +adorable1 +jasonm +prince99 +18071993 +ecko72 +dallas06 +sports22 +yh3hnr4869 +09051980 +britt11 +010594 +nonpayment +190594 +anne +x +170678 +08011983 +sslazio1900 +retlaw +101103 +1322 +2238qwer +alejandra. +symantec +paul23 +same +231991 +19900991 +prospect1 +fatboy23 +villarreal +160678 +rbhgbx +astrology +sam007 +07091983 +311278 +200011 +daniel84 +katelyn2 +hj +love64 +pidoras +anime13 +guns +ns +safe +060980 +20071980 +arm +fraggle1 +teddybear9 +woodlawn +fripon +1qweasd +edward6 +david123 +300578 +sunnydays +scorpions1 +marcus14 +remember! +04111990 +27111981 +aviation1 +310179 +t654321 +dionis +15111993 +3182 +avignon +andrea8 +colt +1unicorn +raiders09 +sergio10 +leslie13 +icehockey +ladyinred +100675 +fernanda12 +kontol1 +tlc123 +010793 +grange +mama16 +lemieux66 +valami +rocky14 +one1one +160808 +woodie1 +190293 +church123 +beanbag +baksik +chevy22 +srisai +141003 +19431943 +brunomars +heather08 +563214789 +kytfy2xd98 +leelee2 +hood123 +pinky09 +220277 +jabari +110178 +jimmyb +gettysburg +hampster +haruna +dinozavr +eybdthcbntn +16candles +anna18 +joel1234 +060582 +loves123 +arcane +0000000001 +hawaii08 +12345qwert +ayyappa +tight +050506 +lombardo +yulia +040182 +syafiq +util +abkbvjy +silverback +brentford +goeagles +24031995 +hollister. +090392 +pounce +04021993 +homeworld +456838 +bannana1 +iuytrewq +654321987 +dragonking +05071981 +564738 +qwerty94 +forsberg +230494 +emily69 +class2013 +buster05 +hood12 +militar +fifty5 +rainbow01 +iloveu17 +cherry +13456 +hichem +misty01 +211984 +550550 +petasse +akinom +panther13 +kittycat3 +askim1 +0608 +voitures +080191 +rajraj +030594 +09121981 +pumpkin1 +papagal +boulevard +mickey28 +hairdresser +dothedew1 +lilwayne7 +250678 +kingofpop +14021975 +privs +280380 +dudinha +01021979 +060981 +antonio14 +210294 +aldo +iloveian +guinea +10101997 +291193 +141984 +250677 +twilight15 +raymond7 +2gether4ev +ypfu2vl856 +jenelyn +bill1989 +roberto +haunted +199898 +dar123 +jellybaby +casper5 +dark11 +08021980 +chrisb2 +3141 +element9 +ashley0 +death11 +x7bktntlez +marche +280495 +aliali1 +a012345 +james55 +1z2x3c4v5b6n +riverdale +291984 +salon1 +babylon5 +201111 +margot1 +goodwife +homegirl +supertramp +kangourou +val353nxhc +serenella +patato +newyork07 +loser44 +199116 +penis7 +070191 +nnn +rayray3 +mariposita +gokussj4 +03081981 +3651118xun +english +sm1234 +zxc123456789 +31101980 +apaaja +123456789zz +aybaybay1 +321321q +metal2 +capetown1 +steelers3 +ybrjkftd +eliezer +darkangel2 +11991199 +25121979 +cool +basket2 +bank +09041981 +hibees +otter +qazwsx23 +forgiveme +renton +chelsea99 +robaczek +bemine1 +football47 +07051982 +197819 +titova +22041995 +sistem +owahodarea +29011994 +27031983 +cooper09 +090192 +21081981 +bassguitar +newport69 +miranda +sokol +19861021 +lovelife7 +vladimirovna +09111985 +281987 +goon12 +steven. +160036 +17051996 +260477 +250293 +master18 +xexeylhf +simsalabim +131295 +jennifer24 +srh420 +kswiss +callie123 +wordpass2 +edd +calais +090184 +yellow07 +12asdf +east1999 +kkkkkkkkk +7373 +simba01 +ilovelove +jennyt +server123 +connect2 +goonie +24031980 +alex66 +jujube +atlanta3 +22111995 +butchie1 +040184 +120597 +516888 +240978 +saufen +daniel85 +perola +poohbear07 +03210321 +trebla +141975 +wqer1314 +scoobydoo3 +bismillah123 +marie27 +toosexy +boomerang1 +happytime +angels23 +toobad +emilys +omsrisairam +oreo22 +allstar5 +091083 +spank1 +coolguy123 +paspas +elijah5 +14011980 +1qwaszx +mardigras +dogma1 +123joe +198805 +asdfgh! +bubbles17 +1234rfv +07051981 +01101979 +191279 +tiggy1 +changa1 +hung +suchitra +rhbcnb +life22 +jaimaa +a456456 +savannah10 +131994 +mojo12 +medellin1 +tunde123 +jeep4x4 +101995 +sis +wicked123 +water1234 +530017 +maver1ck +shalom123 +090680 +18021995 +mindgame +pdiddy1 +carter08 +matisse1 +olivares +ranjith +dancer24 +david03 +johnny8 +grendel1 +clarkson +josesito +product +beckham07 +jaden2 +423423 +image1 +tomdelonge +pepere +231275 +webber1 +19061981 +redriver +sonnensche +alex31 +carolina11 +angelfire1 +rasberry +alligator3 +karina11 +030291 +poppers +aleks1 +harding1 +impreza1 +070484 +alex30 +momanddad2 +blackrock +fuckof +mexico619 +123456er +class12 +aa12345678 +tigger89 +290578 +050284 +198908 +12345656 +vit +charissa +dolphin +240195 +198729 +toby22 +daniel007 +hiphop +001990 +megan69 +biochemistry +210293 +421202 +18121994 +nagesh +freddy01 +hippy +carajo1 +22111994 +angelz1 +kenny11 +joshua28 +asshat +marie. +talia +hayes1 +were123 +babacar +the1nonly +brittany23 +guyssuck +roxy69 +041983 +silly2 +dancer6 +lancers1 +pinky6 +elantra +159263487 +glassman +pink90 +198208 +01012005 +dilshod +showme1 +brescia +290280 +ironman12 +280981 +88552200 +monica5 +21071995 +08051982 +3939 +emily1234 +spacejam +laska1 +atlantis +forever1 +f75s83nqk3 +necaxa +19861001 +duramax +floresta +luv2luv +19071979 +siddhant +190793 +13121978 +06091995 +parvati +lahore1 +rosie01 +140778 +honda93 +0709 +11041982 +lizard12 +250177 +bigd +goldy1 +gold44 +sports13 +texmex +qwas1234 +04111983 +200700 +frog22 +eiffel65 +dolphin6 +413413 +25071981 +130576 +suresh123 +rocky08 +hannah96 +wwd100 +trixie2 +jayant +freshman09 +guevarra +kidman +caitlin123 +liefie +kenny5 +04111984 +03021994 +beatka +alyssa8 +sagitaire +29091981 +elmo69 +erlan +morgan04 +jamesp +yukon +anthon +260179 +jamesbrown +ajtgjm +teabag1 +novanova +1camaro +logan05 +t-mac1 +guster +14031994 +021180 +251982 +antoxa +181079 +260260 +positano +987654321123456789 +savannah1 +weener +27111994 +simo +matthew88 +27031981 +puppy01 +sakartvelo +stickman1 +151982 +chivas1234 +16061995 +08041993 +guessit22 +tima +tiger06 +oscar21 +sop +guimaraes +wulandari +annelies +blackwood +usher8701 +markus123 +chino12 +gideon1 +11121979 +pinetree1 +100606 +010679 +whoopwhoop +ponytail +piedmont +03081994 +allison7 +260979 +mayberry +desirae +texass +wicked69 +clumsy +hubbard1 +01121993 +josue123 +020895 +10171017 +jake2000 +753 +dylan6 +030366 +victoria6 +141992 +capa2008 +tellme1 +051095 +300579 +19941995 +231982 +christop +wocao5201314 +goldmember +kb1234 +jaylon1 +111296 +26061995 +ironfist +jellybean3 +02061978 +jack88 +hosanna +sophia07 +bledsoe +hjcnbckfd +manuel7 +sh1234 +260792 +bqlk8kx79u +159357000 +element69 +aguilas10 +poesia +201989 +champy +becky12 +17111980 +mayann +windsong +raisa +220177 +1winter +littleguy +zxcvbnmasdfghjkl +nasrat +kylee +shree +170281 +nugent +bananas3 +elsalvador +11061994 +020296 +venugopal +punch1 +green777 +400606 +bangor +hotone1 +moneyboy1 +wtfwtf +polpolpol +huxley +dalton123 +101066 +getpaid1 +newborn1 +06081981 +peludo +last123 +careless +larina +funnyguy +mimi09 +021279 +files +07061992 +dragonballgt +swearer +753421 +mjmjmj +baker2 +090393 +harlow +marcy1 +pepperdog +cooper07 +18041995 +23091995 +an123456 +juliajulia +lynnie +zgmfx10a +xenogears +taytay13 +poohbear6 +hemi426 +250395 +knopo4ka +florida10 +gygypyfyyyposhy +houston1 +goosebumps +yanira +ihave4kids +12ab34 +stephen1 +podstava +mikail +2903 +jeffrey7 +28121980 +hejhejhej +28081980 +dalton2 +al1916w +618618 +omglol1 +28091981 +ph0enix +06101983 +munster1 +ab7f23rsv +cavaliers1 +welcome12345 +caitlin12 +250794 +javier +sarah1 +08041982 +friendss +robert05 +yourmom4 +159635741 +love1982 +calvary1 +eminemd12 +stampy +60crip +black. +bigjohn1 +mike28 +prankster1 +qazqaz12 +bassey +gabriel. +muppets +florida! +caitlin2 +080393 +020509 +max100 +roisin +9512357 +tamara12 +firedog +bridie +84131421 +july1988 +limonada +121314a +030793 +111995 +27071995 +bigboy4 +coolkid12 +030282 +brownsuga1 +radish +230695 +1champ +chococat +dinmamma1 +12081996 +lucas3 +pattinson +120776 +2901 +lmnop123 +290180 +nederland1 +chance10 +co2007 +gestapo +041193 +goldleaf +150878 +08091981 +181177 +66chevy +100978 +emoney1 +lillian2 +02041978 +maddie08 +06111988 +barabashka +love1983 +14022008 +dogtown1 +chris2009 +andrew87 +katie17 +ppppppppp +300400 +passion69 +bundy +мамуля +thomas87 +lizzie +pokesmot +strand +remont +brian07 +21051980 +vanessa. +cod +nancydrew +ilovemike2 +project86 +brown23 +031193 +rock14 +110202 +cooper21 +tangos +baxter2 +jenny8 +121175 +gjlfhjr +197328 +bebo12 +20091982 +egipto +maus +311077 +chevelle69 +121971 +farewell +02021974 +geetanjali +1000000000 +400103 +toottoot +199115 +senior12 +mnbvcxz1 +happie +explode +kissarmy +200778 +teamo7 +86248624 +canvas +pimp77 +dragon02 +l0vey0u +clothes1 +adrian18 +sanjar +taylor88 +kobe12 +dawood +califas1 +starlite1 +141296 +21041979 +05121980 +gomez123 +morgan9 +shantell +forever25 +crip60 +01051995 +312 +011279 +angels6 +gracie05 +legioner +q123456 +moiettoi +1888 +scotty +bella123 +050482 +braves11 +qwerty96 +1q3e5t7u +laputa +070491 +warrior13 +131982 +iloveu4eva +generale +angelia +padawan +25051979 +08111988 +130495 +boing747 +branca +q1w2e3 +zzz333 +jesuisla +viva +willy2 +noidea +090481 +imabeast1 +itsover1 +15021979 +nicolette1 +zz123456 +gnomes +kazakhstan +080584 +46466452 +socal1 +jake1 +pelicano +americo +asdfghj12 +sarinka +12041961 +daimler +serginho +jazzy5 +aznpride1 +superman06 +blackice1 +wanda123 +maddie! +element. +gandako1 +power99 +jimmy! +chaise +gtnheirf +opennow1 +03081980 +slim1970 +21091995 +mayra123 +phatty1 +nimitz +pepper00 +legrand +trasher +450450 +l111111 +romeo3 +05111983 +kerry123 +rfpfym +kalamata +27111980 +nascar11 +work4me +14051994 +crazy07 +mainstream +windows7 +nelson11 +777771 +300677 +281984 +temper +gjujlf +24071993 +newmoon2 +dembel +madhu123 +mamana +1skate +inspire1 +080907 +micmac +thomas04 +z000000 +scott3 +01081979 +silverstone +05051979 +sunanda +jasmin13 +3700 +emperador +111111f +brooklyn08 +waikiki +danny8 +pimpin06 +lover +000000o +profesora +moonlite +ladyblue +18091981 +bholenath +awesome5 +170894 +pamela01 +aditya123 +lilchris +c1c2c3 +24011994 +elaina +cherry +lucky#7 +sara10 +fish69 +310793 +football02 +bigmouth +laura3 +ruckus +schatten +robert55 +saraha +chouquette +atkbrc +andrea24 +youare1 +alexsandr +twinss +shay13 +shutter +19841001 +02091979 +jimmy4 +katze1 +panda22 +lovemybaby +skate6 +star05 +buzz123 +060186 +12345678qwe +kanyewest +maciek123 +021194 +money66 +allysa +lucifer6 +depressed1 +june1996 +188888 +katieb +werderbremen +wakacje +tigrotto +160879 +230895 +monkey42 +pipino +siouxsie +22101979 +2times +09071993 +insignia +taterbug1 +tabaco +mylove14 +bia123 +buford1 +1bubble +06011983 +murphy13 +public1 +babygirl87 +gengen +doremon +emmy +booby +19831985 +cintaku1 +420love +02121993 +fire23 +anna2001 +42684268 +150694 +aicha +joseph88 +freaky2 +joyride +03091981 +redhawk +1400 +carson12 +badgirl123 +090681 +031095 +cantik +zsxdcf +passw3rd +michael91 +12qazwsx +fleming1 +gaypride +300594 +02101979 +fuckher2 +likeyou +cbvjyf +yonkers +261261 +daybreak +texas69 +homeland +pink66 +kathryn +cool88 +210281 +337799 +202010 +solar +bronwyn +black +asasas12 +21042104 +jaydon1 +cheryl +rosebud +george9 +berkeley1 +may1996 +emily16 +112233112233 +azerty123 +mallow +030894 +chris29 +moni123 +13051996 +600061 +demolay +teamo22 +canadien +24031994 +nicholas21 +mustang302 +ranger10 +happybirth +15011994 +vanya +pinklove1 +missy6 +jessi123 +29071981 +198824 +020395 +patches1 +++ +frazer +09061994 +1nothing +211001 +issac1 +kaka11 +quidditch +bmw745 +z1x1c1v1 +keynbr +andrew92 +190479 +paragon1 +221991 +licorice1 +erasure +spartacus1 +0805 +03121994 +31031981 +melton +25800 +120675 +lifesucks! +carambar +07091994 +010807 +01021976 +fuckers! +150896 +040478 +ppppp0 +ford1234 +07091993 +hinder +narayanan +hk +16011993 +23011980 +jeremy18 +7753191a +cool16 +amar +tonito +100proof +francisco +031179 +sergik +050695 +8en3dwdxpi +201276 +abi123 +serenity +17021980 +midway1 +sexyboo1 +191277 +jasmine19 +141002 +121073 +24111993 +1nirvana +littleangel +tavolo +slipknot4 +dopey +sanek +4everurs +vanessa18 +1jimmy +richierich +1flowers +dimple1 +ranger +lipgloss2 +coral +050781 +r9e8w7q6 +smith +c0nn0r +10inches +pypsik +chris666 +frenchfry +mine11 +damian13 +135711 +haitian1 +sashaa +fantasy2 +2nqw7a1517 +aitana +charmed12 +andrade1 +panthers08 +18051959 +iamcute +w1w1w1 +198103 +olddog +hotwater +stormy12 +rtyrty +dragonlance +brandy3 +babydaddy +sophie09 +barros +aldrich +ballin8 +300493 +europa1 +chibuike +250477 +nazaret +26031994 +240778 +198021 +nazira +hom +danielle69 +freddy11 +zacarias +4myfamily +diadora +radek1 +01091979 +18111994 +my2cats +1molly +521 +chello +09021983 +haha69 +alisha123 +b11111 +hehehaha +iloveluis1 +there +rosales1 +050484 +1love! +shamus1 +softball44 +altagracia +manofgod +sophia10 +holla2 +bball42 +001992 +19871026 +william05 +150995 +070895 +08081976 +spike22 +80000 +bozena +billy22 +030509 +michel123 +reggie +100896 +198813 +sharada +ilovesex2 +phoebe +purnama +kaylah1 +newengland +bikes1 +198304 +sevens7 +250378 +latina12 +19031996 +gtasanandreas +marie101 +100596 +ummagumma +221166 +nikki! +221094 +jacob02 +cozumel +karime +verochka +fussel +290693 +fktrcfylh1 +1955chevy +herpderp +123boo +ivan1996 +appaloosa +ciccino +noonie1 +001968 +09061980 +superm +010101a +jeremy4 +jenelle +05041980 +stuff123 +feet +24071982 +rockyroad +rutgers1 +hanspeter +mona12 +hoboken +060493 +upyours2 +butterflys +single15 +valentine +chutney +020496 +qq11qq +martin1234 +savitha +12011978 +951 +lmao12 +xkhnmki633 +selmer +police01 +dakotah +mountains1 +bitch26 +020103 +marley13 +goon123 +1590 +lover99 +marine +122015 +cacique +wiggle1 +16091980 +19841123 +marin1 +wawa123 +040509 +1sabrina +lam123 +22121979 +hawkwind +volunteer1 +money1000 +angellove1 +anghel +e12345678 +jackson05 +jomarie +midnight10 +ehlb3c18tw +julianne1 +foreplay +22022202 +winter7 +09061981 +04071993 +270679 +281079 +smile69 +221980 +1985123 +jillybean +ruby13 +english123 +030480 +hashem +babygurl06 +bergamo +willow13 +duece2 +25071995 +198927 +faith21 +tigger04 +aleluia +tomjones +020209 +jesus2011 +jesse22 +2327 +coumba +07111982 +291179 +sunny01 +d-money +attilio +purple420 +delta3 +espejo +090977 +urban +rjhjnrb1 +123rock +jeanine1 +paokara4 +aloalo +dogpound1 +beatit +rfgtkmrf +chris2006 +08071993 +atakan +buick1 +spinoza +margaritka +abidemi +kimbo +dragon84 +140895 +bobble +allin1 +crazygirl2 +carmen22 +2524 +losenord +yyy +101009 +clicker +googly +rangel +acm1pt +beyblade1 +22021978 +jeremy17 +cool25 +rangersfc1 +brandon04 +britt14 +minnie7 +sosa21 +12121976 +oaktree1 +marley7 +nomames +sadiegirl1 +scott22 +rocky99 +arinka +q +17041994 +tiffanie +30051981 +ashley90 +torres10 +sm0key +gobble +anneanne +poprocks +fr1ends +elementary +gfhfpbn +10031978 +0120 +kartina +totoy +vegas702 +amarnath +socool1 +050194 +martynka +joepie +baboon1 +dillon01 +charlie19 +hacienda +dbrnjhjdbx +halo02 +greenday6 +anakaren +080979 +uruguay +parris +love48 +princess78 +sjiecj1a9x +оксана +classroom +sadie13 +jesus00 +19841018 +123443211 +455455 +panacea +juicebox +kissme4 +connor99 +calhoun +050192 +avrill +523698741 +thelegend +rooroo1 +brandon02 +bball31 +woofer1 +proline +sheyla +bosnia +karman +pirulito +merganser +27061994 +badboy14 +pwnage +boxing123 +snowball +iluvgod +vfhbz +231276 +jimmy21 +antwon1 +muchlove +fergus1 +spammer +mygame +volcom! +clarke1 +tiffany4 +landon01 +cfdtkbq +fishing4 +1raymond +mommy03 +dexter13 +rosetta1 +060979 +mary69 +110975 +29051980 +shivji +silver9 +badboy6 +holliday +animefreak +1234567asd +trolls +obama +asdf23 +esoteric +paris01 +831005 +adesola +eat +210179 +family15 +totalwar +care +daddyyankee +music=life +cutiepie9 +laura69 +52hoover +goncalves +tribes +kimak1 +jumpstart +14101995 +annoying +101973 +batman20 +pothead2 +police11 +siempre1 +farter1 +070682 +tonight1 +katie15 +chica12 +lucario +senator1 +virgie +6cctbbk516 +myspace30 +wetpussy69 +bateman +simone2 +benny12 +dakota23 +29011980 +hideki +alba +daniel2008 +david2007 +bubba9 +1sparky +sorrow1 +070384 +olympus1 +nico1234 +1234567890qwer +vidanueva +dutches +kitsune1 +sweetie01 +ponderosa +michael90 +imcool12 +010405 +servant1 +graciela1 +trivial +08071983 +171278 +quackers +011280 +salma1 +230177 +myspace76 +chelsea18 +misamisa +200820082 +yamuna +porshe911 +1stplace +12111994 +marlon123 +blondie101 +sexylegs +gfhjkm777 +noodles2 +ghetto123 +22101996 +lazyboy +whistler1 +p0kem0n +misbah +gravedigger +brennen +madisyn +13324124 +vanna1 +polonia1 +sarina1 +waddle +eagleone +forgot2 +austin101 +dbrfdbrf +zrjdktdf +leelee12 +belle12 +24011983 +monsoon1 +killer93 +cindy13 +545545 +bowwow13 +harley101 +chanel05 +12051979 +huligan +198102 +rfhbyrf +artichoke +shannon8 +02101978 +golfer11 +deadend +amber8 +14111995 +241276 +faithfull +june2000 +sunshine26 +biboune +puta69 +sweeter +01121994 +benzin +busterbrown +angela5 +pirates3 +slipknot01 +nochance +transport1 +martyna1 +kissme7 +122412 +260894 +3tb9xm42xi +edward08 +09101983 +27021981 +maxou +franek +251276 +mark12345 +ktitymrf +mama2000 +tiffany10 +160877 +200576 +vanila +060486 +munnabhai +human1 +love1980 +10061978 +070893 +mutual +230794 +mychemicalromance +rf +flamengo10 +aerdna +ahfywbz +199423 +dalton01 +ambulance1 +patoche +white23 +jenny20 +freckle +melanie7 +odie +ginger06 +london20 +sunset12 +hai +150575 +iloveyou78 +021078 +boomer3 +renee5 +collector +rent +password71 +kimmer +astigako +380013 +vika1995 +lctstens +kakdela +thousand +infierno +121512 +yeswecan +honda6 +work1234 +03091994 +redrum666 +shitface2 +popcorn8 +gangster6 +22081982 +251990 +finnigan +07101981 +panthers3 +liljohn +05041993 +841025 +arihant +kacey1 +d123123 +sivas58 +120200 +gambino +5zgc2t764b +1qaz2wsx +cody101 +jimmy1234 +dance01 +mamatha +duran1 +spooky12 +08111991 +fucker9 +200910 +haywood +26051995 +gjitkyf +kate1234 +fulmine +zerocool1 +bagdad +mustang. +carrick +cats101 +bethesda +tiger! +161277 +181984 +walmart2 +shorty88 +gateway11 +bellsouth1 +morgan. +fantasy +ballsdeep +62626262 +realest1 +040471 +secret101 +oyatayo +numero +rose99 +myspace96 +luiscarlos +sophie4 +125800 +telecom1 +jess01 +031194 +techno123 +screwed +12101995 +06031982 +pantufa +demonhunter +contest +45654565 +boilers +lila123 +bleeding1 +annette +melissa18 +saadia +hartmann +aaron17 +badboyz1 +dancer. +nicole83 +newyear09 +crjhjcnm +19011982 +010577 +261277 +rizal +26101995 +bobert1 +vladislava +teacher +muffin5 +fresh11 +19111980 +nandan +111113 +anja +orca +vergessen1 +djibouti +26121995 +25021978 +199317 +1christina +frederic1 +wwwwwwwww +jayden22 +198106 +fuck89 +vadim123 +anindita +11441144 +randi +iloveyou31 +abigail01 +steaua1 +tina22 +22love +kaliningrad +070392 +cayank +jesse! +120608 +fishhead1 +king06 +killa14 +silverfox1 +tonio +sharon +brenda +wasser123 +santos13 +824553435ss +dildil +august03 +insane2 +100576 +ronald12 +melusine +arancione +riley11 +charliedog +blacky12 +precious11 +republic1 +laksjd +jojoba +tinashe +05011982 +1monica +c0ffee +mooooo +qwqw12 +lollip0p +ravioli +tigger45 +changer +user1234 +24041995 +ronnie3 +110876 +101175 +1donkey +giraffa +munson +shit13 +cvfqkbr +andypandy +160695 +16011981 +sexygal +290494 +6161 +jeremy16 +sammy1 +161278 +1cracker +sunny5 +april1990 +theworld1 +hailey11 +s123456s +herald +stubbs +2131 +vortex1 +irock11 +ballbag +123-456 +polo99 +12101977 +dam123 +cc +capello +omalley +04021981 +1300 +greek +mexico24 +risc +jar +alfredo123 +nannan +water13 +781006 +mickey25 +personale +210195 +howareyou1 +alexandra3 +060676 +caiden +04021982 +050609 +brasileiro +070382 +steph69 +ziggy2 +30041981 +821026 +081980 +annecy +honda500 +jasper99 +hiking +deano +1551 +jesusmary +sweet25 +hamilton +mari1234 +pablo12 +twilight6 +01081994 +proverbs35 +carmelina +allstar23 +7stars +yankees07 +yankees15 +pimp12345 +ionut +zhenyu2012 +06081982 +misericordia +icecream13 +floortje +05021980 +31011993 +123098q +wertyuio +anulka +198024 +fai +221196 +04071980 +unity + +march05 +proverbs1 +240280 +abcdef7 +lovers07 +sabrina01 +19121979 +xavier06 +br00ke +pasuma12 +tillie1 +oceans1 +nenita1 +cheating1 +091983 +ashley86 +1234567123 +4488 +optout +dockers +britt08 +charles22 +lakers +shane11 +lordik +dwayne3 +chris2010 +nelson +shakademous +romeos +300994 +festival1 +m696969 +music25 +love777321777 +vlad1999 +bingo12 +lfytxrf +neverever1 +020808 +hair123 +kicsim +katie08 +chevy11 +159753654 +samsung6 +tinker! +piupiu +ivan11 +2nipples +dick22 +4294967296 +213546 +blood21 +071193 +dangelo +defcon +jaymar +buttbutt1 +560097 +sunshine44 +valerie123 +27071981 +spooky123 +supermax +vfif123 +baby111 +22021979 +success +england1 +general123 +419 +220895 +06121994 +cabana +sherbert1 +marmot +11091994 +feride51 +logan4 +4evermine +figure +fucker01 +michelle99 +181077 +060581 +blade12 +0804 +caldwell1 +012012012 +purple05 +elviss +qazwsx321 +poknat +123pormi +.... +pharaon +georgia1 +zap +helga +18051978 +listen1 +shithole1 +07111988 +fififi +burnside +196767 +071989 +name123 +coolgirl12 +290593 +anakku +010377 +maggie88 +060182 +cancer123 +popcorn10 +krzysiek1 +qscwdv +laffytaffy +school14 +01041979 +210895 +honour +honey9 +03121981 +single14 +iceman3 +15301530 +nick06 +270778 +081278 +reece123 +0password +14061981 +161178 +karina01 +kakaka1 +motorolla +210178 +icecream8 +dancehall +saxofon +frankiero1 +homero1 +cool77 +sexyb1 +janiya1 +starkiller +ryan04 +12091979 +199001 +moustapha +cesar13 +gabriel21 +meli123 +ladyluck1 +cash11 +micro123 +campeon1 +pinky23 +sandrock +010494 +blah13 +blondin +ben123456 +blue04 +051093 +020494 +pinky01 +nokia5320 +sander1 +hahalol1 +masterpiece +ilovemysis +090603 +ronald +vuitton +pisellino +sexygirl15 +ayurveda +rasputin1 +lemieux +d1d2d3d4 +24081981 +28031980 +30121994 +metalika +lilo123 +11111978 +3iverson +famous3 +orlando13 +angel1 +junkjunk +elijah4 +creampuff +199016 +watson831 +frankie1 +monkey85 +yjdbrjd +fh1hm1wl +sidorova +kamryn1 +090286 +191992 +dina123 +05061994 +lady23 +cashman +doll +bignose1 +gorodok +dowitcher +051293 +rangers10 +450000 +nataxa +evaristo +music17 +snowey +smiles! +17041978 +281077 +overkill1 +sexonthebeach +07021994 +baklan +australia1 +michigan +08061981 +masterblaster +link4me +vivek123 +joel13 +foodie +silverio +281985 +080877 +shakira123 +omegared +fltkbyf +robert89 +221990 +198216 +ar123456 +turbine +241982 +040385 +sandesh +bettyboop7 +110897 +241296 +07041982 +fdfd +homie13 +lupetto +011281 +polkovnik +divagirl +ghjcnjkjk +pentium2 +9111 +redgreen +osorio +ed +saunders1 +1compaq +demarcus1 +marlboro2 +scooter23 +cachorra +chris123 +rajeshwari +naruto20 +archimedes +icequeen +lover44 +gayfag1 +duke10 +titanium1 +zul123 +nelson01 +ghostrecon +wanwan +nicholas123 +eastside14 +041094 +hightimes1 +booking +hamtaro1 +1yamaha +asd123 +hayden +51525354 +20031979 +scrooge +mcguire +dale08 +gustav1 +031276 +1234abcd +september12 +triple1 +sundae +andre3 +randymoss1 +qwertyasdfg +william20 +thisismypassword +040382 +chloe22 +31051980 +a252525 +shawty2 +07011983 +frank3 +council +030779 +grad07 +110035 +jenny101 +10081980 +hariharan +tiger86 +14101979 +girl14 +jeremy6 +02051977 +ass111 +marinel +sugar22 +gisella +241093 +963321 +cemetery +autism +intouch +isabella08 +dietrich +110476 +gates +aiman123 +ronnie01 +missme +upiter +01091995 +300394 +papasito1 +courtney8 +pok +hockey31 +gibbon +180578 +cadbury1 +tiger777 +oriyomi +xiaoxin +fifa2005 +milka1 +neopets22 +hitler666 +carlos27 +satan666 +elvis01 +adios +brooklyn21 +0710 +cutiepie09 +20111994 +branko +11121978 +7539510 +1aaron +edwards99 +110177 +lovegirl1 +hihihi12 +120797 +galatea +borracho +ignazio +gsxr1300 +porche911 +180281 +12101979 +camille +19841015 +030493 +fluffy5 +cornflake +manwhore +ccc333 +1916 +dillinger +isabelle +rose17 +07121993 +bhatti +localoca +159357z +holidaysecure123 +qwer13 +ihatey0u +220596 +buddylee +mono123 +1maxwell +181277 +220496 +ghandi +140378 +ability +mcfly +gbjyth +dude10 +07051993 +madeinchina +fuckyou66 +04091983 +31415927 +pelotudo +brittany1 +abcdef6 +scarface5 +arsenio +evgeni +olaolaola +bobsaget +270879 +mazinger +akasha1 +whitecat +korsar +baby100 +bubbly1 +price1 +mariem +301193 +pussy15 +8point +camacho1 +stas123 +lk123456 +sd1234 +access01 +winnie +babe21 +engelchen1 +gogiants +oldspice1 +somebody1 +malmal +welcome1234 +babygurl9 +pas123 +miley15 +slingshot +marie77 +army1234 +020301 +bigdave1 +ricardo7 +annalee +becker1 +210576 +faheem +omoyah1 +hawaii01 +felicidades +fuckthemall +p@ssword1 +birthday12 +elite123 +gutter1 +fuckyou78 +12345699 +volvic +onelove420 +pink45 +drugs1 +12071979 +17011982 +198926 +pirates! +password666 +starts +fumanchu +011183 +shithead69 +moonshadow +080284 +fokker +lachen +qwertya +lol123 +gerard123 +redrock1 +220795 +fermat +toyplanet +couture1 +apfelbaum +newlife2010 +buddy17 +a1b2c3d4 +25202520 +mutley1 +crazy17 +mariajose1 +130778 +fake69 +23081995 +250576 +trouble! +21111994 +26021994 +honeygirl +kontol123 +geometry +beauregard +24051981 +secret1234 +reveal +hallo! +jasmin2 +02061976 +231456 +13051995 +23262326 +luismi +vikings2 +020678 +24071981 +09111982 +90 +120397 +22101995 +scarface11 +juicy12 +teddie1 +kazakova +fluff +coffee! +199113 +280494 +shawn11 +asakapa123 +kinga1 +breakers +number27 +iloveryan! +10021978 +99009900 +118811 +mm744m1 +mittens2 +jkl789 +811010 +amy1234 +anna2007 +300494 +nichols1 +monkeyball +paradise2 +hole +05091982 +hockey28 +miller30 +280993 +pointe +akon12 +zaynmalik +fuck +volvo123 +melody12 +120276 +poopdick1 +250777 +faramir +198815 +07011993 +julia01 +120975 +angelino +dusty12 +bones2 +stella13 +rebenok +120606 +03011993 +hannah77 +1legend +peaches23 +valdivia +tulipa +14081994 +12345678y +pepper24 +reject +kor +sexymom +voldemort1 +25cent +suriname +elbarto +philipp +russia11 +chicken44 +estela1 +199226 +pintura +otis123 +chanel12 +torcida +lucky4me +allstar11 +manuel. +dragon67 +11111r +shine123 +151076 +nikita99 +31101996 +lastpass +dukedog +danielle6 +flower08 +cristofer +capri1 +myself2 +pathology +1234567890w +manny13 +kayak +02021975 +23032303 +269269 +charlotte3 +michael85 +luvya1 +golddigger +gabriel14 +pitbull5 +mixtape +tochukwu +300381 +hailey04 +lesbo1 +elijah09 +voland +120674 +blume +sucks1 +natnat1 +kaulitz89 +taller +jason19 +gohogs +ciara12 +thomas92 +451451 +evelyn123 +whales1 +fergis +041093 +montauk +05111984 +yomama3 +iloverob1 +161991 +stonehenge +05051977 +22081995 +booboobear +ne +nemo11 +02081995 +13111994 +110220 +mememe12 +read +friend11 +99889988 +kevin +goodwill1 +kravchenko +sonika +glorytogod +lynn14 +dmitrij +allison11 +2p76xg2yhv +210977 +arena +lzudz2xe98 +230974 +19021981 +794613258 +altec1 +dedmoroz +fuckoff01 +maracuja +becca12 +superman55 +600092 +cheese24 +789551 +shanon +aprilia1 +1315 +16071994 +symmetry +zzz000 +houston7 +tabbycat1 +fibonacci +puppy8 +morbid1 +tanner13 +60606060 +dottore +toby10 +130776 +warfreak +welding1 +dance8 +imperia +19841212 +swallow1 +victoria22 +beauty +111965 +dogtown +140795 +21121995 +lifesgood +cookie19 +30121980 +josema +srbija1 +moody +123456й +160994 +jeff22 +a212121 +eng +manson69 +280979 +lad +russia123 +pimp55 +drake12 +grad2009 +scarface10 +07041980 +3322 +fastback +spongebob12 ++ +400602 +espana1 +getrdone1 +hate2love +trever +christine0 +060483 +woopwoop +babyjames +1loved +cenicienta +mygod1 +caronte +6uldv8 +201175 +30061995 +youaregay1 +mickey05 +220641 +ashley26 +jazzy7 +jamie14 +iloveyu +softball99 +chingching +filudskou +qpalzm123 +hate13 +wesley2 +monae1 +fdfyufhl +230178 +123456789qwert +25061994 +28021980 +02071996 +wilmington +06091994 +111095 +18101981 +333444555 +stupid6 +magdalene +140994 +221222 +13011982 +18061994 +qazplm123 +230196 +12031996 +imsorry +economic +nelinka +dingbat1 +bombon1 +cazzoduro +steroids +carlisle1 +lazy +shake +senior2008 +17071995 +050677 +miller21 +alexzander +akunamatata +faustina +artem1994 +one2three4 +020309 +londonboy +music99 +72nova +jacob16 +barbie18 +saladin +021980 +bubbles18 +pepper77 +favre04 +joshua27 +pantera69 +playboy. +skittles5 +slaughter1 +angel82 +777vlad +20041996 +lindaa +091985 +alex84 +natasha1 +616616 +922i4ddebm +glen +adrian17 +cheer23 +gujunpyo +08111983 +katarzyna1 +damien12 +maggie1234 +purple96 +yellow45 +040192 +yunusemre +braeden +urmine +2807 +15511551 +honden +italia06 +311078 +070183 +chevys1 +kjhgfdsa +jordan55 +mengmeng +ranger7 +vaquero +trent123 +22031981 +02101993 +darko +coral1 +plague +241983 +19861011 +mikola +100995 +honda10 +rapala +babyboy17 +balderdash +myhero +milamila +kr6sjhs412 +lolsmileyf +toad +010609 +kokolo +101005 +gtnhjczy +01041977 +03021981 +258036 +rem +drinks +baller9 +brandon0 +19932009 +1zachary +seventy +051989 +mamipapi +ca1234 +christopher1 +lettuce1 +fatbastard +1q2w3e4r5t6z +fuckaduck1 +20111995 +@123456 +selassie +24061980 +1toyota +fishface1 +sasha14 +111111g +31081994 +qaz123456789 +cheerio1 +scotland1 +pass_rrewq +christ777 +13091981 +carmen10 +23252325 +17081995 +piter +godisgood +300881 +agness +bandit! +010379 +monique +13041980 +mackdaddy1 +karen01 +superpippo +121264 +emily03 +shane13 +maggie77 +2loveyou +emery1 +12291229 +dannielle +heaven08 +220896 +daniel12 +gotcha! +10041996 +pangitka +trinity6 +chocobo1 +catdaddy1 +babygurl8 +13061978 +180194 +blessme1 +20081981 +buttercup9 +282001 +200395 +peanut88 +santos +genesis +290679 +moskau +123456z +hardware1 +latrell1 +petanque +lacrosse11 +musica2 +sofresh1 +tokunbo +197719 +170779 +hghghg +sabiha +snacks +sasha111 +198318 +winslow1 +hf: +sophie14 +youtube2 +19011980 +louise7 +1bullet +hiphop23 +27071994 +isaiah08 +pf: +sammy17 +happy2011 +powerranger +25051975 +halo21 +tbird1 +larenga +etienne1 +2blueeyes +ronald2 +2hdq6c9azv +pandora +asdf;lkj +jesusrules +fidel +10091994 +hubble +08031981 +dorky1 +vlad1234 +010777 +240878 +031277 +bushman +akeem1 +120203 +pituca +20031994 +penguin8 +abbeyroad +aracely1 +wazup +140495 +maria07 +hotspot +charlie27 +success09 +dinadina +poohbear +isabella11 +perez123 +smiley14 +tolits +florcita +1frankie +satguru +esenin +lollipop13 +pepper06 +aubree +jonson +22101978 +lugnut +zachary13 +050596 +nectar2011 +beyonce12 +barbie6 +david111 +soukaina +050708 +santi1 +love000 +26081980 +cameron99 +4040782as +placement +mexico2010 +vavava +010294 +420high +little11 +2213 +dorita +natalja +toothpick1 +cms123 +sternchen +fire01 +valeria +patou +kerberos +15111978 +skittles4 +michigan12 +nbalive +reddwarf1 +shane3 +29101981 +bubba08 +king666 +06021993 +131983 +pimpin24 +farmgirl +rawr13 +julian +rf: +230278 +asdfghjkl12345 +01121981 +1carmen +olivia03 +reaper2 +1918 +180680 +pupetta +robert26 +adidas21 +dimmuborgir +olympique +pimp100 +boater +090509 +gosling +retsam +annita +gravy1 +mollie01 +sexboy +joe101 +jkmxbr +nexus1 +290396 +mojehaslo +130178 +august02 +botas76 +shipra +23101996 +spencer01 +catdog5 +123456789101 +satan123 +macondo +agostina +starmoon +blackandwhite +ewan +evolve +omega12 +junior00 +elephant5 +18101995 +ilovesos +02081978 +pipetka +brookside +simple11 +matt09 +warrior11 +khattak +011079 +19851012 +drevil +foghorn +gerard2 +ferdinando +master0 +faisal123 +12wq12wq +301195 +1fuckme +rediffmail +appaamma +swampy +gangsta10 +pop101 +cassey1 +redboy1 +snowdog +pinky10 +unloved1 +richard14 +east +26091982 +salami1 +password420 +loader +sadies +miahamm9 +200999 +080384 +260695 +poppop123 +pintoo +19861210 +copeland1 +1a2b3c +26021980 +24081980 +h1h1h1 +1913 +kinjal +ibiza1 +рѕр°с‚р°с€р° +06041994 +19851025 +idonthave1 +08111992 +emma04 +210176 +iloveboobs +brooklyn22 +htlbcrf +mancini +140296 +mexican7 +shawn3 +gohome1 +560084 +heyyou2 +myboo2 +160101 +290381 +destiny14 +urthe1 +taktak +billiejean +94mustang +saints11 +liberty1 +setsuna +121212s +yanayana +hakima +blinky1 +21011995 +gunner11 +shelby500 +solovey +jasper21 +terminator +michelle77 +shiner1 +15951 +03121993 +jaded1 +02041996 +sister5 +jesuschrist +ariana12 +7children +firecracker +sdsadee23 +gman +93mustang +lincoln2 +aiden08 +1234zx +godhelpme1 +jessica77 +q1w2e3r4t +northeast1 +09041994 +dubois +kluivert +wrong1 +m0nst3r +eatshit! +090809 +79ford +132132132 +789012 +jazzy10 +anneliese +14021979 +amin123 +pink86 +daniela13 +naruto55 +honeycoh +silvina +04011982 +dancer88 +ba +chelita +197510 +0109 +limelight +sukanya +coolio! +elfriede +fatman12 +honda +131996 +140594 +angel555 +1miguel +26091995 +molly123 +red222 +1234545 +dolphin! +gjyjxrf +rene12 +13501350 +karatekid1 +040283 +123456787 +sativa1 +love68 +12061979 +freerider +231076 +tubgtn +parazit +jamie22 +krokus +paladin +allgood1 +17031980 +030182 +kelsey10 +frank +25081995 +morgana1 +1326 +player16 +29051982 +ela +powwow +gamers1 +bas123 +manuelita +coondog1 +ulyana +ghghgh1 +jessie23 +krysta +wer138 +alina1995 +raymond +squires +ellabella1 +freedom. +bubbadog +steph22 +010396 +150295 +fresh101 +136479 +bradley3 +071180 +buckie +sandra3 +nemonemo +31101978 +frostbite +donjuan1 +13021994 +thuglove1 +sharkey +success01 +lola10 +dreams12 +++ +fall2008 +baloch +29061995 +cooldog +cocobean +pussy666 +bassline +blastoff +patsy +andra +wasalak +281295 +200694 +billy6 +25302530 +12481248 +chloedog +230778 +777777q +sunnyd1 +caffeine +steve0 +220294 +taitai +lagata +liverpool01 +nokia8210 +0409 +31122009 +010678 +puppies4 +30071982 +06021980 +djtiesto +rivendell +mark09 +198699 +10021996 +pnufsci218 +laura14 +dodgers123 +floricienta +515051 +136900 +wildwest +02061975 +210995 +severina +angel1992 +gogreen1 +tristan3 +nicky12 +family03 +thunder21 +princesa2 +284655 +201986 +jawa350 +300695 +basketball22 +glenn123 +noadmin +n.kmgfy +ashly1 +bosna1 +bitchass2 +29031994 +050509 +hackme +nermin +30051995 +4201 +pass00 +vicky12 +151295 +demonyo +justin97 +babebabe +megaman12 +112007 +ole +sosweet +indya123d +anteater +star100 +234589 +queen7 +gtnhjdyf +vinny123 +sunburst +784533 +cool33 +will23 +housewife +illegal +carson123 +rhfcyjzhcr +grandslam +maxito +killie +sreedevi +dallas14 +md1234 +breakfast1 +threegirls +janela +phillip +jacob03 +tacobell12 +puppup +boonie +gor +04081979 +lewis12 +13111993 +030980 +nympho +201308 +gwadada +password41 +123456789asdf +3q2w3e4r3t +102288 +purple29 +stratocast +ichbin +anal69 +jason05 +2016 +account123 +dani3l +061079 +walkitout1 +tango2 +waterlily +milla +corona2 +diesel2 +gangster11 +amoree +3odi55ngxb +carolina5 +twins08 +kaden +111275 +2gangsta +hannan +29101980 +adam07 +06031993 +lavidaloca +sniper2 +riley7 +16111981 +money007 +yukiko +odysseus +frankenstein +harsh +g123098 +fitter +ninja101 +bubbl3s +parade +minty1 +noah11 +myzoosk +alec +hotmail3 +kytfy2xd97 +19031995 +libra10 +021989 +spiderweb +suleiman +12031997 +waiting4u +deusex +repent +alabama3 +110496 +tennis4 +iceicebaby +alyssia +27041981 +lizeth1 +123456jk +150577 +08061994 +konstantin +rose69 +1outlaw +amelia12 +callan +luk +lee1993 +buttons123 +jack2006 +110999 +happy. +111076 +darvin +189189 +lotus7 +kovaleva +25121994 +chevron +120775 +google9 +kenzie123 +marina22 +180993 +bitch27 +mama07 +badass23 +pumpum +merced209 +green28 +160679 +dogstar +04051994 +123qwe4 +emmie1 +02111981 +gena +bhabycoh +montez +20051977 +123456rr +111111a +loveyou143 +wwe4life +pornporn +13151315 +dane +benedict1 +martin07 +sweetpie +bunny4 +nene15 +6grandkids +princess85 +123456am +19821984 +discreet +pink96 +cholo +carter4 +sidney +sender +villeneuve +applejacks +zoedog +3355 +niclas +bigdick9 +030495 +eugene2 +mahaveer +11081978 +14061980 +shisha +23111979 +brandon88 +click123 +brianna! +050281 +crabby1 +jelly2 +davenport1 +chocolate11 +arc +martins1 +ram2500 +221993 +kelvin123 +1snowman +grace4 +bananarama +florida01 +everlastin +blakey +020192 +wol +jayasree +oliver14 +11341134 +hermes1 +pavlenko +010277 +lovesexy +to +19841011 +lovehurts3 +peanut03 +31081981 +payaso13 +joseph03 +spongebob +angely +renesmee +aaron09 +loser00 +16051996 +aristo +volley12 +montydog +thierry1 +monkey12 +bulldog +101298 +1358 +ashu +ayushi +norman123 +theone12 +201007 +priceless1 +loco22 +030595 +ceres +20021978 +090493 +1bigpimp +tijger3417 +banana6 +dream5 +punk01 +rachel9 +giants123 +120673 +dbrf +180195 +bighead2 +280898 +1qw21qw2 +halfmoon +taylor33 +130296 +badoo.com +richard. +double7 +yay123 +laketahoe +cookie55 +29031981 +mayotte +vivivi +woodward1 +2bananas +northwood +gemgem +suzuki1000 +4yfb2s753d +19051977 +ayman2008 +121201 +hecfkrf +lotusnotes +abril +czz000000 +hazard1 +198002 +mightymouse +010173 +05111981 +10021977 +playstation1 +jedidiah +simone11 +199614 +soufeliz +georgiy +mooney1 +jumpstyle +kerri1 +darknes +fylhttdf +layouts123 +g76u94prm4 +13031996 +surfboard1 +270379 +12121974 +230396 +silva123 +balla3 +qq112233 +katinas +16061978 +260496 +cowboy5 +pinklover +19021996 +ch123456 +ghgh +wicca1 +friend +18031995 +martin88 +deedeedee1 +01031976 +07101982 +ricky7 +trustno2 +poop55 +notime +gg1234 +25111978 +secret10 +18101980 +malia1 +shinedown +10051978 +11081976 +13541354 +123258789 +king360 +knight2 +darius12 +love2sing +15041978 +3password +houston +preston123 +vball11 +assass2 +25041981 +02041995 +daniel0 +funkymonkey +kaylynn1 +salamon +kelsey +55555d +ghjcnjqgfhjkm +14111993 +bungee +04081994 +jebise +outcast1 +1cheyenne +killed +shadow87 +03101993 +payroll +zxcv1234 +hppavilion +bongos +2907 +gigino +gohard1 +november05 +coyotes +5monkeys +qwertyuio9 +barrie +brooklyn1 +qq000000 +fantasy12 +flint1 +1momma +hotboy5 +t4_us3r +fordham +290894 +dean12 +12inches +07061982 +chakkara +1010110 +23091981 +adivina +gamess +fishbone1 +angel1990 +lovebug22 +a1sauce +king007 +090880 +lokote13 +153045 +genie +wapwap +bloemen +12345ss +suzuki125 +260794 +princesa +sandgrouse +joints +jeremy15 +isabella4 +010607 +warface +2babyboys +bipolar +alltel1 +yellow44 +041178 +141196 +twilight16 +love1999 +socorro1 +fktdnbyf +viktori +trinity07 +yogurt1 +cupcake9 +linda3 +paris3 +sisi +19861012 +america6 +motita +porcodio1 +100876 +a12344321 +stgeorge +haterz +tetete +seba123 +1fireman +trinity11 +sony11 +mama2008 +889977 +cody16 +music77 +rodney2 +101205 +12891289 +vollyball1 +brown11 +elemental1 +afridi +110057 +zodiak +eleazar +noodles123 +1s2s3s +daili123com +effect +regina12 +victoria14 +red007 +keshia1 +trying +polymer +virtus +milind +jewel123 +poohbear8 +brianna07 +paramore! +amani1 +dani10 +16101994 +wolfenstein +jenny18 +bernardino +anarchist +13021978 +270894 +solitaria +kanye1 +britt09 +martin4 +bubbles88 +literature +wizkhalifa +aceraspire +sherin +ginger00 +insomnia1 +23011994 +pieface +081093 +ghetto12 +freeuser +198107 +brett4 +14111978 +nosoup4u +12e3e456 +andrew97 +monsieur +treeman +larrys +cool18 +sunshine28 +chewy2 +love831 +guero1 +an +ciara2 +evgenij +crips6 +45124512 +inform +disciple1 +kelly14 +112111 +15161516 +04091981 +112911 +olubunmi +yukiyuki +523 +180894 +sexyboy13 +11111977 +antara +babajaga +elvin +nokian80 +honda04 +120598 +261194 +09041982 +popeye123 +31011980 +hutchins +palestina +kikou +jin123 +791010 +gal220 +sunnys +w2e3r4 +19841026 +hammy123 +marsh1 +theonlyone +sexual69 +rosanna1 +030895 +soleil12 +kingarthur +andyouone +19031979 +coolcats +wanjiku +macey1 +lloyd123 +16111980 +600053 +19841986 +bobby! +skate01 +gagoako +210877 +13041995 +hector2 +teller +samsung4 +anna17 +niger1 +strikers ++ +564321 +daddyyanke +tinamarie +azalia +260779 +bonaparte +resident4 +nascar01 +110026 +ukulele +lost4ever +green321 +jeff13 +17041995 +texaco +norcal +jukebox1 +gfhjkmrf +richard6 +kisses7 +thumper123 +sussex +dirty30 +181194 +01111982 +400012 +polilla +199105 +mineonly +maintenance +star87 +hardcore. +3bears +ty123456 +24021980 +so +jayden02 +hanako +volimte1 +partridge +cloud99 +ball1n +141982 +starlet1 +bulldog22 +dylan03 +nhoemnhieu +micha3l +051277 +tennis09 +apples +cynthia12 +120699 +290978 +26041980 +iluvyou! +muaythai1 +dupadupa1 +huracan +yummie +01011964 +jonathan08 +polska2 +911007 +05071994 +buknoy +urchin +oconnor +peaches1 +11112011 +janiyah1 +birdbird +bigshot +takishima +vlasov +xuanxuan +interiors +truelove7 +raven6 +anshuman +000021 +knight11 +faith06 +qwe123rty456 +marita1 +promotion1 +life13 +bible123 +thundercats +megan21 +bigtits69 +1235689 +rubicon1 +trudy1 +14121978 +shadmoss1 +bundeswehr +040579 +sarah8 +crazygurl1 +pussycat2 +141095 +cantona07 +08111989 +clones +sarah +oliver07 +conflict +thales +luna01 +danyelle +george. +prudence1 +samuel21 +lilmama11 +050293 +bonneville +260895 +usharani +barrington +668668 +28081981 +131177 +michelle30 +woohoo! +thisisgay +alexis1234 +13666 +28071994 +c0urtney +r5gnqyrr +wembley +peanut17 +dreamworld +01091978 +change08 +123king +260279 +sarah88 +saralee +18121996 +kelantan +beerme +sexii12 +dogboy1 +horace1 +christine8 +acmilan1899 +sandy10 +harley24 +xk45xdxcyr +danny09 +patrick07 +master07 +braceface1 +boylover1 +28051994 +mistydog +krish +27011982 +douglas12 +091081 +cupcakes12 +fucku21 +amanda101 +killer98 +july1985 +16121979 +08121981 +kitkat11 +flor +studentka +dennys +myspace85 +zayzay +sherzod +appelsap +pooping1 +bentley2 +7001850 +200220 +031195 +yahoo12345 +riley07 +hakkinen +braves12 +love1234 +green32 +singer2 +lovelove3 +wildcats14 +diva23 +17071977 +080895 +struppi +alejandra +12081979 +sister4 +dustin3 +ihateyou22 +thomas98 +freitag +010172 +g86u94psn5 +159753159 +021295 +lupita13 +fun4all +carlos! +11101978 +werock! +1236987450 +mo +kondom +0902 +prince14 +fevral +blackveilb +1422 +nadiya ++ +19881010 +cycling +lovehurt +6323463 +hacked123 +hunting123 +230808 +bella9 +1wifey +trieste +angel1993 +galindo +220194 +lissette1 +baseball04 +redneck7 +ilove18 +sca +080380 +111197 +tom12345 +ilovelee +qazwsx! +justice4 +raccoon1 +gunot1 +010208 +gfhjkm11 +notengo +cacaboudin +rke: +vika1997 +teddybear! +hip +kel123 +lynn10 +ginger17 +minnie10 +flavour +ferarri +millie11 +lala16 +mmmmmmm1 +snoopy77 +vampire! +sundrop +loveme77 +7896 +punkrock10 +alternativa +democrat +xxx007 +13071995 +1212345 +allen13 +people7 +bear1 +july1983 +marco13 +cessna152 +clarkkent1 +x100pre +18081981 +samuel100 +truskawka +ysabel +hardhead +190893 +heather. +2527 +10002000 +260577 +corona69 +161177 +barfield13 +ashlee12 +12111979 +slainte +check12 +vallejo1 +troubled1 +adam06 +09051993 +fosho1 +199310 +misiu1 +nursery +boyz +butter01 +harimau +kabuto +pepper15 +lmao +basketball123 +zardoz +beast13 +060293 +23031980 +trustno1 +alekseev +pepite +140978 +july1984 +iseeyou2 +stanger +080283 +rachel99 +dr1234 +february20 +marvellous +vitor +victoria123 +12wqasxz +12101978 +121224 +18011980 +space1999 +ninja6 +sinsin +fakename +castanha1 +kancil +111096 +martinez2 +benjamin4 +akamaru +1tattoo +leeroy1 +mario6 +dreams. +170595 +papino +mexican14 +sundaram +trustno +atljhjdf +rosso +meetme +221095 +jackass22 +victor15 +finn +poilkjmnb +matamata +19861028 +hello18 +160578 +ferris1 +tony88 +04021994 +15101978 +16021996 +missy69 +homegrown +eatpussy69 +15081977 +evildead1 +acb123 +diogenes +talented +nirvana69 +cheeko +gotenks1 +chapin1 +aaliyah5 +deagle +121212m +dragon34 +cracker123 +sugarpie1 +greenday14 +brooklyn07 +qweasd +commerce1 +pastry +dobber +cows123 +06091980 +chihiro +tati123 +brillo +gary1234 +huanhuan +aaron18 +bronx718 +southside0 +flower88 +naynay123 +hawaii7 +jasmine02 +12071996 +2325 +tuwo4u9 +1piece +143iloveyo +280794 +cabrones +monkey31 +jhonny1 +mondragon +unicorn12 +sunflower5 +123456789zzz +chunchun +sj811212 +bananna +0402 +sexisfun +allaha +aikman08 +segura88 +101108 +hanifa +magelang +cena619 +jess23 +050493 +08051993 +190695 +eltoro +joking1 +tampon +tecnologia +winkle +6666666666empulgara +180495 +mario9 +alo123 +anime4ever +smriti +wow12345 +fuckoff23 +aurelie +mikesch +alive +25121977 +bmxbmx +280194 +199710 +150277 +japorms +07091981 +kasper123 +faye +010295 +qweqwe11 +brayan1 +1234567897 +space3 ++ +119 +xiaoyao +19911992 +sassafras +nurudeen +26111994 +valeron +2bon2b +160279 +redsox! +baby98 +camera12 +diosteama +blink1234 +brianna14 +garth +1christmas +maricon1 +skins1 +welcome@123 +27021982 +101972 +chivas22 +0704 +player! +sallie1 +kool1234 +carolina3 +172737 +eminem6 +chan123 +memememe1 +angels. +fakepage1 +lineup1 +farkas +walid +25101978 +angel83 +kapoor +himani +26081994 +170895 +surfer123 +swordfis +aksaray +freewill +dancer +120303 +cool00 +0077 +grace +varela +keparat +trade +rtyuio +fisioterapia +bullets1 +smile8 +elshadai +vika1994 +gameboy2 +hundred +poop77 +gas +my4babies +slayer11 +liver1 +win2000 +goodluck123 +301278 +parkside1 +abdulaziz +balaton +comandante +loveme99 +11031996 +lucio +trompeta +19851218 +stefania1 +sasuke23 +071987 + +198809 +friend7 +magnet1 +mikey22 +161294 +29071980 +playful +15121978 +arthur01 +garry1 +tester12 +changa +020208 +badboy9 +banana8 +ind +bluered +homosexual +garcia2 +05091979 +alihan +giveme +rebelde6 +klasse +shannon10 +n00dles +02081974 +carbone +winner +198826 +slick123 +22022002 +canada10 +little +bigsister1 +maybach +hunter28 +guera1 +mandar +midnight4 +010677 +sandra21 +19899891 +singer12 +joven +britty1 +mikolaj1 +fifa2007 +orange09 +laurab +sierra3 +clo +ybyjxrf +fuckme21 +bagong +judy123 +jason101 +blake01 +freefree1 +mahalkita2 +corsa1 +230373 +mike32 +love123 +14081980 +16021981 +husain +190579 +19861111 +canada99 +12monkey +stupidgirl +010495 +cooper4 +jojo09 +coochie +katydid +cupcake01 +qwertzu1 +301093 +dallastx +andrea19 +cateyes +bubba16 +maremare +beauty11 +432432 +630630 +frusciante +w2e3r4t5 +sailaja +20011978 +augsburg +1213456 +atenea +sacha1 +lama +rootbeer2 +blackmoon +football38 +1234321a +427cobra +diva22 +030409 +271988 +020595 +angels8 +moomoo3 +nichole3 +1428 +miramira +19081981 +bball9 +prometeo +958506 +sandra15 +metal13 +dolphine +sumner +riddhi +dash +ytrhjvfyn +kisses11 +0509 +rip123 +amc123 +174174 +hotmail +qwert55 +kitten10 +ashley33 +lizard123 +kisses22 +26031996 +mudkip +040293 +280780 +130277 +mobila +mylife3 +y0mama +suka +chucky123 +alleniverson +joker18 +steve-o +23021978 +09061995 +trippy +pussy07 +06061978 +nova123 +lfplhfgthvf +snowflakes +19101980 +towanda +s000000 +diva14 +tw1l1ght +050995 +24021981 +chuy123 +170478 +260178 +alex100 +lancome +maribeth +2monkey +happy2be +srilanka1 +eybdth +patrick24 +3zibuvmrx6 +finch +grace777 +wwe1234 +abracadabr +230377 +fauzan +131275 +240379 +07121981 +cristina +081179 +oleg1995 +watermelon1 +ellamae +rellik +littlebit2 +mateuszek +bitchnigga +connor5 +multipla +asdflkj +anarquia +190577 +michael96 +04111980 +18061979 +checker1 +teddy22 +fuckthissh +suburban1 +rocknroll2 +iloveanna1 +casper14 +hardy123 +poohbear9 +100700 +841023 +catchme +gonoles +tou +vote4pedro +backoff1 +osman123 +1goodgirl +vencedor +311095 +131176 +ashford +06101994 +gatonegro +pookie14 +salvaje +avelino +orchard1 +paterson1 +cholo123 +bodyshop +11111l +willi1 +redbull2 +terorist +07081981 +july1994 +181295 +10121977 +15061979 +--+ +magic01 +171178 +199102 +040806 +emily18 +burton12 +280279 +trell1 +missy23 +boopie +gznybwf +harddick +080596 +monique5 +1234678 +102103 +261295 +12340000 +2simple +spawn666 +johnson1 +headstrong +cuppycake1 +21111993 +reborn1 +algebra2 +080193 +icecream22 +cowboys4 +maluca +chris98 +12345665 +010204 +vulkan +888889 +lia123 +grind1 +16121612 +cathie +пїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕ +parrotlet +dinosaurs +harrypotter +271989 +slickrick +010595 +liu123 +hunnie1 +animals12 +maples +16041980 +determined +ранетки +dokken +020379 +7550055 +lkj123 +superbike +katie1234 +password52 +05031980 +258123 +ichbincool +jesse23 +buffy12 +240478 +sonnenblume +flaquito +searcher +mahindra +dupa666 +lol123456789 +deep123 +sophie21 +26031980 +angrybirds +lesbo +cobras1 +angela15 +200805 +kimberly10 +skate21 +dan1elle +darkshadow +drago1 +allison1 +123456789lol +steinway +07011982 +271079 +simba7 +100908 +25061981 +carolina01 +bianca11 +ryan25 +261293 +impression +170707 +rose08 +060992 +4123 +lll123 +lovestar +miguel18 +400094 +malditah +16051981 +180694 +daddio +crazy24 +dakota03 +maxie123 +250396 +nancy2 +sofija +19861214 +qwerty95 +ihateme +19221922 +carrie123 +titanic123 +13091995 +010795 +070878 +qwertasd +aq1234 +jeff23 +08021995 +airwalk1 +adidas +jgthfnjh +tyler98 +1californi +damian01 +krysta1 +13245 +199505 +kraftwerk +291194 +vissen +fatdog1 +basbas +pascua +2bfiy28byl +uzbekistan + +disney! +houston5 +tigger68 +mizpah +dmband +4horses +nok +pixiedust1 +246855 +bears12 +draken +golosa +020507 +iceman7 +199323 +brandon03 +orange08 +charlie33 +corvette +zzz777 +lesbiana +230496 +89chevy +16111994 +santana2 +olinda +mama77 +pepsi01 +07041994 +shotta1 +15041979 +12589 +drift +190505 +12071977 +raiders07 +lolote +25082508 +jazzy08 +120707 +andrew95 +0301 +paxton1 +password.. +bigcountry +skull123 +270695 +lehman +rjrfrjkf +modern1 +19861026 +seetha +2580123 +kelly21 +24112411 +13thirteen +tristan1 +captain +harleyd1 +dolphin69 +michael1 +kitten6 +281277 +shaner +tristan12 +renee01 +puttputt +parker09 +fuckoff +baller! +tampico +260394 +cpt310 +alisia +anil123 +05041982 +celine +230677 +nagasaki +carl0s +legoman1 +prince08 +aleksik +hernando +07021995 +roddick +murena +motorsport +gogetter +germany2 +0906 +google21 +120404 +mygirl2 +montego +anthony33 +10101976 +tenchu +jackandjill +25071993 +babygirls2 +1rocky +alexis. +karavan +2a2a2a +persian1 +!qazzaq1 +harpoon +27061980 +amonra +zadrot +270194 +zipzip +hfccdtn +190180 +german +230876 +angels77 +131276 +mark24 +198877 +crazylady1 +chinwe +020577 +01031979 +salvador12 +080480 +yankee123 +peppy +221174 +taylor1 +remrem +04091982 +09071994 +thomas95 +23051996 +198719871987 +gabe12 +balou +muffdiver +lilita +731731 +batmonh +198217 +aiden2 +smokey08 +bhuvana +peanut02 +ahjkjdf +cheyenne7 +1strawberr +10011979 +040594 +damage1 +airborne82 +tgtgtg +29071994 +poop88 +romo09 +10102008 +toystory2 +i<:3you +shirley +password35 +14041977 +24011981 +23071979 +вероника +09061982 +irule123 +chris44 +260595 +maya1234 +alex1976 +aquinas +130697 +shorty. +america17 +saved +regan1 +chuchi1 +nedved11 +tinka +nathan. +elizabeth12 +trabajo1 +silvana1 +mailme +292513 +jill123 +lz110110 +ilovejen +natalie10 +160606 +963741852 +delta7 +569874123 +money56 +walhalla +020180 +250277 +solecito +mambo1 +1kayla +asdfjkl123 +interdit +abbaabba +polkadots +calvin11 +flowers +enfermagem +160478 +esponja +markov +pikmin +kikiki1 +500011 +12021977 +fullerton +rebel9 +621621 +safrane +airforce1 +dontae1 +morgan00 +04031980 +231075 +habitat1 +spencer11 +mnbmnb +vincent5 +emi123 +horse5 +tree11 +shadow03 +mati123 +andrew96 +steph01 +juvenile1 +lemonlime1 +fifty +20062009 +181193 +23212321 +loveyou01 +sammi123 +02091977 +olivia23 +2500hd +idon'tknow +daniela. +missy4 +shawn13 +180576 +bryan11 +fucker23 +maverick7 +love411 +lynn23 +obi4amte +langer +04091980 +andy14 +override +brittany20 +angeldevil +19831120 +170295 +susie123 +24011993 +kristen7 +dancers1 +relation +abby07 +ajedrez +david30 +26051980 +pavlina +cherry07 +bucks +bunny8 +clutch1 +040496 +default05 +andy15 +fanatik +toohot1 +elephant +ilovejim +salma123 +increase +260993 +theron +newyork6 +brooke09 +23041979 +paradise +cricket +turkish1 +b43n6whifd +alejandro5 +tahira +sweety3 +21121979 +essendon1 +sydney3 +snowman3 +t111111 +193755 +tiny13 +hpotter +198914 +200666 +31133113 +carton +sexygirl7 +akira123 +shitass +macca1 +badtrip +kevin25 +13021981 +270195 +play4fun +6flags +gendarme +whatitdo +offthewall +motherfucker1 +iloveme15 +vegetable +500007 +paracetamol +cutie4life +bobbi +jovan1 +redblood +14081996 +krishnaa +h00ters +140578 +powermax +sammie3 +010306 +nevergiveu +hoping +shitter +babycakes! +charles23 +vixen +120809 +biteme22 +chicago13 +dave01 +grace10 +tits69 +toogood +hack123 +peanut18 +pagan1 +polkaudio1 +2125 +270478 +scorpian +ilovejimmy +qwe098 +bigears +karen10 +yes90125 +karito +fight123 +fever +nanny123 + +derbeder +creature1 +vinay +131619 +1234546 +ujkjdjkjvrf +brian1234 +dodgers5 +connie12 +161990 +557733 +mykonos +crocodile1 +200794 +280995 +gordie +01071979 +167349 +theking12 +qwerty1989 +hamza1 +darkwing +ferrum +pookie4 +ladybug10 +aj12345 +flyers88 +191179 +ricky3 +ilovewill1 +marie87 +salocin +200495 +cutey +ruffus +sniper13 +garcia10 +sabiduria +oscar15 +austin1234 +quarter1 +bullock +joana1 +sarahg +000000aa +21121977 +naruto45 +mariposa7 +success08 +600088 +marcos13 +pussy18 +mcleod +151994 +fuckem1 +samuel99 +123asdfg +chacha2 +lilly11 +boston21 +fashion7 +lulu10 +rainbow14 +lunatik +040782 +16011980 +051294 +chitti +fuck24 +hazmat +meinschatz +ds123456 +lovely101 +020794 +fatboi1 +player8 +marshmello +coco07 +131981 +alannah1 +01200120 +nutcracker +112006 +lplplp +shelbie1 +150696 +matrix21 +010981 +loser4life +912912 +13091996 +ilovemycat +031079 +fashionista +mybabies1 +301293 +kar123 +080186 +100676 +power6 +vanessa8 +bbc123 +katie9 +mexican5 +tupac96 +19861988 +tiger111 +actor1 +03041978 +23love +120297 +801122 +h1xp2z2duk +010205 +emma99 +kyle15 +moonflower +monkeyballs +qazokm +betsie +ktrcec +ybhdfyf +qaywsx123 +latinking5 +cars1234 +terrell2 +k.,bvsq +prapor +iluvmom1 +030181 +isaiah11 +zeratul +199422 +aaron4 +coocoo1 +renee14 +220779 +sandra69 +contender +300893 +ivory +251259a +1vincent +240795 +hadoken +10041997 +samia +honey06 +astro123 +abbas +190780 +lateralus1 +bobbyboy +heart7 +sissie +rossoneri +881122 +puto +demarco +04021980 +asdfzxcv1 +bitch34 +max +zane +seedsnipe +meadows1 +peanut77 +ryan02 +myword +mike2009 +5324 +worldwar +260495 +manchester123 +03071994 +nrfxtyrj +dublin22 +college08 +brownbear +cbr1100xx +lilwayne10 +land +babyb1 +29051995 +monaco1 +sabian1 +12string +257257 +rawhide +muthoni +bocman +merlin +darjeeling +deception +inspired +wakeup1 +01031996 +220196 +hendrix69 +ska123 +111196 +sasha23 +251001 +riley06 +stamper +ranma1 +afganistan +071093 +kaydee +09021994 +30101993 +ytrewq321 +e5fhxkqibw +heather14 +1234567890l +goldilocks +nokia6610 +110111 +dylan! +digimon123 +bonnie +teddybear0 +mister123 +bebop +molly06 +040879 +ironhead +kimi +300181 +sikander +badgirl12 +passwordko +hirsch +jackfrost +dontworry +peterpan2 +sunstar +vladka +30081980 +sos +marie28 +monkey111 +curling +dgaf420 +parola33 +googie +2princess +111299 +badboy4 +phish420 +yo123456 +160577 +budda +erikson +honda96 +19851024 +sherry123 +jackman1 +mybabyboy1 +peggy123 +snow1234 +160278 +boss01 +16011995 +teddyboy +king1 +idontknow3 +120500 +242 +31121978 +got +051177 +050180 +coco99 +08051980 +elijah10 +tramp +courier +cthuttdf +lovers9 +123125 +23011982 +1597532468 +13611361 +chidera +ikaa4kr257 +02071978 +sanju123 +olive123 +081984 +140204 +08111993 +narutofan1 +k1k2k3k4 +kooldude +qwerty1995 +020203 +starbright +samone +hero12 +121966 +shithappen +joejoe123 +fuckbitches +qqqqwwww +disney3 +chevyman1 +yakubu +myspace79 +tupelo +yhj34: +polopo +bailey00 +165165 +hidayat +paper2 +azimut +26071981 +30041979 +0201 +03021995 +pongpong +08031994 +xavier5 +103185 +sonic13 +240496 +maharashtra +decatur +lindsey7 +ethan11 +dolphin01 +barbara12 +nirvana6 +rascal +thomas01 +winniethep +junkfood +rambo3 +amigo123 +110497 +otrebor +pato123 +08041980 +01031972 +freemoney +tractors +recycle1 +zachary10 +11031979 +lady10 +wewewewe +jalapeno +renee21 +baby +230194 +iceman13 +ballen1 +4ever21 +lovespell +wilson +rockybalboa +coke11 +planner1 +nine11 +28021981 +141193 +73jagtk4q +061095 +repair +nascar18 +200277 +ramjet +cuteness1 +abc12345678 +thomas26 +onetwo1 +sassy4 +1520 +emelia +sexyback2 +antwerpen +cookies. +warrior5 +cute17 +peligro +henry3 +boogieman1 +19111981 +bigdaddy5 +fafa +samuel23 +0676135313 +angel2011 +lacrosse5 +edhardy1 +abacab +cassanova +abcdefg5 +ashash1 +assmaster +sugarlips +andres2 +040578 +istvan +04081978 +bandit08 +irfan123 +simple +201200 +rohan1 +25031995 +27101995 +gracie5 +forces +physical +creative1 +rebus13 +270270 +flash12 +1drpepper +drew13 +grandtheft +kandy +29051979 +kikakika +48151623 +theman69 +iluvsum1 +560002 +557755 +ascension +lilika +011986 +chata1 +lovers6 +cool09 +dalmatian +voldemar +390007 +martin09 +aaliyah4 +10021979 +ittybitty +171294 +sav +cf: +chaching +liver +hannah25 +aaryan +sharpei +eddie11 +velocity1 +28111982 +annabella1 +club +красотка +romeo11 +070594 +3e4r5t6y +10061995 +kikinou +30121981 +ihateschool +07031980 +igromania +090109 +legalize +shannon22 +ilovesteph +crapaud +twotwo +saulito +821126 +dakota00 +11131113 +scooby4 +williams3 +synyster +wow101 +shinoda1 +300593 +andrea77 +sonia12 +thanku +55555b +j3r3my +31081980 +estupida +1cricket +197310 +punyeta +lebronjames23 +16011983 +mikomiko +heloisa +dashawn +anaisabel +lokoporti +bmw530 +sunshine55 +lilac +270795 +gracie! +841010 + +supersport +sex111 +america18 +bubu123 +mossyoak +221276 +strawberri +kahlua1 +godblessu +onelove. +jesus05 +chick12 +yoruba +chris86 +ward +westminster +4000 +hester1 +eggroll1 +ktyfktyf +19931994 +janis +phoebe123 +shiver +241241 +123468 +22011980 +myindia +dmitriev +14111994 +050381 +zxcvbnm3 +gnaget +golf72 +18081995 +lfiflfif +omnislash +cartman2 +liyana +4gotten +счастье +lanier +cacat123 +seedorf +28081995 +findjob +iro4ka +gothic13 +2wwerty1 +bigdicks +781007 +badboy09 +brasov +28091994 +rfpzdrf +hailey +cnhfcnm +19861016 +pikolo +alexandra9 +mistero +04101994 +021294 +nomoney +brooklyn13 +p4ssword +scruffy2 +sammy99 +14061994 +disney07 +030877 +0108 +070770 +sammy18 +player07 +060109 +07081994 +14041404 +medrano +cheese33 +33333a +starbaby +gabriel09 +lame123 +11051978 +mechelle +aekara +347347 +lisbon +inuyasha1 +aa1234567 +michelle00 +pogime +daddy33 +youth +devious +balmoral +yuki +ciclismo +glitter2 +matilda +170778 +kessler +07071997 +mama24 +stripped +kenney +sub +brandy10 +flores13 +051295 +highwind +misty7 +justin94 +havefaith1 +socc3r +061295 +lubasha +14031996 +missy21 +saba +17061995 +brooke21 +jackass9 +ineedlove +marinamarina +vinvin +fluffy10 +171077 +northeast +danette +020276 +vball10 +sushant +shadow45 +herohero +carebear3 +ally12 +isabella07 +emma2003 +15021502 +123.abc +millionair +scroll1 +181208q +lionking2 +1234hi +lumber1 +cycle +1doggie +kevinm +unlucky +unlucky1 +baumhaus +abcde5 +baseball35 +tati +meisha +alices +apple88 +wanted123 +thering +scott5 +kaylynn +motorola12 +fishie +heartbeat1 +innovision +280295 +unodostres +281276 +paciencia +2inlove +gang +999990 +ssj4goku +02011979 +050480 +sphere +forzaitalia +dingo123 +kelsea +eminem4 +250877 +direction +09111984 +hayleigh +coaster1 +zacefron14 +thecool1 +macchia +danielle20 +jaguar123 +080793 +miracle2 +24091981 +guevara1 +italia2006 +james2008 +arsenal09 +02041976 +712712 +raine +cagney +080287 +bulldogs7 +x1234567 +kinder ++ +313 +07021993 +73737373 +knopochka +acdc1234 +26111979 +5841314521 +azulazul +west11 +noneya1 +takoyaki +liana1 +welkom1 +killer911 +ipod13 +666425 +pino +chance +051983 +babybash1 +greyson +adaada +rahul1 +audio +sex247 +blockbuster +sb123456 +permanent +redarmy +djembe +metal12 +jasmine69 +spicey1 +sasha1988 +263263 +kongkong +lexis1 +smeghead1 +kissme13 +master16 +12d8a377 +dragonlady +anastasya +luckyduck +pass4word +321654a +ashton01 +ganjubas +lovebug11 +141995 +southend1 +purple93 +20041976 +razors +clayton2 +loverlover +ewelinka +campioni +hannie +dnangel +25091979 +lasvegas12 +boston08 +120574 +slifer +redzone +butterfing +estrella7 +wolf22 +rfrfrf +789456m +nessa12 +red789 +gourmet +290478 +mason07 +sergant +1236951 +eloelo +210595 +fireandice +03101980 +paris7 +ionel23 +benjie1 +mellon1 +malboro1 +telaviv +jess69 +nobiles +buster. +fiamma +12021997 +happyman1 +21121996 +sonics1 +freedom101 +miami23 +bethany +sairam1 +hermana +nick1 +johndavid +110066 +busted! +che123 +dolphin23 +summer44 +150779 +2fine4u +14051979 +223456789 +stonecold3 +63impala +babigurl +cintasejat +dexter +what1234 +jessica26 +1rocker +260994 +joker1234 +zoosk.com +dome +brianna08 +rosinha +vir +jackjill +010477 +pennylane1 +190394 +shitbag +281989 +hunter27 +omega5 +02011978 +maggie101 +shay11 +babyboo7 +sonnie +miguel5 +dakota69 +clyde123 +gizmo10 +nyknicks +11021997 +macario +glock21 +220395 +jonas15 +cubanita +01011963 +???????????? +saipan670 +050979 +mynigga +norman12 +gangsta15 +niners49 +slammer1 +sveto4ka +171093 +tink69 +310196 +bubba8 +15081978 +element0 +inchallah +quilmes +oficina +pimboli +peaches09 +dakota8 +fuck123456 +ptktysq +isidore +mobius +gman123 +mirabella +goosey +pimps +joshua97 +52105210 +dhtlbyf +noodle2 +zhanghao +marika1 +poopy6 +k7777777 +andersson +lovers101 +270694 +070493 +matilde1 +14091980 +mizzou1 +qazzaq123 +401202 +21031978 +12031979 +kayla05 +scarface21 +bingoo +123ewqasdcxz +goodsex +dragons7 +loveandhate +cutey1 +13101979 +ass123456 +dallas31 +farrah1 +willie +081193 +mystuff1 +17011994 +091080 +marcus09 +1931 +steve3 +joseph1234 +sanosuke +diandra +30111994 +toucan +walking1 +gabriel05 +stink +sabinka +apple45 +diarra +mike1985 +timtam +119955 +kitten4 +031177 +puppy! +dolemite +reyna +crazyme +171276 +040982 +anduril +gabriela +131978 +ricardo10 +fashionist +mahalakshmi +july1992 +rocky15 +poohbaby1 +nigga15 +17101996 +joey16 +cock12 +drywall1 +31031980 +damnit! +vannessa +muzik1 +pressure1 +banana21 +010308 +28081978 +zola25 +surfing123 +1winston +yourself +zakopane +kimberly01 +insider +aust1n +13031979 +mathew12 +william25 +112011 +qweiop +07091995 +205gti +avmpwd +199125 +outsiders +hollis1 +ktm450 +ecgt +24011982 +straw1 +weyfvb +2kisses +suka123 +marmara +589589 +polonez +061277 +jaishreeram +buddy05 +blacksabbath +goodbye2 +27031994 +emmylou +yinyang1 +777778 +987654321r +1promise +danika1 +angelitos +omg +160294 +law123 +080595 +200111 +a741852963 +mustang24 +softball03 +18051981 +nameless1 +hitachi1 +pisellone +cameron03 +03071978 +0803 +bratty +sparkle123 +arsch1 +pensacola1 +123monkey +230495 +happy33 +redick4 +290881 +030978 +firewood +280694 +lover12345 +151200 +brittany +2224 +stevenash +teamo11 +pirate13 +aruba1 +ziggy12 +121999 +dollbaby +304304 +qdxzc43gba +vanguard1 +200394 +linwood1 +09021981 +vilnius +291077 +barrio13 +01021977 +hogehoge +yannick1 +18071995 +arsenal3 +james44 +14181418 +gg123456 +tagheuer +25272527 +199229 +crystal6 +nikita1995 +gwapo123 +mymyspace +smile99 +170379 +muffin4 +dauphins +pinklove +yahoo0 +gfhfdjp +snoopy15 +fivestar1 +raiden1 +081987 +25041979 +wilfredo1 +tyler00 +620620 +tyson01 +trumpet2 +warhammer4 +dixiedog1 +danielle17 +ilovemax1 +nono12 +racquel +purpose1 +r00tbeer +bandit21 +asphalt +warhol +2314 +prince69 +555555q +cliffy +zz +demetra +popcorn6 +colton12 +09031982 +newmexico1 +diamond. +amanda02 +kiss1947 +199810 +suvarna +msnmsn +happyhour +rayne1 +gitara1 +killacam +krazy +15091979 +200506 +010281 +07011984 +samuel07 +november09 +romans116 +jason77 +bigdog5 +barbapapa +carmen3 +cap123 +eagles15 +3kids +josh1 +parfait +megan23 +cassidy123 +05121993 +26091980 +gators11 +199525 +denise08 +11081977 +tetley +winter3 +lucas1234 +duane +carnegie +xavier05 +220476 +browndog1 +214dallas +wordpass12 +123apple +14111981 +andrea25 +radhakrishna +viper69 +23041977 +joeblack +federer1 +nikka +smilee +spelling +redskins26 +rad123 +abc123# +beats1 +071207 +christo1 +12081977 +24111980 +13145200 +jazmyn1 +online2 +laika1 +demo123 +jesusmeama +hayden06 +15031979 +armando123 +ioanna +carmen7 +smith2 +mariana2 +19841029 +nightmare +bulldogs09 +27091995 +folletto +tinkerbell12 +w1954a +120697 +grad2007 +keroro +5432 +stephanie. +hopewell +lizardking +lynnette1 +piggy3 +hoodrich1 +loveindia +06021981 +thirdeye +tuntun +100years +benson123 +11081979 +potenza +papier +ryslan +pooper12 +nene14 +ilovehim22 +flaka1 +010196 +120874 +holdenv8 +010478 +needwork +jack666 +love102 +22002200 +satanic666 +lildude +m987654321 +reunion1 +paula12 +swamphen +01011999 +seriously +azul13 +2qefx7t3sy +alina12 +9900 +mickey19 +ramchandra +playgirl69 +think456 +09091995 +vienna1 +не +jawbreaker +crayons +197319 +w9998999 +3452 +smiley101 +nikita2010 +bringiton1 +kiara12 +1vampire +dragonfly3 +selfmade1 +hawaii05 +cookies23 +280478 +12348878 +iloveme01 +runescape3 +190478 +guess2 +sexybaby2 +m1m2m3m4m5 +latin +chaos13 +17071994 +82airborne +memito +kiki00 +tiffany18 +311001 +ducky2 +babyboys +james30 +gail +lolita +10071978 +qianqian +verizon2 +lily13 +bandaid +ayodeji1 +290379 +031178 +ilikepie! +drift1 +pom +myspace31 +margareth +medeiros +nbanba +machoman1 +mahnoor +shadow98 +20091996 +divx +01092008 +nikola123 +amirkhan +cal123 +cubbie1 +maggie17 +william88 +141294 +stefan12 +851010 +abdula +django1 +beauty3 +aurelie1 +selena13 +ltz400 +1alabama +sexythang +1011111 +morgan03 +clover123 +ohshit! +chemicals +poohbear18 +garrett123 +rockwell1 +ringostar +vehvfycr +cradleoffilth +jane1234 +0802 +gameplay +star26 +sexygirl01 +needletail +wewe123 +eric07 +1234!@#$ +kailyn +140207 +miranda7 +arnold123 +rover123 +fuzzball1 +hildegard +winter04 +23111978 +pacman2 +restore +815815 +10041978 +shakal +120907 +justme! +maddog12 +bigdog7 +061982 +vfhvtkflrf +novgorod +jesse. +romance! +mylife08 +alejandra7 +limabean +198529 +queen01 +incognito1 +peyton01 +ihateyou5 +lovespell1 +pharrell +battleship +leolion +freya1 +rafita +keineahnung +beatles2 +florzinha +budapest1 +marilynmanson +joaovitor +04071981 +generals1 +08111982 +ngocanh +244001 +alex83 +shooters +loirinha +zif1313 +sweet88 +29111992 +bluetooth1 +12061978 +1atlanta +fulcrum +tigers69 +lildaddy1 +friends15 +sieben7 +231993 +jason20 +11061995 +franchise1 +r26nnxjx7n +single101 +alana123 +121303 +28061981 +tupac7 +bambucha +current1 +bobbyb +16011994 +t1gg3r +2black +chance22 +wave125 +310180 +jesus27 +goofy13 +ruth123 +291989 +110796 +hola22 +ashland1 +silvia +rrr123 +lizette1 +360001 +dreamon1 +papaya1 +brille +greenway +156324 +malena1 +farthead1 +archuleta +bamaboy1 +jhkjdf +jopajopa +11031978 +doremifa +250876 +indian +090581 +momof6 +yahoo6 +1april +childcare +marlee1 +f00bar +jacqui1 +billard +sin666 +adr +deleon1 +1903bjk +edge +zxc123 +clairebear +ursulet +lkjh +11071996 +loquillo +africa123 +sanchez13 +hyperlite1 +buddy77 +27072007 +20042006 +sneha +301095 +fierce +042108 +epa650 +oscar69 +eumesma +55555t +sorciere +pizzapie1 +chichi11 +24071994 +fkg7h4f3v6 +170878 +julieanne +spider4 +zero000 +crackerjack +skully +jyoti +ludhiana +gabriel23 +hannah95 +rtyfghvbn +nose +bighouse +vader123 +packers123 +blessedbe +shonda +obelisk +booger69 +696969j +qwerty28 +monica15 +271278 +holidaysecure123$ +27021980 +14021977 +145353 +simpleman +divina1 +megan15 +sicherheit +s0ftball +49494949 +skittles14 +vertex +failure +charmin1 +shinedown1 +04041978 +slayer7 +031984 +postoffice +notyou +longfellow +310395 +03071995 +112005 +mike666 +05071980 +jemoeder1 +198588 +gomets +mercury7 +oreo10 +casado +600087 +madonna +jehovah +kandi1 +197922 +campos1 +catherine3 +lilmama01 +bert123 +scream123 +siciliano +smokepot +25061978 +killa22 +090482 +224 +fuckem +081181 +abc123456 +homestead1 +winston3 +weevil +314 +tomlinson +030183 +healthcare +julinha +18091994 +allie12 +emre123 +philly2 +gangsta22 +pumper +hay +bearshare1 +rakesh123 +1veronica +dat123 +parrish +123456al +pegleg +backpack1 +cherry24 +adriana13 +1peewee +lachula1 +awsome12 +101111 +steves +giants08 +080382 +ladyred +11091996 +aero123 +bigdaddy23 +bang123 +window123 +eastcoast1 +reggie11 +310378 +eiffel +friday11 +10031979 +padisco +03021980 +tina15 +123456jr +25121996 +19841028 +dauphine +hanhphuc +lolliepop +110505 +m1cha3l +elmo01 +130278 +password777 +jose09 +along +zxcvbn7 +19851123 +bajsbajs +morgan17 +150576 +jamuna +310779 +adam15 +27021995 +ilovecake +198316 +ytyfdb;e +hybrid1 +northside4 +di +chevy57 +0703 +maddux +funnyman1 +viper7 +dominique +lovely1234 +logan22 +gemini77 +friend4 +smiley5 +sluts1 +0503 +dc123456 +om +kitty18 +backlash +indya123d +gayman +280895 +cytujdbr +jimmy8 +ashley77 +zachary6 +dgkallday1 +robert03 +10081979 +11111b +08061995 +chelsea06 +forevermor +password0 +lala69 +colombia10 +roland7859 +slava1 +russell123 +cassie21 +blazeit +gwendolyn1 +volcom5 +valera +5525 +irock101 +putanginamo +220378 +levi12 +nathen +lukeluke +199101 +susanna1 +420stoner +seahawk1 +darkness0 +jobelle +pizza9 +hagakure +iloveme6 +201014 +iloveshawn +cena +brave +00000m +rabbit13 +rocky09 +titania +168168168 +roland123 +spongebob +10111977 +1danny +roosje +mama99 +jessjess +united10 +gbrfxe +soccer2010 +666420 +cocker1 +hailey08 +061194 +romanroman +greeny1 +tippmann98 +magnifico +shimmy1 +akusayangkamu +quake4 +lilboy +zhimakaimen +linde +heffer +chicago10 +rain12 +december01 +abby10 +68charger +jeremi +021982 +diana5 +arkangel +cutegurl +741085209630 +sadiemae1 +19841022 +bailey9 +sk8terboi +146146 +dirtbike7 +ladygaga12 +15031996 +heather18 +366366 +angelboy +asterlam +dadsgirl +050380 +baby79 +imtheone +august +drumset1 +betrayed1 +b696969 +yohana +04081980 +ala123 +lucozade +mymama +1montana +maximus123 +tippy123 +stupid69 +p@55word +siddhu +moose13 +jeremy09 +05051996 +cooling +lover88 +backstreetboys +dun +miley11 +carhartt +bluem00n +091278 +lizards +fritzy +ryan03 +kitties2 +198814 +emily04 +crip66 +16031978 +197930 +jaimataki +wsadwsad +159487263 +best1234 +bigsky +kool13 +club2030 +roxy15 +ringring +jamming +fear +12435687 +reaper69 +caught1 +excal007 +yasmin12 +natacion +ilovedave1 +josh88 +1397 +borat1 +thanh +srisairam +bakura +griffen +bk.irf +no1cares +2519 +211002 +wjsswj +lotte +scooty +chacha12 +hookem1 +102100 +vladislav +060794 +010508 +apple. +purple30 +15201520 +chucky13 +0125 +travis16 +lovemedo +jarell1 +church2 +kashyap +600032 +poisonivy +republica +300976 +bushido7 +dalmata +23081996 +mitali +130876 +march2009 +notyours1 +sean22 +piss +p1mpin +231175 +crime1 +676869 +271194 +mmmnnn +nausicaa +biondo +20111978 +inventor +yearbook +timmy7 +21314151 +dell22 +lemon12 +060183 +21121978 +linking +din123 +17746052 +210794 +bubba07 +20031978 +17011981 +elmoelmo +baylor1 +kfc123 +151195 +amanda87 +jeff01 +zxcvbnmm +bball08 +perempuan +iceice1 +loli +16091981 +120473 +monster17 +040809 +08111990 +sabrina10 +paintball4 +weedweed1 +blckd_sa_unpaidfee_oct06 +kittens3 + +lucette +060893 +27041980 +lenora +170479 +22051979 +4r5t6y7u +smile14 +justin87 +5ahc2v875z +rocky123 +bryony +juan16 +ewqewq +lion1234 +xavier7 +larryboy +mercedes01 +palangga +09031995 +1mouse +melissa09 +massacre1 +baseball42 +bronzewing +foxmulder +pesciolino +maddog123 +sadiya +hebrew +nuttertool +amanda77 +rottie +bugatti1 +violet123 +drumnbass1 +art131313 +050501 +311094 +30303 +batman19 +198220 +asdasd2 +brown5 +030979 +10051977 +simcity4 +27081980 +deshaun1 +touche +sabato +lilbear +06051980 +izabel +february18 +happy2007 +bluebaby +iverson23 +coco24 +chipchip +black33 +031294 +raider13 +pappy +carlos26 +emilien +300379 +0604 +201195 +volleybal1 +bijou1 +crystal14 +booooo +fuck16 +panda01 +daman +kellogg +194 +bogosse +titans12 +trouble7 +freakazoid +pimp44 +super1234 +shanghai1 +astoria1 +140595 +cello1 +morgan24 +111111111q +pretty17 +miamor2 +byyjxrf +american12 +171079 +hellyea1 +daniel55 +tennyson +27031995 +1sexyboy +felipe01 +marcus08 +20091979 +delight1 +27031980 +italia +adidas5 +figvam +inline +smith89 +shane01 +latrell +14021976 +101203 +duffbeer +090691 +james34 +kazumi +windows1 +parabellum +198105 +t55555 +1spencer +515000 +sexy777 +theory +terminator2 +25021980 +midtown +050696 +06011994 +040383 +primavera1 +271078 +laboratorio +joedirt +261195 +400088 +zdenek +gangsters +urmom12 +alfaalfa +wapiti +06101982 +mad1son +14011995 +honey101 +football03 +february12 +maurice +evropa +tucker5 +bigd123 +blaziken +110798 +silver17 +savannah5 +05061979 +poodles1 +mark1 +31121979 +jasm1ne +sunflower4 +linda22 +mama111 +flower33 +29041995 +851212 +kingman1 +catriona +galactica +dang +fenway1 +cab +gerome +lilnigga1 +bennyboy1 +02051975 +abstract1 +chicago21 +280177 +star92 +kilgore +blumentopf +sweetthang +199418 +nonudity! +nuo0725nuo +poppins +11061996 +291079 +mitchy +manman3 +03120312 +maddy2 +020979 +101174 +yfcn. +spider99 +getbent +actlg728 +pedro2 +armitage +15995123 +pebbles01 +getcrunk1 +821028 +putra +dewdrop +minnette +santeria +20051979 +tower +kostia +cherif +sprite12 +angpogiko +811025 +love7777 +depeche101 +scott7 +wass123 +110708 +power23 +kassy1 +240977 +141993 +hat +wahoo1 +natalie07 +maddog2 +dtown214 +martin! +bankai1 +200376 +virgo123 +pachuca +redwarbike +400060 +031093 +7e9lnk3fc01 +211095 +18121979 +160295 +09091999 +sylvania +deimos +24071995 +moksha +nagendra +angel1997 +armand1 +121300 +28101977 +radiance +k3zedhmexs +badman123 +cowboy23 +sadgirl1 +181095 +adrian09 +tyler95 +wsxwsx +198214 +pljhjdmt +monkeys4 +irish13 +20081977 +aradhana +aaron16 +sameena +nagamani +ricardo07 +july1986 +drilling +findlove +pho +air123 +04051980 +120909 +30121978 +shoot +qazwsxed1 +111111aaa +napoli10 +chris0 +louise21 +jack2010 +11121997 +10061006 +700006 +zach13 +nikol +devin7 +170578 +230596 +yx12345678 +ishaan +evette +may1986 +robinson +superman26 +sus +lakers4 +macho123 +151196 +friends0 +050805 +xxx12345 +priya1 +missydog +suc +hottie0 +billy1234 +123green +sashadog +kiska +ibarra +hapiness +expresso +sexy456 +06121980 +28111981 +181078 +5element +cenation +tfzwf44idb +tommy21 +aqwzsx123 +bc1234 +101060 +0504 +ohmnamah23 +playplay +alaska +maggie04 +1593572468 +cubby +jasmin01 +husan0890 +wethepeople +vardan +panocha +bigdad1 +atkins +210177 +canelita +16081995 +pinki +zarazara +laila123 +15101977 +gabrielito +jabberwocky +trapstar +12421242 +qwert +bigsister +123123p +swagg123 +blood9 +babyjoker1 +henry7 +pearce +poseinfopass +learning1 +jasmine04 +happyness1 +b00mb00m +daddy06 +vania +alpha01 +mercurial +82828282 +100400 +sereno +191194 +solidus +singleton +sonny2 +1carolina +jasonjason +jamesw +ska +c44n6vijfc +farheen +slayer01 +duck11 +haunted1 +myspace56 +ladysman1 +javier23 +pedro10 +iluvu13 +spanky11 +teresa01 +david04 +joel11 +03011982 +198329 +mateus123 +bandit23 +290394 +rererere +nate11 +04101980 +ella12 +applepie12 +brayden08 +bellezza +shakila +catdog22 +trujillo1 +27091980 +visa +1mariah +1hockey +impalass +jerome +arlingtonp +novartis +mohan123 +03111981 +jeshua +080508 +251275 +loudog +pokemon69 +5qwerty67890 +291985 +qazxcvb +801010 +3boys1girl +administrator +shaylee +paige13 +blue87 +821021 +210976 +swimming! +azerty11 +castel +ilovedogs2 +chopper69 +shelby8 +cheat1 +tension +hotrod123 +pacsun1 +godchild +peaches08 +1qazxsw23e +madelaine +kala +rayden +minotaur +scouser +indie1 +010296 +140377 +beachbabe +jackass. +dragon42 +251980 +piscina +ziomek1 +lisette1 +peregrine +mortimer1 +001991 +inuyasha5 +yahoo4 +dont +eleven1 +sanpedro1 +22011994 +caleb01 +050877 +katrin +25011981 +110797 +hostel +lamont2 +zitrone +blood11 +brooklyn6 +jacks0n +eclipse99 +blue90 +kangaroos +150777 +0501 +bigdog22 +pra +merry1 +boobs! +libran +rebecca5 +darla +jack2005 +unbreakable +250279 +goldy +spanky +anuoluwapo +getmein +261095 +fuckyou06 +alicia7 +markova +richgirl +24422442 +chris100 +amelia +brutus +pele +osipova +lexicon +23061979 +tommy1234 +stason +170577 +waqas123 +010979 +051990 +071178 +030879 +beaumont1 +19851987 +icebox1 +mhine1 +adam18 +skeet +olivia6 +greenday123 +rockrock1 +290678 +phoenix9 +debtfree +hitman23 +romanson +db +pharaoh +elephant +magic22 +jesusloveme +george6 +26041978 +290194 +booger01 +171177 +030679 +argentina2 +110676 +danil123 +password5 +jackie15 +uzumakinaruto +021178 +20041977 +launch +yellow20 +que-veux-tu +4u2nvme +playa23 +jarda +50505 +anna2011 +batista619 +thi +engenharia +dukenukem +amojesus +judaspriest +music4u +bballer +steven19 +fresh09 +troy14 +moon22 +louie2 +hooker69 +fortuna95 +801212 +007008009 +krystal2 +101107 +081294 +sexyman2 +23101994 +050608 +160179 +dong +rams28 +1manarmy +030496 +tanner22 +zhang +money26 +carman1 +hardcore +equitydev +lolo13 +260879 +14themoney +1inuyasha +theone11 +oldlady +bianca +estella1 +andover +black12345 +2589 +rachel17 +bulldogs08 +250778 +brazil123 +bigballer +22061996 +boucher +ryan2007 +yankee7 +16121995 +mrmagoo +florida13 +anchor1 +10101972 +overcome +96mustang +196363 +sims2 +bubble11 +220696 +taylor92 +200876 +friday01 +quercus +19851126 +movingon1 +hullcity1 +speeds +123qwe1 +kaitlyn12 +minimax +16061977 +zuzia1 +190195 +rabbit7 +foothill +741456963 +f246865h +09051979 +kamelia +beechwood +halloduda +pathan +blasco +sangria +snitch1 +lost12 +bigdaddy10 +francheska +godman +crappie +231992 +nicole32 +0107 +201076 +january08 +198829 +marypoppins +barcelon +17101978 +blessed07 +chaz +ovation1 +0901 +rangga +booga1 +newlife201 +120671 +18101979 +abbydog1 +boy123456 +lynn69 +pocket12 +13071980 +neuken +tinker23 +190794 +05041981 +stars! +t-money +sniper01 +paul21 +010779 +lindy1 +chase10 +jeffrey +cuteboy1 +blue222 +100999 +leopards +paints +ghjrehjh +171095 +070282 +ss12345 +viernes13 +moimoi1 +mambo5 +050895 +changepass +checkitout +notmine +23071994 +hello34 +deviljin +goodfella1 +baronn +gocards1 +bailey16 +28081994 +19072007 +13011301 +050282 +bella04 +15051978 +coconut2 +malcolmx +allen23 +300193 +smo +zyltrc +02120212 +killer321 +demain +melanie13 +keebler1 +25121975 +asshole14 +100808 +070981 +bethany2 +iloveluke1 +inlove4 +amouna +tequiero12 +070581 +nascar +dolphins7 +963852741a +girl22 +legolas2 +jeep123 +haseena +c654321 +221096 +murphy3 +travis5 +02101977 +rats +e-mail +yamaha46 +blowfish1 +1721k1721 +aphrodite1 +ameera +jerry13 +140202 +justme3 +123690 +monkeys101 +080994 +enterprise +teddybear8 +kenny01 +balloons1 +geroin +busted2 +maria88 +blackmore +browne +ridebmx +hisgrace +country12 +dogma +florida +lukino +anhhung +noobnoob +fairfield1 +130996 +adam08 +021077 +bambam69 +1isabella +lauram +fuck17 +130294 +kizzie +291295 +minato +katia1 +821023 +20111979 +davidka +19861121 +cotton12 +dziubek +titimi +27091981 +27061981 +120607 +teen +miamibeach +marina2010 +happiness +chevy09 +katty +sweety13 +scooby14 +space11 +ferrarif40 +basketbal2 +090976 +ilovealex! +250294 +281195 +williams +lightimes +781022 +210197 +roger2 +start12 +wallflower +happy00 +23011996 +loverboy +suffer +ghjrehfnehf +alex34 +structure +scotia +141010 +murphy +android1 +120898 +310193 +qazwsx7 +20121977 +tigers6 +16081978 +francis3 +302012 +triplet3 +hottie34 +789456123z +000999888 +amrutha +anthony89 +jessee +punkista +corinna1 +farhan123 +mascot +pokemon00 +lust +advanced1 +vlasta +tootles +jane22 +michael31 +25071994 +radharani +04041977 +amaretto +03101978 +salut123 +valkiria +nightcrawler +word12 +erin11 +maxamillion +herbalife1 +qaz4532 +anatole +henrys +10091979 +superman87 +achiever +101172 +11011979 +carter5 +kippen +fritzi +lover34 +fuckyou32 +emma21 +puggy1 +marley3 +cardenas1 +persimmon +lizzy2 +141075 +rachel. +161993 +dumbdumb +twinkletoes +reallife +janedoe +rootbeer12 +pendragon1 +nicholas14 +scimitar +001905 +533533 +50cent123 +cammy1 +plumeria +schach +panther4 +lebron6 +harley66 +trotter1 +dick101 +bakker +11223366 +fyz +pieman1 +november06 +okcomputer +sebastian9 +blockhead +trythis +1234567890r +elaine2 +01100110 +020495 +pennydog +qwe123zxc +636234 +local1 +lanalana +artem1996 +mason08 +11091995 +shumaila +purple02 +dallas! +osama +fdcnhfkbz +1qaz2wsx +coco09 +coolhand +narutokun +jobros1 +asas123 +19871120 +jessica92 +hello20 +hotbox +080483 +1emily +bass1234 +flyhigh1 +191079 +anjani +experiment +leg +misia1 +mark17 +lasher +killme666 +shagufta +892892 +jazzy09 +1255 +amande +peanuts2 +football49 +sa12345 +020607 +landser +universita +raven01 +2908 +claret +carter23 +linkedinlinkedin +14021997 +giangi +200575 +star94 +100796 +goddey +bb12345 +isaiah05 +251274 +transform1 +08021994 +02101976 +781024 +dossantos +dupablada +gabriel15 +down +13111978 +pimaout +телефон +aaa111aaa +monkey777 +060897 +30111981 +19861023 +20041978 +greentree1 +29111980 +marialuiza +14061979 +justin31 +198218 +26011995 +jupiter5 +poczta +spider8 +199322 +maman123 +nov1988 +181278 +05011980 +miguel17 +22882288 +pink04 +rickross1 +08011982 +monkeys13 +cat666 +gallo +1cooldude +daniel101 +itachi123 +jakubko +1688 +inuyasha10 +not4me +sandy22 +aaron! +anhyeu +boston07 +jarjar1 +jesuschrist +080783 +310895 +gwapo1 +190679 +rose101 +coolkids +070481 +200178 +302016 +maverick12 +sg +rainbow24 +angel79 +jason99 +151993 +271277 +pogi123 +bach +jasons1 +dickinson +mommy69 +06021982 +maitre +figueroa1 +libertas +220594 +ballball +nautical +502502 +30051993 +gizmo5 +lovergurl +buster16 +jamrock1 +modeling +peaches +luchino +boricua123 +haha23 +riccardo1 +blue78 +051079 +jamesa +600014 +beanbean +modified +keane16 +scorpio21 +jesus2000 +angelyn +palmier +diplomats1 +redrider +theblock +passwort! +sarinha +medic +mydog +redneck! +090283 +tab +brennen1 +ichich +billions +15021978 +babygirl78 +zanzibar1 +diana14 +sorella +pooh06 +202030 +190707 +lightyear +sanchez12 +280577 +begonia +bloodrayne +playhard +pointer1 +george15 +noknok +sexxx +cyrielle +121518 +30111980 +carrie +211193 +disney10 +199225 +17051981 +maddy12 +darragh +meninblack +271990 +261982 +kelly +killer87 +291983 +twoboys2 +13041978 +theflash +alejandro8 +95959595 +buttcrack1 +shawn23 +sambuka +pikachu +blume1 +wilson3 +mathews1 +hoilamgi +multipass +04011981 +lolo90 +nodrog +1kisses +musico +smokey09 +jason88 +01121995 +penang +matr1x +johnston1 +correia +161094 +muckel +lurdes +191177 +03101994 +theman23 +4eternity +porkypig +hi123 +ali110 +jenny08 +jasmine03 +1278 +xxxpass +poochy +mommy30 +n1n2n3 +180676 +11011995 +sn1ckers +armada1 +newport123 +28071995 +wwweee +pratiksha +6699 +harry1234 +191294 +joshua96 +sofly1 +336336 +peaches9 +luzifer +211194 +dotty1 +sixflags1 +sebastia +2q2q2q +desiree2 +0403 +bebita1 +117 +shelby67 +cuoricino +duality +kyokushin +austin20 +marco2 +ronin1 +niggaplz1 +201985 +flower09 +anna99 +201009 +101204 +220178 +surenox3 +fuckth1s +040282 +09091978 +aur +170994 +ilovegreen +outlaw2 +230976 +loveangel1 +tommy4 +daddygurl1 +12021978 +asd1234567 +111276 +lavigne1 +dancingqueen +cassie16 +1lovemusic +nappy1 +eltigre +mrkitty +baller4lif +esther12 +mc9ad9w2ux +cancer +23051978 +mark07 +blazed1 +ballin01 +04071995 +monique11 + +swag123 +june1983 +258963147 +mohana +portfolio +ghjcnjz +160878 +newport12 +hardcore13 +miniman1 +chris1 +bigben07 +lfc4life +thebigboss +831010 +alenushka +samson +pocoloco +beck +kopretina +heart13 +juster +ivana1 +machina +20061979 +olawunmi +17081980 +jabalpur +040284 +040281 +golden7 +ladiesman2 +ilovemywif +140178 +nick12345 +gohawks +220576 +07061994 +05011981 +15031978 +claire +1boston +music18 +alukard +anushree +bluewater1 +nurse2 +helloma +jessie16 +staticx +200177 +1bigman +jojo08 +gldfzpy +peckerwood +22051978 +rewq1234 +1fluffy +zz1234 +dizzy123 +asusasus +moron +0721 +matthew98 +melkor +111077 +wzq8xcfxqm +shukla +itsover +dick23 +saumya +susann +ryangiggs +tebogo +0209 +dolphin21 +javier11 +241176 +39393939 +230101 +sexy420 +pothead69 +rusty5 +babyblue13 +buffys +magodeoz1 +180777 +040384 +ikbengek +kasandra1 +020878 +cool100 +zandra +mercedes7 +matlock +poopy11 +pooop +murphy10 +steven06 +renee16 +harmonica +dustydog1 +20111996 +jake2008 +kristen +sammie +080784 +micha1 +woshishen +kodak +200278 +vans13 +160895 +colorado2 +nicole31 +rangers1873 +nich0las +xbox360 +claudia7 +alastair +777555333 +wildcat2 +googles +sassari +lucius +bufalo +angel67 +florida4 +19861216 +angel81 +040895 +warren123 +crazychick +11021996 +internet. +fate +mario69 ++++++++++++++++ +praktikum +28111993 +jessie15 +joseph04 +ptybnxtvgbjy +211276 +12011996 +laflaca +screwu +david29 +koolsavas +imogen1 +analsex69 +lilboosie +aaron69 +driftwood +sami12 +hearts7 +single4 +asad +hotwings +erwin1 +warped +jack55 +prince1999 +federation +bulacan +muhammad +198514 +19942009 +aquario +09051995 +06071981 +00123456789 +angers +sarah06 +xh248zhhtm +matt00 +batman45 +20121979 +29091979 +sunset2 +euronics +171194 +120506 +170494 +sydnee +17121977 +lilflip1 +ruchika +sparky99 +eragon123 +cameron21 +babyko1 +!q +riley5 +guarana +170694 +dragon96 +aaaddd +bulldog9 +passrett222 +getsilly1 +29121980 +courtney6 +201275 +forever0 +scholes18 +informatika +197822 +youngbuck +199120 +panthers7 +fukoff +promote1 +redbull12 +230675 +tapper +ganondorf +nutsack1 +coco16 +19401940 +wolverine +grove1 +steven24 +blbjnrf +joshua95 +02031976 +12101996 +olivia02 +pepsis +211983 +panthera +kennedy123 +turtle6 +minnow +romanenko +pfqwtdf +111108 +aga +sabita +petewentz +arizona +whatever1 +14031995 +1cooper +aiden06 +ivan1994 +031094 +lovelife3 +clover12 +snoopy24 +dominos1 +2229 +wwwooo1234 +martell +01071978 +4vdaxp542g +freshmen +22021981 +coolchick1 +27011994 +olimpo +toocute1 +bennington +santa12 +autumn13 +68chevy +deus +050382 +amanda27 +jimmypage +jettavr6 +1eastside +midnight6 +qwert12345 +cooper23 +116 +sandy1234 +06041995 +1beast +km1234 +23021977 +badass21 +konnichiwa +1jesus1 +kuning +allegro1 +bmw328i +toro +20061996 +1blondie +261991 +kisses01 +honda300 +junito +nickjonas! +pimpc1 +cody69 +jonas14 +cppzfrc933 ++ +250795 +291294 +toyota11 +fifa2002 +drumstick +mariah7 +julie13 +connor03 +25051976 +giggles123 +shorts +101208 +omnamahshivay +mila123 +kitkat13 +dance23 +rambo12 +terenaam +barrow +240876 +cali14 +snipes +060281 +hamradio +020676 +halo10 +23091979 +240994 +sexmeup +110776 +flaming +liline +letmein0 +vangelis +100975 +mrs.brown +vjzgjxnf +chava1 +southsid3 +030377 +dustin! +njdevils +1miller +coco08 +dimabilan +123456go +accenture +171195 +111997 +080583 +30111995 +050182 +27011995 +191278 +250196 +travel2 +miller23 +lorna1 +verbal +pinnacle1 +barbora +241075 +james92 +linkedinpw +noodle123 +business +mystikal +skyler2 +kucingku +june1981 +100497 +wezzy1 +george27 +cooldog1 +tiger2000 +zozozo +victory2 +yonkers1 +sanson +220894 +king00 +natty +kofola +akril2442 +gfccdjhl +intimate +alwaysandf +ecureuil +and125 +nnanna +55555z +judge1 +partha +devera +rikki1 +111966 +01111992 +prasanth +skyking +x123456x +03011980 +bcrich +4422 +123iloveu +evenflow +24091980 +anna07 +jianjian +batteries +080993 +28021978 +qwertyu1 +teagan1 +161980 +gg +02071994 +carolina. +16011982 +nichelle1 +171078 +melissa07 +112004 +210999 +jun123 +ololade +kaleb123 +vlad1994 +120897 +110043 +omarion21 +001967 +anna1983 +hansen1 +a7ckuntldy +denis1997 +berserk1 +arizona123 +regal1 +134 +china13 +angel1991 +411019 +123789852 +mike02 +181992 +marcus +28031979 +emma2009 +lazyboy1 +201202 +dx1234 +billygoat1 +parekoy +giovanni +estrella +crickett +all123 +sargento +peace1234 +canguro +mr1234 +jayne +mimi08 +rockon11 +20081979 +chijioke123 +miracle7 +wy1000000 +supercar +blind123 +sparhawk +torben +casting +ancient1 +ruicosta +pumba1 +mapleleaf +mybaby09 +susmita +lilj123 +britain +25031996 +121071 +molly09 +ilovejosh2 +21101995 +serfeliz +claire2 +johnnycash +portugal +james45 +gerard12 +020977 +marajade +blocked +268268 +++ +nfyznfyz +271077 +13579135 +vojta +dfcz +02011975 +pdbdfby2xx +180379 +isaiah7 +phuket +800008 +anna08 +buttonquail +20101997 +marietta1 +000webhost.com +lawnmower1 +july1982 +stooges +151176 +preety1 +charli3 +111295 +qwerty82 +furby1 +333777333 +argentine +bigbad +emmagrace1 +160494 +maxwell5 +101006 +220475 +l0veyou +rocksteady +lop123 +florida8 +19861123 +suzette1 +dima1999 +котенок +110297 +311093 +casper4 +021409 +sactown916 +peter22 +budala +rollie1 +19871988 +060494 +28031995 +31101993 +timbaland +candy25 +lisa10 +babe15 +oscar4 +bai +max2005 +paintball5 +13101978 +audrey123 +katherine3 +01011997 +repytxbr +nishizhu +110299 +10051996 +bobrik +july1997 +packman +falcon69 +10091995 +billy4 +28121978 +monkey30 +tmac01 +291094 +gem +tigers9 +123123g +cvbn +123456www +101206 +121097 +gavroche +martha2 +olivera +imkool1 +q1234q +821025 +199128 +bastille +makemyday +denpasar +12356790 +03101982 +goduke +25051978 +masaka +blue96 +peluso +rebecca10 +euzinha +andrei +197801 +laura16 +sparrows +abc123456! +5588 +pendeja1 +gfh +20022004 +190280 +cuatro +03071979 +bhabyq +muttley1 +ricardito +latitude1 +sayang90 +schoolbus1 +01041995 +oakridge +07031995 +gay4life +zero666 +alanya +justintime +foosball +musica. +okay12 +forzatoro +cooler123 +18121978 +jenny1234 +hazzard +raiders99 +section1 +matthew0 +honeydip1 +chiquito1 +300479 +board1 +prince4 +learn +deadmeat +061179 +eueueu +23081979 +ancona +06091981 +dragonman +tgzvf55idb +19841027 +austin94 +marissa3 +sakamoto +speeder +malvern +pierluigi +vallejo707 +payment +2708 +hiroko +lunanueva +sdfg +070593 +momsgirl1 +gfhjkm2 +fuckface2 +olayinka1 +asas1212 +raiders +pimpman1 +xfhkbr +blossoms +catty +done +wobble +aurevoir +fuckmyass +ptcruiser +19850101 +gracie22 +karnataka +panda101 +05031994 +chowchow1 +cvbnm +crying +anatoli +133001 +victory123 +24091994 +girly123 +yfcmrf +music2010 +antonio18 +melon123 +karate2 +alex1977 +05011994 +mokona +coaching +tomwelling +reddy123 +dishant +mikey69 +apolon +140479 +momndad +17051995 +powerman1 +alabama +firedog1 +jeremy06 +sonu1234 +290378 +270995 +121108 +tekken1 +jazzmin +secret77 +natureza +030577 +london123 +executor +bulldog23 +nokia1600 +22031978 +04041996 +081194 +ar1234 +ca123456 +zxzxzx1 +kurczak +putas +smiling1 +061988 +2514 +angel1987 +asdf00 +bella2007 +rotterdam1 +miguelange +jimmy9 +trouble13 +gators2 +hugoboss1 +samone1 +mybusiness +17151715 +121198 +23051979 +freedoms +ilham +puma12 +satchel +april2006 +burgess1 +yellow00 +veronica7 +080293 +livelife2 +spartak1922 +lilly13 +petruska +steven9 +caca13 +assman69 +365214 +@@@@@@@@@@ +chr1st1an +donald01 +ap1234 +1239875 +1234567889 +cookies8 +cece12 +juanpablo1 +asdfghjkl1 +gabriel6 +tiger34 +redshoes +rodnik +deloitte +bandit6 +bahadur +macias +holly5 +walker01 ++ +140995 +victoria. +4649 +14081979 +skank123 +qwerewq +stasia +soloman1 +angels02 +baranov +780504 +luver1 +zzzzzzz1 +alicia10 +vasilina +number99 +bananas7 +mariahcarey +graduate08 +clear1 +samir21 +neronero +stocking +boylover +vikas123 +franklyn +951951951 +kazuma +nephilim +clements +peaceman +thatha +friskie +den1ska +lynn15 +030578 +lesego +kisulya +dakota15 +26091993 +peanut33 +aaron6 +123456zxcv +sereda +jayden7 +weight +goldflake +black0 +220976 +angela! +wigger1 +bluegill +14031978 +12121973 +a134679 +1bobby +london44 +diablo6 +kenny23 +boggle +puffdaddy +sharkboy +robertina +imaloser +nini12 +scamp +cleaning1 +180279 +58565254 +ranma +hottest1 +jhane +ivan1989 +25222522 +colchester +barborka +jamie10 +12122008 +jewelry1 +tammy12 +727727 +090782 +tyshawn1 +nessie1 +130575 +25101995 +pollen +25011980 +jay-jay +`````` +20041979 +shianne1 +nate23 +madden12 +cocodog +chimchim +forreal1 +phillies08 +gfdkeif +jackson. +bigdaddy13 +kaskad +123654789q +cristian +110475 +loco69 +andre11 +papapa1 +ashley97 +161295 +bonsai1 +nana06 +lj: +pretty07 +cheer8 +master89 +enomis +010608 +2mylove +lindsey3 +al1716 +alicia22 +stomper +mummy2 +0213 +savana1 +250994 +pakistan47 +totoybato +george8 +toyota99 +29081994 +12345654 +8686 +rom828 +clover4 +allyssa1 +24685 +hottie25 +scout2 +loveit2 +charlie03 +nokiax2 +stank1 +singsong +tiger321 +julius123 +miriana +30011982 +inlove07 +red123 +minotauro +19101979 +luis123456 +robert93 +eatshit69 +pirata1 +shaddy +290694 +01051976 +19001570 +allthat +0106 +dima1986 +anything2 +ryan +oioioi1 +1469 +йцукенг +horses +131195 +100375 +ненавижу +poiu1234 +1235678 +27091994 +memorial1 +ads123 +honda03 +pavel123 +15091978 +140394 +mala +jack16 +270278 +silentium +121199 +710710 +fuckyou111 +adrian06 +davidr +flower77 +badass11 +felino +221978 +primary +211075 +3310 +060994 +bulldog4 +210296 +qwe123! +678900 +dollie1 +197619 +0921 +newyear08 +molly99 +dios777 +musicrocks +timoshka +askim123 +dunamis +15051975 +guillaume1 +general2 +payton12 +diva21 +25101979 +rawalpindi +ihateyou4 +300694 +458458 +mikey6 +03061979 +king19 +dartagnan +240277 +jessica03 +sebastian5 +dodge2 +forlife1 +199419 +flower18 +2662 +benjamin! +ariana123 +beemer1 +12051996 +791127 +jamesr +behappy2 +winter2011 +150476 +south12 +24051996 +vika1996 +2244668800 +2people +jolly123 +051982 +barmaley +basketcase +060282 +myspace86 +comp +hottie19 +pusssy +madison200 +holly13 +198007 +cocacola7 +skyline12 +1q2w3 +guyver1 +doorbell + +040794 +cayman1 +ernestine +gerber1 +150495 +bunny14 +211991 +jelena1 +tink16 +imsohood1 +560103 +030396 +softball32 +dudu123 +redneck21 +03061995 +180478 +poopoo0 +balla123 +golfer69 +yeller +bailey98 +karim1 +logan6 +200596 +21062106 +mnbv +02081976 +21021996 +lidia1 +amour100 +sasha007 +deliver +danecook1 +call +kitty55 +snoopy07 +roxas1 +00990099 +red234 +georgy +rfybreks +smiley +whitefang +may1985 +sniffy +yilmaz +19851011 +diamond24 +charles21 +09121993 +xfk3bxezqj +mickey1234 +newyourk +honda89 +011980 +loser12345 +18021978 +johnson +ares +chris85 +phoenix01 +sarasota1 +181994 +lulu01 +2906 +malachi2 +gold11 +floripa +casetta +winnie11 +oguzhan +mama1970 +04061994 +number34 +beograd1 +fuller1 +michele2 +creatine +p000000 +nimisha +weymouth +polo00 +granger1 +27091979 +03031996 +qweewq1 +201983 +all4god +sooty123 +120772 +eagles9 +amor16 +hotbaby1 +jack007 +040894 +lilly3 +abbygirl1 +superstars +oliver09 +samboy +joinme +qazxdr +041177 +15041995 +lev +donna12 +cagnolino +polita +1police +frank69 +22081996 +040877 +redder +bball6 +gangster4 +8123 +1967gto +19861218 +240178 +12081978 +011094 +bigworm1 +1hotrod +ted123 +2hot4tv +blood69 +falcao +mustang92 +jordan29 +37217086 +070393 +beto13 +ball22 +thumper12 +3377 +soccer35 +08081996 +07081978 +foofighter +jeff69 +yummy69 +wilderness +1indian +cfkfdfn +iceage1 +100775 +rhbcnz +henry11 +pineapple! +080896 +michael55 +2333 +barca123 +hotpants1 +pequena +lasvegas2 +bro123 +brody123 +rooter +bradipo +silversurfer +kiki99 +loveyou15 +lilman23 +miamore +meandme +1819 +celery +rofl +sizzle1 +280195 +diciembre2 +1inlove +1138 +crafter +killer91 +rayados +hawaii! +cestlavie +alyssa16 +maddie5 +jacque1 +surrender1 +hugo1234 +james2010 +280379 +06031981 +brutus123 +bella88 +austin88 +1357911q +rfkbybyf +fcbayern1 +longhorns3 +cherrys1 +03091980 +romel +070494 +haselko +serpent1 +mama1960 +myspace* +11111975 +789789a +confused2 +babs +wonderful2 +charmed +icecream9 +stadium +redstorm +51535759 +180179 +29061980 +03111980 +j666666 +vazquez1 +zahira +dear +140896 +compaq13 +sys64738 +baby86 +robert02 +venkata +24041979 +saraba +pickle7 +120873 +ladybug9 +ellehcim +197555 +malta +28071980 +richard07 +delta4 +mattman1 +andruha +lilolilo +bonefish +23071996 +babygirl44 +balthazar +blood101 +marvin11 +franks1 +callas +080493 +claudia13 +george24 +imahoe1 +3ub9xm53xi +super14 +27081981 +megryan +ataris +sir +haha101 +iloveu18 +02031974 +erika13 +dhananjay +internet11 +grande1 +peace9 +15121977 +confirmed +singlelife +smetana +250496 +a246810 +1718 +septembe +joejoejoe +jujujuju +mamaypapa +091979 +cedar1 +bandit4 +dollhouse +197830 +ilovemom! +pepper16 +jonasbros1 +jacklyn +yamaha69 +senhasenha +22031979 +perroloco +skyline7 +lilwayne4 +pokemon98 +vincenzo1 +17021977 +101273 +sophie23 +27011981 +golfman +197212 +1424 +maurice3 +precious5 +15021996 +hellboy666 +acevedo +frufru +dickhead69 +steven20 +mario +ghbdtn +199129 +asesino +26091981 +fynjyjdf +eric09 +mama1964 +zhangyu +06021994 +daddy#1 +iloved1 +steelers#1 +111075 +kisumu +291278 +triada +iamtheone1 +thesun +17011980 +inuyasha15 +199911 +ploppy +412 +cneltynrf +dakota98 +cancer2 +27111978 +neger123 +x1x1x1 +mostaganem +040609 +757757 +jake00 +iloveblue +141176 +01234561 +chubby123 +splender +jayboy +maveric +adg123 +redskins +luxeon +3horses +050777 +10101968 +1lovechris +christina! +wibsh56kec +letras +asdfvcxz +jesse15 +dayang +wildcats11 +petroleum +lilmamma1 +solaris1 +11101995 +tony25 +071984 +010207 +lawton +robert28 +scorpio123 +abdellah +maxwell +letmein9 +15935728 +adebayo1 +super15 +tragedy +askimbenim +anneso +1771 +14121977 +sarah99 +rand0m +bumhole1 +jkjk +surbhi +shoes2 +070980 +chinedu1 +juggal0 +elijah04 +110875 +greggy +nissan300 +holiday +ibadan +holiday123 +qwerty1993 +pinkness +carter22 +diddlina +24011980 +loserface +matrix10 +821015 +aldana +masloboinikova1987 +1november +jellybean7 +hahaha5 +guitar15 +tina69 +remilekun +sammyjo +741230 +31011979 +princess81 +godzilla +050694 +ilove1234 +100398 +19871024 +bashful +gregory3 +twins3 +cats22 +serenity3 +zxc098 +120300 +spike1234 +epsilon1 +iloveu88 +00000000000000000000 +tailor +18031996 +1asdfghj +woodbine +aaa888 +gonzalez12 +36912 +100396 +220195 +33443344 +aaprintbb +santaclara +maggy1 +customs +patapouf +dread1 +samual +22111978 +predator2 +dcltabih01 +060894 +cricket7 +4rfvbgt5 +jaja12 +tooth1 +mamapapa +888111 +cupoftea +250295 +anthony00 +319319 +0602 +humans +mara123 +jess10 +sanchez2 +nenene +310877 +1turkey +coach123 +010696 +wolves2 +bellatrix +092 +classof99 +mooses1 +030478 +poepen +chimera1 +kleine +51286700 +160779 +123123123123123 +25051977 +mylove15 +badboy15 +westside11 +liverpool05 +1q2w3e +goodwin1 +billy23 +tropicana1 +lovecats +rosewood1 +suave1 +tyrone79 +24061978 +sarafina +nicholas. +alitalia +431001 +cookie06 +ueptkm +020409 +anais1 +aslan123 +camp +stairway +rowley +scoobyd00 +071293 +19851030 +161982 +05081994 +tvinktvink +kyle16 +diva08 +06011993 +heybabe +ziomek123 +monument +portugal17 +191980 +17121996 +queeny1 +050878 +culinary1 +alison12 +bassie +jumpman1 +manola +020206 +21101979 +pierre123 +bailey77 +sensesfail +faith77 +rio123 +kartal1903 +kimora +wood123 +140396 +falcons07 +03051979 +781003 +sixkids +panino +worms +121102 +fallen3 +kevins1 +referee1 +barry20 +pw1234 +ginger101 +rko123 +password47 +runner2 +audis3 +shanae +codyboy +priyaa +trek +210295 +nicklas +master12345 +passion3 +babi1234 +password_1 +bailey17 +whittier +19051978 +150877 +barrel +blood22 +240377 +asd123321 +shadow04 +south3 +france2 +kissable +athlete +navyseals +snuggles2 +24101978 +noviembre2 +peugeot406 +deadeye +080580 +bmwe30 +light12 +bitchbitch +submit123 +cdtnkzxjr +chelsea88 +ronald +killroy +bronze1 +18111980 +jesse69 +sqdwfe +050492 +tha +90107142a +danielle07 +drugs +john05 +zagadka +zxc123123 +seniors06 +svoloch +norwegen +twin12 +gallo1 +billy10 +shemale1 +010408 +loser16 +080807 +show +dementor +kobena +ballard1 +jea +qqqaaazzz +kollol +231981 +pa44word +surgery1 +dixon +college09 +heaven22 +kirstie1 +02051995 +bigpun1 +1cassie +qwest123 +sammy +counter123 +benbenben +140575 +maryj420 +frances2 +25352535 +manner +020608 +02041974 +blazed +101270 +blubb +lbyjpfdh +061989 +coolbaby +denise14 +jacob +200894 +midnight22 +060283 +121197 +5678dance +260294 +180477 +bas3ball +lolnoob +shorty20 +06121981 +231978 +gazprom +nupe1911 +violet12 +bigworm +051094 +vivian123 +pussy6969 +will22 +final123 +bear07 +bloodgang +1rooster +999999999999 +110376 +19061979 +julia7 +hottie94 +panther10 +151094 +money +sassy14 +solutions1 +600005 +abcdef5 +5starbitch +chois777 +mike123456 +preppy +deuce22 +puccini +02051976 +19021995 +jeffrey3 +sylwia1 +12091978 +199025 +kukuruku +livinglife +morenita1 +14081995 +oneshot +271991 +rocker101 +10011978 +120305 +skate9 +californication +plant1 +iloveu0 +cody21 +tribe1 +freddie +samuel5 +07041981 +spagna +wedding09 +19081978 +dima1989 +mittal +player17 +3128 +26111980 +felony1 +badcat +leon13 +chipper2 +shelby07 +godisgood! +michael86 +goodboy123 +cat123456 +victoria08 +18011995 +vqz6qyo294 +duhduh +171277 +britney +august123 +domain123 +ak1234 +whatsup123 +5522 +vfuflfy +rockstar. +jon101 +dragon30 +american2 +abcdefgh12 +040193 +camila01 +waldorf +milani +cassie23 +spit +mementomori +280678 +solitario1 +soup +qwerty112233 +hadiza +thissucks2 +213546879 +abarth +080482 +071179 +15091995 +bondar +tobeornottobe +9090909090 +r654321 +dayday2 +elijah03 +michelle03 +qweasd11 +22091996 +zak +laney1 +011295 +deidre +chris90 +rollingstones +crochet +asdfzxc +27071977 +crap12 +rekbrjdf +25021977 +05091978 +jacquie +29081993 +musicbox +bigdogs +261076 +eyeliner1 +watitdo1 +09101981 +polo13 +lady21 +asians +qqqqqqqqqqqq +050181 +bubba101 +blueline +password43 +cocacola! +24111994 +lagbaja +treytrey +werwer1 +billy! +k.,k. +architetto +090595 +pershing +drunk +gshock +31051979 +djibril +brandi +kalifornia +coffee22 +ain123 +10041977 +jongjong +tears +friendofyoucanmake$200- +kevin99 +whitley1 +paige11 +198929 +marines1 +sexymama10 +paloalto +gustavo12 +honda00 +olivia21 +bills +brentwood1 +piccione +sk8mafia +eltonjohn +071983 +rowan +christiano +050900 +malyshka +dakota6 +alfa123 +jazz01 +diplomat1 +sunshine05 +150396 +jazmine2 +olivia8 +14371437 +lovebites +123132 +020709 +february16 +bigballs2 +qqq123456 +paulwall1 +ash101 +marykate1 +codigo +yellow08 +10121975 +jeancarlos +matt06 +qwerfv +1q21q2 +jade23 +bulldog6 +pivoine +grzesiek +estudio +666667 +kagandahan +060382 +tbs13 +09111992 +bachata +kk12345 +pfhbyf +25412541 +loverz1 +kayaking +010479 +panthers! +121210 +zachary8 +rothmans +spicy +honor +21081979 +muskie +vikingo +22041978 +19881212 +bobby +pelusita +14031403 +sandals +14071407 +26051994 +doggy11 +ithaca +04101993 +30041978 +271982 +catsmeow +oyindamola +121262 +castellano +ipodtouch1 +12345zzz +twingirls +newlove12 +lp123456 +loco11 +closer1 +gemini06 +miami12 +boulet +031995 +surfing2 +190693 +shivan +cgtwyfp +2528 +mpc2000 +zinzin +kiley1 +allochka +c123123 +morgan98 +555566 +308308 +dookie2 +joycee +overcomer +199023 +paige01 +megan4 +010307 +sexygirl23 +harley55 +peyton12 +jdq4j8lu3a +iloveanna +06051982 +141070 +7891011 +vickey +jordin +iheartu2 +dragonage +champion +rowena1 +live12 +monkeyman2 +201194 +2515 +25021995 +susanne +thecrew1 +metropol +cosmo2 +chloe09 +180577 +shines +160178 +120499 +rocket01 +caiden1 +gandaako +sebastian8 +chrissy123 +filip123 +22021997 +240378 +171994 +c111111 +bobby14 +elloco1 +dfktynbyrf +25081979 +lovesloves +childofgod +180476 +luis69 +nfhfcjdf +hoopla +cameron23 +11011978 +teddybear6 +29081980 +49ersrule +bitch02 +110275 +2q3w4e5r +moonriver +0523213511 +220676 +payne1 +1288 +sexygirl9 +gucci2 +2518 +readme +ser123456 +reymond +shantell1 +310578 +postal2 +jessica93 +15061978 +untouchable +caden +zx12cv34 +galileo1 +along1 +maulwurf +andrea1234 +that +edward8 +456abc +110675 +funkytown1 +jayden21 +09021995 +771177 +21061978 +vaches +080982 +alegria1 +noname123 +sdsdsdsd +chester22 +callum01 +howard2 +scared +armenia1 +mireia +532532 +120400 +mark25 +clarinette +kokotko +ghostface1 +060677 +isaiah5 +fatouma +palmtrees +happening +200878 +anna2003 +iloveu07 +1524 +teejay1 +cdjkjxb +showbiz +124589 +subwoofer1 +diaper +sweets12 +3219993xx +040696 +21061996 +redfire +iamme +leonie +200608 +myspace001 +iloveme101 +1two3four +purity1 +valleyforge +06071995 +250793 +bigbob1 +cac +23142314 +191095 +16121976 +030293 +lovehina1 +antonio6 +sexycani +051383 +shelby08 +chicago6 +carey1 +tweety19 +197929 +drummer12 +lovie1 +17091995 +68chevelle +espinoza1 +betmen +drink7up +kurdistan1 +getmoney11 +chidinma +196464 +bianca10 +201208 +muffin +jorge10 +jamieson +funk +hater2 +octave +kangen +webbie1 +carlee1 +haribo1 +katika +dolphin10 +ily101 +08071980 +etoiles +record10 +love1010 +schnecke1 +420420a +dominic7 +taliesin +passion +martin99 +georg +qazplm1 +davinchi +28101995 +06101980 +79camaro +hometown1 +walter11 +23041978 +20021997 +cora +olaolu +ender1 +marocain +010279 +vj +eleonor +kiki21 +jabbar +ilovenick2 +winter2009 +firewater +cin +tony19 +040381 +iniesta +hgf4h3fhf +13271327 +gamer12 +granny12 +fisher2 +robroy +silverwolf +master66 +5544 +07061981 +ilovejorda +jd123456 +rosebud123 +o1234567 +123_123 +999998 +antoine +831013 +allison5 +co2008 +lipton1 +cabelo +coolkids1 +13051978 +fuckoff88 +30101995 +hitler123 +110028 +karina15 +17012003 +vanessa6 +020575 +dagmara +jiang520 +colima1 +24kobe +nepal1 +jhajha +kiesha +grumpy13 +20101977 +cristiane +devin3 +260195 +dasdasdas +fahbrf +09111991 +vigilante +pontus +030307 +edw +11aa22bb +harrydog +unlucky13 +mgoblue +gillespie +barcode +778866 +abdullahi +olga2010 +24021996 +study +19951996 +montana1 +geoff1 +musashi1 +restart1 +didi123 +boomer10 +worksucks +sandra5 +160977 +gloves +dork12 +04071979 +ktyecmrf +amamam +270293 +frankreich +my1stlove +1905gs +040474 +chick3n +sex +090893 +ladybug6 +sinead1 +ujhjljr +pokemon88 +tinker9 +141096 +kirstin1 +fiftycent +hardcore7 +reserved +redneck08 +robert30 +++++++++++++++++++++ +ye123456 +hotie1 +1530 +oct +moose3 +151515a +samsung69 +michelle02 +ihateyou11 +brian08 +juggalo123 +060698 +pierpaolo +nick92 +040294 +babykitty1 +q000000 +maryna +240895 +erica13 +8marta +dakota9 +150808 +chouchou +n2xcfgjcvr +sexybitch7 +meomeo +bro3886 +genesis3 +apple17 +johncena! +hantu123 +mygodisgood +ninja69 +flblfc +2manykids +lakers88 +wingwing +rocket22 +countdown +babiigurl1 +271196 +123456r +dan +charger06 +01081977 +cheese44 +27101979 +ensenada +p8ntball +gertie1 +steve22 +papyrus +300577 +muffin10 +270179 +01021997 +schoolgirl +041195 +ddd333 +olajumoke +wondergirl +altec +27121979 +brooklyn09 +josephine +pontiacg6 +camile +bono +skippy11 +diable +stoffel +hitokiri +neopet +wichita +marten +nikitosik +dancer17 +capitaine +chrischris +antwerp +123e123e +raiders9 +juggalo6 +040695 +1421 +theman22 +excite +password64 +martin24 +ameena +judas +linkedpass +lovinit +vanessa16 +jonathan17 +silmaril +55255525 +741852963q +bailey69 +shelby4 +blessed! +tropic +custodio +198928 +usg242 +240279 +150676 +ballin6 +1toomany +123456pa +motherwell +antigua1 +winter2008 +lovemonkey +19851015 +201075 +marruecos +myspace84 +always123 +311294 +ghjcnjghjcnj +1359 +akucintakamu +64chevy +acrobat +rayray7 +gaara12 +5262499 +171295 +a123654789 +jujubean +reynald +poop111 +kristin +gamlet +kamari1 +666666g +melissa24 +justin95 +viridiana1 +juggalo13 +27051994 +heybabe1 +yahoo99 +27111979 +asdasda +molly69 +blinker +chokolate +berry2 +littlered1 +vasili +snoop2 +tdutybq +ilovebryan +lucifero +johnson4 +dinner1 +xiaozhu +myjobs +08081977 +88488848 +841028 +network123 +martin17 +samdog1 +villas +bronte1 +pauljohn +12041976 +february17 +phelps +bobby9 +123killer +mabait +020795 +sucker2 +19831020 +ginagina +rancher +qwerty987 +65impala +blake3 +ghostman +0331 +chicano13 +bandit77 +laptop12 +allister +021079 +daddy16 +200496 +jack04 +vfhbyf123 +loveu! +abi +mexico06 +adrian4 +buggie1 +wiktor1 +090193 +eddie23 +beckham +privet123 +198803 +spalding1 +melanie! +29121979 +allblacks1 +tdubdub05 +mexico25 +040679 +helena123 +111106 +ass101 +whyme? +05021994 +boys2men +yeahboy1 +smoke12 +cagada +555666a +harlie +gratis1 +deadlock +smokey99 +olivia14 +precious13 +redsox8 +tutifruti +esmeralda2 +lightfoot +199228 +buddha +magic6 +lola23 +cinthya +081279 +170795 +201102 +marybeth1 +120100 +kim12345 +lol100 +26061978 +3bitches +panda23 +creole +07101994 +sundin +happyfeet2 +dragon52 +091193 +142434 +secret00 +091293 +3fozaqb33q +bigbang123 +180778 +radmila +djerba +rajawali +oran31 +lfieyz +escapethef +gavilan +hannah88 +wolfy1 +cousins1 +loveisgod +jennifer07 +mafalda1 +hotaru +2dragons +121069 +19861015 +04091979 +iamlucky +ksenija +kayla17 +alucard666 +street123 +welcome22 +280394 +qwerty1986 +easyeasy +srivastava +strongbad +rotciv +ulster +school07 +xavier21 +babylove3 +charmer +jr1234567 +p0k3m0n +dimo4ka +dylan04 +noel12 +daisy15 +w8agc47kla +may1988 +05061978 +hummerh1 +040576 +heather07 +animal11 +della1 +diana22 +mollygirl1 +oracle123 +kevinb +270994 +04111982 +79137913 +021983 +kirsche +bhabyqoh +ema +130396 +220272 +040180 +smi +tanja1 +elena12 +mariac +19851020 +toshiba2 +sexydiva +ana123456 +webkinz12 +gotrice +yunita +280707 +pizza6 +jayjay01 +170278 +123456ff +zebra2 +system2 +035690 +number55 +pookie +cameron14 +jade10 +bebop1 +nastusha +051980 +toughguy +denis1994 +omonoia +chris82 +jeopardy +198586 +portugal12 +partyhard1 +110974 +08031979 +1loveher +121265 +toyosi +maha +jovan +qqqqqq11 +landon123 +210175 +shawty123 +black55 +071277 +fuckit7 +mkvdari +littleman3 +madeline +surround +0903 +fabric1 +alltheway +doom12 +chargers13 +scouting +gay1234 +bandit99 +1stoner +tennis21 +specnaz +13031978 +1xxxxxx +hanka +bart12 +jorge2 +poop45 +16121978 +scooter6 +britany +dome69 +travis199 +katelin +flocke +holland +@yahoo +1lovebaby +forty2 +biggay1 +212224236 +ammaamma +redman2 +fktrcf +lilly5 +trousers +allegria +strongbow1 +mamuka +tenor1 +matt633 +estudante +calilove1 +06051994 +citroen1 +estrella10 +brenda14 +jade08 +27081994 +tay-tay +sea123 +jiji +210575 +122123 +r1r2r3 +stuffy +sunshine32 +08011981 +damian11 +soldier2 +honey +disney5 +def +191981 +28081996 +ticotico +leighann1 +cjhjrf +webcode1 +angle12 +icp666 +wwe.com +111007 +smurfy +katy12 +nitram1 +action123 +andre23 +jenn5366 +qwerasdf1234 +makimaki +monkey68 +mirka +mackdaddy +store +olalekan1 +nasrin +200001 +190379 +chechen +rugbyman +salvacion +180695 +123741 +031077 +erica11 +mylove24 +13771377 +sandra14 +031078 +120974 +24111979 +rockstar16 +vegeta2 +beauty! +andre10 +virgen +magda123 +elenaelena +penny7 +momo10 +calender +drumming +gago +tope123 +hobiecat +doggies2 +310178 +masons +pickle! +dodgers11 +fyfnjkbq777 +overseas +skittles10 +bocephus1 +katyusha +28972323 +rocky12345 +quinto +denise09 +22031996 +120603 +226622 +chevy98 +bombom1 +ismail1 +pietra +furniture1 +lolcats +rollins1 +sunday7 +poplar +meatman +factory1 +211195 +30071980 +fishing7 +281076 +b1teme +jazmin123 +password65 +metoo +300977 +ilovenikki +23071977 +emma2000 +jimmorrison +030677 +pageup +sexybeast! +suhasini +redlight1 +++ +goldengate +010896 +dates +290479 +kalbo +dude15 +tomasz1 +902860 +6shooter +rishi +rebel4life +lolada +pakalolo +chivas16 +youngluwe +02031975 +pes2010 +dreday +fyyf +balling +evette1 +29041981 +raver1 +425425 +rankin +alluser +morris123 +lolek11 +nd4spd +jobert +siopao +ryan2006 +nanna +devilz +212121q +rapstar1 +oluseun +jktu +lilmama15 +sarah19 +young23 +113114 +84728472 +ezequiel1 +gromit1 +yahooid +lollie1 +iloveu101 +nate1234 +18041996 +1618 +28061980 +aelita +212321 +adithya +prezident +143000 +mitchie +1kelly +disney7 +babubabu +hawker +sodomie +grandpa2 +fuck +p3anut +ronaldo77 +buster25 +06071994 +08041981 +060993 +kailua +ivan1992 +marijo +jay101 +poopey +cherep +rusty3 +shutup12 +iloveu24 +snoopy17 +asdf13 +240177 +115 +nicky2 +portman +230708 +rockstar123 +june2002 +textile +goobers +pimpette +nokia6020 +myspace03 +sunlight1 +imsexy2 +darkn3ss +sorina +19861024 +290895 +shona +pippy1 +martin08 +november01 +montano +allahhoo +myl0ve +041984 +13061306 +30011978 +helenka +loveyou +motdepasse1 +25051996 +140876 +duran +shakthi +monica. +ilovealex2 +lauren05 +taxidriver +666665 +password001 +12121313 +08021981 +22121977 +queensland +bratz9 +lov3ly +youyouyou +killer100 +classof2011 +ashu1992 +13121977 +corey11 +shelia +swisher1 +camaro2 +houston23 +chicken24 +100275 +anastas +prince07 +vb[fbk +251294 +carranza +loverboy7 +maddog69 +god101 +loris +vojykgi959 +145623 +281983 +07101980 +seo123 +070193 +lovelove123 +bigguns +snoopy16 +willow3 +19861226 +02111993 +fresco +whitesox05 +061983 +bball09 +harry10 +hotmail11 +buddy18 +1jasper +bambam01 +aragorn +angelheart +stryper +04061996 +31121995 +ambre +titties2 +foxglove +phobos +bogie +1234tt +hartnett +777777s +1fucku +tallman +greatday1 +teamoo +100176 +chevy04 +tiffany15 +1fender +1coolguy +miyavi +sashimi +6655321 +220975 +pass55 +batman666 +computer20 +guthrie +19851111 +josh20 +saxaphone +pitbull69 +dolphins3 +19851125 +sweettea +lamalama +hailey5 +angie11 +patty12 +krystel +19871023 +1balla +elisa123 +19011996 +aga123 +sharma123 +scorpion12 +gabby5 +221075 +080408 +310878 +08091980 +001007 +jamie21 +gonefishin +sandman2 +shrooms1 +ilove16 +pakkness +fredom +onion +110400 +cleaner1 +100776 +sanjay1 +becool1 +280894 +060309 +barchetta +1q23456 +h0llyw00d +17111979 +malade +041293 +tobacco +cdbymz +180895 +gisselle +ida123 +080494 +cerveja +pepsi69 +misty13 +05071979 +281176 +197710 +14101978 +qwerty1994 +shahnaz +michael97 +kayla18 +flatland +warrior +05111993 +kiki15 +swat +grace22 +olga1987 +lips +720720 +1xavier +230303 +tosca +refillmotives +ruslan123 +lovely19 +stiletto +anjaneya +index +06111982 +angel999 +kissme5 +growth +19841017 +qwerty1988 +emily02 +eeyore12 +nigga10 +210894 +masala +lorena +apple +animal69 +011294 +111274 +spirits +friendofeveryemailyouproc +booda1 +021981 +slipper1 +yodayoda +peugeot106 +armin +danny9 +311276 +famous11 +janganlupa +snowstorm +31071995 +qw1212 +mistake1 +deano1 +alberto13 +google6 +luna22 +underpants +pouncer +m121212 +26071995 +joshua89 +kikumaru +grigri +kaikai1 +loveyou08 +sexy36 +highbury1 +snooper +18081977 +sephiroth +ashley1 +brandon98 +henry01 +cancer13 +hottness1 +angel1989 +free4ever +fakespace1 +131413 +090282 +powerfull +16041978 +821018 +password57 +march2008 +app +180278 +cubs1908 +444455 +private123 +141981 +stupid101 +lovebug13 +david00 +julie +dukedog1 +4561 +celebration +dukester +furman +hunter96 +peekab00 +sparky5 +forsberg21 +741852963z +stressed1 +1239 +1lilman +andrusha +ficken666 +03041979 +28111994 +milady +pickle11 +cinco +606606 +tugboat1 +120507 +dick13 +player09 +qwerty11 +simpsons2 +pooping +260877 +07031993 +dementia +1boomer +hellhound +blowme! +iloveyoujo +needmoney +xavier09 +southport +babygirl56 +labirint +615615 +07081979 +version +marley22 +nando123 +cd1234 +turandot +creep +200809 +oso123 +alexandra0 +1236987456 +jayjay22 +practical +lalala22 +30111979 +mommy16 +tennis07 +iloveyou42 +fuck07 +fucker8 +tito13 +qqqqqqqqq1 +legal +spiderma +unhappy1 +welkom123 +290879 +ilovehim5 +sonicx1 +010908 +221074 +master20 +naynay2 +orange19 +jab123 +lucas23 +111169 +choose1 +playgurl +wesley01 +kimmy12 +guapa +room101 +dukes1 +tete +chantell +23011997 +rebound +ssssssssssss +15061977 +fullerton1 +morris12 +060594 +komodo1 +17011996 +luiza +cookie00 +110896 +parent1 +0421 +sac123 +iloveliz1 +cowgirlup +050993 +pietje +college123 +cipollina +martin. +paintball0 +massari +fenerli +suck1t +compaq +30101979 +vtx1800 +guitar9 +croatia1 +11061979 +12121970 +159357258456 +dragonfable +sunshine02 +gonzo123 +031988 +yggdrasil +melimelo +kmdtyjr +morgan18 +p1ssword +preview1 +cocacola3 +lyts123 +19021979 +051981 +141312 +horse7 +matt88 +anna09 +159874123 +colocolo1 +momo22 +mnbvcxz +carota +bharat123 +346100 +02121979 +sunflower8 +shafiq +1jayden +03011981 +21091979 +fuckit420 +290395 +080780 +angler +jasond +07071979 +camara1 +sara23 +tyty12 +400020 +funny5 +mexico88 +muse +051179 +tomoyo +bac +artem1995 +lilmama5 +lichking +11061106 +100874 +sean23 +northside2 +akbar +naruto19 +rinrin +bethany123 +keisuke +deedee11 +25091996 +townsend1 +0908 +gillou +123466 +sowjanya +198315 +laural +stakan +stayaway +29091978 +lazaro1 +linked1n +07051994 +ficken69 +160995 +sana123 +valeria2 +741456 +243243 +shadow28 +krayzie +sandra18 +pussycat69 +ontheroad +hoover74 +1234432 +hellohi1 +colten +fucknut1 +qpwoeiru +adaaja +wilson23 +shawn22 +wilbert1 +denise5 +ट: +masato +gershwin +heartland +03051994 +equilibrium +lonley +23031978 +loo +adam16 +sasha1987 +george06 +camille2 +nargis +jaguar +ride +wu-tang +jessica94 +123music +07011981 +199523 +mutter1 +apa123 +kundan +wzr8ycfxrm +virginia2 +darion1 +eugene +7732844 +francis12 +december05 +pot123 +fishbowl +chivas07 +rwanda +24121979 +307307 +310778 +159258 +soleil123 +bellavista +florentin +0024657 +29111981 +cupcake15 +andrew94 +5555566666 +sara7272 +19952009 +friends06 +bigmoney2 +wyatt123 +radhekrishna +orion2 +fas +04011993 +153 +0987612345 +198006 +1qweqwe +warriors2 +07031982 +marlen1 +080782 +kurt123 +jamie4 +rostov8888 +james29 +101199 +cello +spicer +geordie1 +harley96 +rbceyz +g-unit1 +060194 +ololo123 +james00 +210676 +041988 +radiant +tiffy +paparazi +196200 +david2000 +tayla1 +spawn123 +july1980 +billups1 +03101995 +thetwins +oioi00 +kyle69 +florida22 +nitro123 +nofx +tweetie1 +broken3 +020596 +bass11 +781020 +7777777c +1949101 +231994 +030803 +panther1 +chrono1 +frank5 +jh5thrwgefsdfs +talleres +pacman12 +jayden +hulagirl +1change +123kkk +tata11 +emmajean +bootleg1 +darkone1 +qwerty02 +cocacola +scales +020609 +window2 +megan16 +february15 +260777 +agatha1 +keira +beowulf1 +100dollars +wenyin12 +19851228 +drugfree +victoria23 +dancer9 +prieto +07021981 +05041995 +monkey123 +fifa2011 +shahrukhkhan +fireball2 +orochi +01061977 +christ11 +kingdomhearts2 +maryjan3 +198008 +020477 +sugarfoot +heaven13 +nbibyf +87chevy +travis15 +anatomy1 +05051997 +george77 +peaches6 +julio10 +h0ller +lashae +trusting +vitinho +080593 +boondock +football101 +single16 +motoko +edmonton1 +sexybitch4 +reaper123 +wanderers +taruna +bmwe36 +951753852456 +curry +ryanjames +20051976 +24041996 +skeletor +anna2005 +131400 +alaska11 +maximus1 +legend2 +loco1234 +29051994 +chucky12 +saracen +blond1 +vball7 +081277 +shanda1 +imsohot1 +link123456 +yousuck3 +000000k +lala101 +198104 +291991 +richie123 +aotearoa +ianuarie +cleopatra +vagina12 +bonita13 +mish777 +asd654 +gemini88 +mycats +30031977 +incorrect1 +rustik +flower17 +250776 +travis09 +stroker1 +smudge123 +clock123 +oddworld +oxygen1 +010506 +brian4 +04031981 +2bitch +k55555 +ms +100299 +rosendo +240896 +r00tb33r +26101996 +july1995 +badcompany +cbhtym +teach +123asdzxc +271095 +brandy23 +mypassphrase +26041995 +szymon1 +1q1a1z +shetland +renren15 +713houston +reload1 +eatmyshorts +boragud02 +nanay +lynn16 +ste123 +zwinky1 +14061996 +13511351 +allen11 +imcute1 +abcd2244 +tassie +0124 +chulita +muff1n +160000 +dynomite +07041993 +rabbit3 +mex123 +ccc111 +monkey79 +gearhead +texas06 +inferno666 +forzalecce +potter ++ +nikki06 +2gether4ever +zaqwert +nascar38 +arista +040694 +livelove1 +alyssa9 +no1234 +010909 +woody12 +waverly +lover56 +aaron8 +13795 +iluv +raducu +291988 +01041996 +jasper23 +junker +fdsfds +181993 +305001 +valeria12 +jaredleto1 +15011995 +sexygirl09 +jimmy14 +0702 +04051979 +guilty1 +21011997 +freedom2010 +qwertasdf +jessica28 +aranha +261983 +030878 +nastya1995 +mamula +janita +ryder +sandberg +hotdog01 +maguire +bobmarley2 +andrew01 +michael32 +pelon123 +iamlegend1 +mee123 +123kat +dvddvd +fender3 +co2010 +smashing1 +azizbek +theone123 +280778 +shadmoss +concept1 +200194 +general +bahalana +tyutyu +parsons1 +lolliepop1 +02011977 +shorty#1 +241076 +slimthug1 +199223 +guitar14 +money05 +embassy1 +tal +sniper11 +lcv7bry1cf +starwars9 +laura18 +fernand0 +fallout3 +hottie99 +giovanni +panther21 +17031978 +carolina22 +jaguar12 +159159a +stacey +ilovechad1 +маруся +gala +lucy07 +poopoo3 +151096 +radford +19851215 +071278 +z1z2z3z4z5 +maddie7 +201984 +lilmama07 +coronado1 +darlin1 +teamo23 +jazzy101 +mascota +ninja250 +motorola2 +simplegirl +kitty06 +elise123 +zakzak +julian7 +tazz123 +wilson10 +1793 +dino1234 +bogdanova +fluturas +mother03 +buttercup0 +piggie1 +0603 +billiards +ven +sadie5 +acdcrocks1 +bastion +valentinorossi +idriss +redskins1 +linda15 +nene16 +madison14 +zhangyan +compusa +soso123 +kotova +821212 +400701 +mavipies +180978 +skylark1 +moneyy1 +abigail4 +fybcbvjdf +jonny12 +paris2010 +bgt56yhn +400095 +010978 +westend1 +jordan0 +31121977 +mata +delta12 +monique23 +petula +mohit +006900 +fuck55 +brains1 +tomi +skipper123 +191979 +young5 +brianna23 +10401040 +zonnebloem +joey15 +godislove2 +ford2000 +anchorage +pussylips +girlss +23071995 +santo1 +jeremiah +antonio1 +sunshine29 +pimp2006 +slickrick1 +lucilla +star777 +izzit +nikki4 +dsa123 +audirs6 +righteous1 +limegreen2 +191078 +45678910 +avatar +sims123 +mimi16 +justine123 +paprika1 +05101994 +bebe21 +112003 +12011979 +gay101 +16071979 +eric16 +carlos05 +280877 +billy27 +casio123 +05081995 +logan09 +lihenan +jhgfdsa +nettie1 +deborah +roanne +september23 +gocards +pumapuma +mustang77 +22061978 +110374 +jamie! +mama1995 +oceans12 +tits123 +babby +summerland +heather09 +352352 +carlene +011235813 +040109 +february10 +fredperry +199106 +oreste +0330 +mimi07 +beto12 +hello2me +291279 +dollar123 +1ilove +290495 +bailey33 +elephant11 +dexter10 +horse4 +05071995 +gizmo22 +prenses +iceage2 +myloveone +1blessing +mybaby07 +recife +tarragon +1elijah +22091978 +amylou +180377 +bethel1 +ghost5 +poesje +mareike +02071976 +rover75 +logos +barbi +hotchicks +07051995 +01092009 +archie12 +ecaterina +inmortal +sexy007 +darrius1 +121263 +seb123 +forest12 +manuel18 +hotcakes +01092006 +yasmeen1 +voronin +eagles33 +desi123 +080977 +allblack +pumpkin4 +blue75 +cowboys14 +fresh08 +071988 +lokita13 +16081979 +balbina +thenewme +123ddd +201296 +junior28 +zoosk2010 +++ +20031996 +ghjcnjrdfif +180378 +121174 +troyboy1 +spacer +199713 +boone +monkey84 +mandy13 +1mountain +rachel8 +melissa08 +ethan5 +kalambur +patryk123 +paper12 +spruce +sandler +alan11 +sparten117 +flemming +kawasaki7 +4569 +230296 +290377 +197909 +120374 +shakeit1 +08121980 +jackson06 +kbkbxrf +020193 +rose09 +diabetes1 +formation +velazquez +280477 +merda1 +751001 +0401 +troll0 +mysp4ce +071294 +malenka +рјр°рєсѓрёрј +20081995 +120997 +04121980 +sassy08 +cole11 +nath +konvict +mama2011 +nia123 +diana1998 +23041997 +winston7 +sprite2 +sep +trinity08 +three33 +112233d +rabbit5 +55558888 +54565456 +dedede1 +antone +princess84 +haley01 +blackknight +christine9 +181294 +only +1620 +59blood +231123 +kamenrider +jeanna +ch3ls3a +charlie20 +123456mn +jonathan09 +197825 +270578 +wishing +13021979 +follar +abundance1 +24101977 +vikings12 +061177 +0522 +liferocks +220470 +199109 +090293 +sixty +05071977 +malaria +30071981 +iloveausti +080694 +060280 +08041994 +ad1das +yahoo21 +181276 +bigred123 +peace77 +16101978 +ellie12 +benton1 +newme09 +1430 +weed01 +oliver1 +purple03 +ternopil +shawn01 +19851022 +230676 +brutus01 +08121995 +foxyroxy1 +blonde123 +nicko +dragon82 +500005 +steamer +timmer +89631139 +radmir +chennai123 +131979 +anabelen +newguy +151214 +carlos06 +extrem +safety1st +thatguy1 +metatron +ironman3 +hitsugaya +03041976 +steven1234 +spirit2 +sergent +13801380 +jennifer88 +track123 +197011 +davila +suzuki123 +150778 +suhani +elgordo +smokeyjoe +27061995 +jack02 +baby31 +1215225 +gangrel +martin8 +dick01 +fedcba +animal6 +rojo123 +021278 +laredo1 +iluvu22 +playgames +dragon100 +patanahi +poke +lollipop69 +hellhell +angelica13 +coeur +10061976 +280896 +oliver06 +ghj123 +mommy#1 +sebastian. +sexymama! +1hotstuff +dead13 +austen1 +604604 +khalid123 +walgreens1 +160477 +sk8r4life +990990 +771122 +23101978 +jojo24 +lacrosse13 +220575 +lifeless +finster +dylan8 +batman55 +soda +damien2 +bmw750 +pepete +shitter1 +28091979 +redneck09 +loaded1 +junior27 +ikickass +cieloazul +12071976 +smooches1 +gateway5 +hayden05 +78910 +birba +rockstar24 +07061995 +whitman +jose07 +26071980 +091101 +jess15 +rahrah +hotstuff10 +crazy666 +mauro1 +soumia +cicciolina +mine4ever +natsume +12071978 +030407 +temppass1 +forlove +love2013 +spuddy +ihateboys1 +mo123456 +joshua01 +puffpuff +parvathy +bernard2 +natasha11 +jannis +rachell +mchammer +thesame +kiki88 +hockey. +blacktiger +charles10 +104 +monkey80 +honey1234 +conner2 +lamina +181096 +121267 +qazpl +martello +16051979 +280178 +knulla +weed666 +hiromi +858877108aop +asadasad +pooooo +headphones +102300 +kottayam +bebe16 +fishing69 +mydad1 +alexa2 +matt1 +29101979 +retina +stella22 +sydney07 +160696 +hershey3 +jayden13 +iron666 +yjwfn73j +corporal +estrela1 +shadow90 +ekbnrf +191093 +300377 +gbemisola +231297 +vball13 +wakaflocka +250995 +sangohan +31011996 +mikie1 +nikki17 +133333 +cisneros +saregama +august89 +tackle +260395 +bestfriend +freinds +lover77 +gophers +13041979 +821012 +011181 +quan12 +travis07 +16041997 +albert13 +cbr929 +softball05 +301276 +221981 +101400 +kundera +lovin1 +hapkido +28091995 +doggie3 +roxy07 +dkflbckfdf +fuckyouass +legia1916 +neversaydie +saints10 +lovely77 +lucky05 +dolphins! +tiffany16 +gundamseed +bumblebee2 +432100 +membership +chevy89 +sunny6 +jinx +flower0 +010596 +123453 +piratas +surfergirl +pioneer +goody2shoe +gfghbrf +ronnie10 +starchild1 +199516 +maria27 +ultraviolet +1nikki +sesshoumaru +donotenter +loriann +25061977 +godjesus +orange07 +tramonto +abramova +skyler12 +conner123 +pika +rach123 +stephon +1norte4 +victim +sunnyboy1 +130378 +1vision +111008 +gizzie +anuska +escalante +antioch +lulubelle +ginger24 +tristan7 +1kittycat +steven88 +jaylynn1 +1472580369 +notrust1 +cinthia1 +mike2000 +crunk +09081994 +kelly4 +fucklove21 +palani +william19 +198005 +sandy +thewall1 +123456789789 +sentry +catgirl1 +raman +suckmyass69 +solito +foreman1 +b123098 +ifiksr +abab1122 +ace12345 +210975 +220376 +001964 +veronica3 +dig +seventeen17 +trans +teflon +aspen123 +tutu123 +fender. +cece +carlinhos +batman0 +nene10 +081096 +310596 +schweini +123aaa123 +tapioca +yamaha13 +1040 +dumpster +04051978 +19091978 +joey666 +july2004 +angelina3 +cinta +rooney08 +12031978 +natalie08 +sheila123 +blackie123 +1hotmom +backyard1 +crosby1 +madman123 +horizons +mamasgirl1 +damian666 +160194 +greenfrog1 +mommy77 +george1234 +171981 +000010 +crhbgrf +bartbart +denis1995 +02101994 +stacks1 +anniedog +159000 +cricketer +teamomuxo +hope4me +sk123456 +mb123456 +poli +ricola +february11 +nena14 +0315 +skizzo +300779 +bullet13 +fiction1 +masquerade +nene11 +yoselin +leticia123 +1324354657687980 +20032006 +marissa7 +jeanie1 +z00sk +stang1 +020178 +david89 +230776 +31101977 +look12 +smokey77 +initiald09 +lkjhg1 +iwashere +20042007 +serg123 +311200 +asbestos +climber1 +danyel +080502 +smokey07 +q55555 +lethal1 +mike04 +playstation3 +sabrina5 +tpxerxjmp +110206 +11234 +paleta +sing123 +31101979 +741023 +requiem1 +john101 +miranda9 +1brooke +180879 +dg123456 +moh +edward1234 +alive1 +taylor77 +lala24 +19831212 +moron1 +26102610 +flappy +king32 +section +jennifer25 +born2die +bycnbnen +vbif +yegbpltw2012lol +louise14 +marijuana420 +danielle123 +moeder +cheyenne11 +marine13 +06051995 +vikusya +19861018 +ghj100 +suckit. +16071980 +oliver88 +thanksgod +fen +evolution7 +nothing3 +main +310577 +sascha +jaqueline1 +edward9 +marcus4 +makati +predator +20032005 +asshol3 +shrink +78951230 +11051977 +amo-te +rclens +giratina +14061406 +gavin2 +210279 +987654321c +300395 +wanksta +0415 +ninja666 +cabowabo +tanjiang999 +blue97 +63256632 +geogeo +3223 +mam123 +27011980 +foresight +benson12 +rayallen +1starwars +kenzie12 +emmarose1 +140404 +shoebox +justice +tigers +xlf65b6666 +010378 +polgara +myplace +mw0720 +starwars22 +blitzen +elpaso1 +aaron1234 +rancho1 +makeit +clocks1 +barbie17 +high123 +1234567890qwert +boloto +chicago9 +rrrrr1 +melissa17 +trecool1 +05071996 +bigpenis +prettyinpink +821125 +tigger26 +pappa123 +chevy05 +maxwell01 +260177 +030778 +13061979 +ranger3 +19861220 +199221 +mah +golden01 +eric +040980 +rooney9 +actarus +120698 +jemma1 +angel1985 +leslie11 +08071981 +prima +lthmvj +crosscountry +071279 +azteca13 +07111980 +santosh123 +justicia +freund +28121979 +199108 +perfect12 +passover +andrea9 +tiger74 +br5490 +fbi11213 +bassin +gopal +goofy12 +keke14 +kendra2 +converse12 +usa777 +mandarino +ykdpj67mgd +muffin21 +112233m +fulham1 +olateju +nina22 +090381 +squish +yildiz +09121980 +qwertz1234 +ruthann +banjo123 +crapper1 +jade22 +aus +1364 +yamaha85 +aggarwal +114455 +uzbjnei451 +starlight2 +plumbing1 +21041978 +pinky! +flamme +09101982 +17081977 +brooke15 +feelmylove +boobooboo +willows +nikita10 +page +130896 +070380 +sadman +5blood +1artist +staff +luckylucky +marcos10 +julie01 +austin. +mama17 +081988 +samuel14 +22071995 +phialpha +maddie07 +suhail +09011982 +disorder +161194 +190909 +marijke +bib +dana1234 +290995 +traxxas1 +lena11 +sargodha +andris +assfucker +55555k +kevin05 +010507 +!@#$%^&*( +dennis22 +19121977 +10021976 +everclear1 +221173 +kswiss1 +just12 +fk +hotmom +400019 +amanda1 +mumu +justynka +a33333 +090579 +teamo17 +cityhunter +22011979 +20121996 +11101976 +leon11 +mm123123 +green100 +star95 +docdoc +bay +evasion +14001400 +camaro95 +290777 +sweety23 +estonia +06051981 +19841124 +19061996 +fkmabz +alpaca +nicholas16 +elyssa +the1ilove +270979 +powerball +heynow1 +ohiostate2 +beautifulg +vfyxtcnth +alpha5 +sublime69 +kacper123 +mangesh +jeric +aaasss1 +blondie69 +monique21 +13061996 +hello999 +dingus +herbal +matthardy +marisela1 +blazer12 +181275 +simon3 +icp420 +10071979 +ryan88 +030995 +05101980 +maneater1 +kulet +the2ofus +option1 +141888 +alexandrea +0801 +010878 +likeme1 +bambam7 +201204 +princess66 +wolfdog +darkness5 +shithead3 +domino2 +kenyan +denis12 +15love +yourmom8 +fishing5 +hunter66 +hummingbir +jorgito1 +caddy +k. +dance21 +170794 +vitamine +`12345 +nicodemus +daxter1 +monday +hotmail7 +candy77 +reb +melodi +lovesit1 +haley11 +36903690 +monaghan +111111v +280595 +dickey +nikky1 +brownie3 +johnny18 +hesoyam +kerstin +hpg2n89qif +herve +19861022 +aaaa123 +huguito +steve7 +anjelik +081208 +april69 +150795 +jehovah7 +16041995 +jenny09 +cookie0 +kaydenlee +2232 +billyb +102589 +179324865 +mrkitty1 +amazing2 +bluesky2 +abhimanyu +2124 +randomness +kos +sebastiao +21051995 +eagle11 +andrew91 +matt99 +baker4 +sexy2006 +bradly1 +z123321 +inteligente +tocool +12345az +missingu +230000 +peace8 +stasstas +newlife1 +kakashi12 +montre +harbour +whitney12 +xanadu1 +terrific +ehlbctw +070709 +02021970 +69lover +pbyfblf +06061976 +brenner +0701 +lovely88 +shadow01 +rajneesh +misio +qwezxcasd +rose88 +planete +10111975 +italia10 +edgardo1 +dak0ta +tranny1 +dressup +milanello +helpme11 +znt: +190378 +rubydog +adnan123 +frontech +havoc1 +.adgjmpt +funnygirl1 +tobias12 +13751375 +godfrey1 +destiny15 +lastchaos +lovestruck +020478 +tiffany09 +arjona +tambov +dewitt +hornet01 +sierra5 +worm +wilson22 +youkofa569 +090882 +guerra1 +1122330 +197901 +max1997 +rukhsana +estrella5 +poop44 +grace +cirilo +197803 +horst +saturn01 +regiment +sexesexe +03121979 +clark123 +811028 +darion +110046 +woodside1 +p2wcffjcvr +2muchlove +project123 +kris1234 +mike2010 +contrasea +kelsey14 +14211421 +02031996 +abcde3 +green26 +12061977 +21092109 +martas +carlson1 +jeremiah7 +hase +sixpack1 +miller13 +jasmin11 +30051979 +mike2007 +angcuteko +billkaulit +199126 +123qwe456asd +021979 +pitchou +xt97794xt +saints01 +55555l +ayamgoreng +07031981 +grace07 +voltron1 +warlords +buick +silver00 +eclipse7 +jason26 +office123 +sassy21 +la123456 +nena11 +ashwani +buterfly1 +marcie1 +bedtime +harry22 +otilia +125478963 +joanne123 +travis4 +02121978 +santillan +mama45 +30101994 +fordf100 +qayxsw +010709 +adegoke +santi123 +pintail +maggie18 +iloveyou30 +dripik +affection +nate13 +cj12345 +987654321n +1alicia +31051981 +anything12 +sarah101 +faggot6 +xterra +24011995 +jamaica7 +123321b +212325 +osipov +220874 +skater24 +jaquan +vampiro1 +firstlove1 +sycamore1 +rjhjyf +090900 +yagjecc816 +300477 +texas254 +phantoms +akademia +djkxbwf +h4hgaipgzu +reanimator +angelica +shrikrishna +mifamilia1 +lobo123 +joiner +spaces1 +overit1 +holyshit! +170377 +134625 +reyes7 +19801981 +jason27 +lilli1 +041294 +exotic1 +24011996 +16101979 +hardhead1 +darkness1 +danny +baruch +170797 +30101978 +pup +bilabong +witchy1 +june2004 +020978 +lilbear1 +041095 +whysoserious +loveisreal +qwerty777888 +talula +sexyman123 +firstlady +amber9 +09101993 +mskitty +petra123 +enjoy1 +23091978 +far123 +001200 +021978 +brenda3 +schatz123 +dogeatdog +vjhjpjd +oneblood1 +jew123 +241294 +123as123 +191993 +iluvu3 +512 +050978 +truelove3 +qwerty123456 +jurassic5 +102800 +mother69 +bullhead +davidp +band101 +159753s +ika123 +tinker21 +february24 +vegeta11 +abcde6 +korn1234 +070293 +12345qwertasdfg +getjob +jg1234 +111964 +30061978 +1478963a +internet7 +mybaby13 +winner +linkedin69 +alexis25 +kimikimi +popstar123 +zhangqiang +pinky8 +030180 +tyskie +jjjjj5 +penny11 +billyray +laurens +jordan91 +shana123 +fatpussy +bigdog10 +anna1 +19861223 +bluenose1 +wsky0o0o0o +man2man +20102007 +assassinscreed +mhaldita +11113333 +20121976 +selma1 +nick25 +cowboy! +chris1990 +654321123456 +gondon +hanicka +folashade +xtkjdtrgfer +bradley01 +rollsroyce +manchester1 +pipers +romawka +bumfluff +qwerty333 +steph14 +everytime +poodie +saw7139 +1317 +pedrito1 +rana123 +costa1 +7inches +anna2006 +311296 +monique +mustang14 +rj1234 +anywhere +280393 +ilovesocce +warrock +789456qwe +0316 +123god +01081996 +travis14 +karla13 +reymysteri +firestar1 +ingenieur +christina5 +stepashka +120275 +lukinhas +hellion +bulldozer1 +080910 +blacklab1 +chickie1 +240196 +j123098 +abc123@ +110077 +daisygirl +canton1 +petronas +satchmo1 +sexyboi1 +radius +yahoo01 +199227 +19841014 +220796 +lilwayne09 +302019 +namnam +huyhuy +flamenco1 +19821212 +jimi +lime +147258963 +golftdi +andrea05 +120899 +susannah +wolf1 +varitek33 +ticket1 +sexytime69 +power01 +angusyoung +psycho69 +110575 +angela14 +hilary +cjxb2014 +golfer +22061979 +qwerty12345678 +future12 +22021977 +19871212 +james2007 +saucisse +amina123 +chevy24 +notagain1 +stupidass +charlie02 +hepburn +07041995 +sexymama69 +010877 +barb +cheater123 +torres12 +myking +hanshans +jessica04 +mahalko +alex1974 +bloodred +jenalyn +ducados +310575 +gaia +lol +ou171423 +verite +3puppies +daisy9 +lenicka +chandler2 +250996 +barbie08 +24051978 +adriana +33663366 +emilly +newyork14 +21081994 +spencer4 +marley10 +casper99 +zzzzxxxx +aretha +havingfun +crystal18 +thekiller1 +rjdfkmxer +realtime +500045 +mono +adeshina +knicks33 +camelo +190477 +nimbus2000 +germany123 +pleaseme +19381938 +pissant +timo +slippy +maksim123 +drummers +091981 +12021976 +power22 +andrew93 +goodtime1 +300676 +xxxxx6 +240576 +021177 +goahead +mushka +19871012 +191293 +cocktail1 +caserta +рјр°сђрёрѕр° +diva1234 +kiss23 +20071977 +030795 +mainstreet +sasha99 +20021976 +leigha +665665 +stooge +cb +ambition1 +blueprint1 +dennis23 +swimmer2 +erick12 +july1996 +280576 +february27 +09101980 +podarok +order +17021978 +140194 +lynn1234 +arbonne +asshole24 +24111995 +puck +falcons12 +venganza +jordan89 +02091974 +walker +devina +chickenbutt +199009 +cable +riverrat1 +lopez2 +benjamin13 +babyboo3 +131075 +loveisblin +qw123456 +neophyte +romina1 +mommy25 +tommy9 +marilin +gloucester +destiny. +101272 +jetlee +h3llokitty +198924 +kyle18 +bloger01 +0564335 +buttsex69 +elpapi1 +rugged +sunfish +ondine +teddy23 +cabbages +127 +060393 +17711771 +171993 +locker1 +pseudo +feliz +dog100 +calendar1 +251978 +1bambam +22012201 +10061979 +babygurl24 +pinina +d7777777 +winnipeg2612 +05041977 +700075 +cableguy +030294 +tribute +simon +dayanara +waheguruji +secretaria +schwimmen +marlies +jerry01 +24101979 +010203q +lapierre +boricua7 +nan123 +steak1 +natalie9 +23111995 +yahoo8 +millencolin +moorea +anaheim714 +1love4life +pompino +brindisi +adrianita +locutus +sommer07 +bitch87 +261096 +zxcvbnm5 +miguel. +100599 +070181 +paris07 +bestmom1 +22032203 +calibra1 +london05 +tiffany08 +knight01 +03061996 +maryjean +owned +nirvana9 +yojimbo +.kbz123 +february28 +njhnbr +common123 +23061978 +010778 +carebears2 +lilith1 +supremo +hiphop4 +takeme +always12 +balboa1 +runescape! +18101977 +20052009 +linda7 +240474 +002233 +apples6 +dustin69 +290179 +stjoseph +dima007 +160495 +sweety01 +101002 +jason143 +pinky21 +theanswer3 +ffffffffffff +kaycie1 +lolli +winters1 +2022 + +27021994 +29011981 +surf12 +grazie +180395 +cornelio +19101977 +13101977 +cthuttd +ftw666 +lhbjkjubz2957704 +usmarines +290676 +fatass13 +synyster1 +200795 +192 +july2009 +tape +friends16 +daddygirl2 +class04 +005005 +catcat123 +u2u2u2 +yoyo22 +malice1 +muchacha +06021996 +gee123 +raqdc4ml +tigger1 +babu123 +rats12 +3388 +scorpion2 +davidk +19870111 +iamgood +415 +buster02 +831004 +19881989 +piscine +raiders34 +cowbell +14071979 +gregory7 +sammy77 +shannon9 +pimpollo +eiknon11 +7777777j +bigdogg +passenger +boy12345 +augustine1 +bread123 +qaz789 +freeport1 +manoka +overlook +blaze13 +polina1 +walters1 +srinivasa +rocket3 +010994 +aderonke +synapse +yv3bcdaq +giveit2me +tyrone12 +theresa2 +270377 +mybaby7 +01011998 +081982 +1rosebud +laracroft1 +stephen +21031977 +friends4me +asdfghjkl456 +mayhem666 +connor +jerry3 +shianne +ray-ray +harmony7 +mythreesons +bayarea510 +1williams +02101996 +hidalgo1 +chibuzor +april92 +10071977 +screwed1 +bienvenu +lorenzo123 +24081979 +jasmyn +111998 +19871029 +luv4me +everton11 +produce +6453 +patches7 +riley13 +iamme1 +pinkpig +horse13 +335335 +cowpie +freebee +895 +bunga +27061993 +neumann +l00ser +monsta +tigger66 +011989 +020896 +godswill1 +residentevil4 +riyadh +happiness! +thisis +vjcrdbx +speedy7 +7414 +thereds +liljoe +ilovemyspa +666666z +playa5 +180994 +031982 +811118 +cammie1 +061178 +pokemon09 +michael44 +ededed +oleg1992 +frdfvfhby +mavrick1 +manuel5 +1001wdst +05081980 +200179 +fresh21 +wilmar +wrinkle1 +lovemy +140696 +03041975 +indianajones +decent +cocopuffs +230975 +fidel1 +23022302 +svetasveta +bibou +still +11021979 +goodwood +tucker7 +nutsack +isabel13 +belmar +sportsmen +nastya12 +10031977 +rascal13 +250278 +bandung1 +281196 +31081995 +tamia1 +labebe +w123456789w +32113211 +drunken +larson1 +valeria +21031979 +redbirds +faith6 +011982 +zumzum +dum +kerwin +841226 +varghese +141618 +shalom7 +palencia +stephanie1 + +anna24 +brian6 +02021972 +rs2000 +phoenix! +animals3 +newport7 +moviestar +leverkusen +florida9 +mistic +twojastara +summoner +wisdom12 +29071995 +4sunshine +060380 +dantist +zaqxswcdevfr +olvido +azerbaijan +blowme123 +squeek +elena2010 +mille +cokecoke +ghjuhfvvbcn +230897 +fireball12 +11111c +lisbon67 +akash123 +123123zz +m123456m +d41d8cd98f00b204e980 +blackbear1 +cartoon123 +samsung! +lwxlwx +811811 +97979797 +lala18 +poolshark +chumchum +rouges +198003 +beatiful +bitch2009 +vondutch +coldwater +bouddha +090382 +paulina123 +theiige4x2 +preston3 +luckyone1 +baptist1 +barunka +frytol +atleti +1jehovah +555550 +051077 +bruins77 +grasshoppe +170193 +08011994 +ruffryders +holly3 +shaker1 +05021995 +160296 +april1991 +english3 +20051978 +leafar +jeffrey1 +brandy5 +250696 +090182 +minidisc +gloria +011984 +fluffy69 +gotribe +0.0.0. +black00 +pinkflower +tromba +mariann +withyou +ciao1234 +starwars01 +raptor350 +adaeze +041079 +nul +imsosexy +scorpio9 +giadina +assass123 +shadow32 +blue4u +19861224 +000789 +19861017 +bigfoot2 +oigres +letmein22 +getmoney21 +shanta1 +imalone +ilovebobby +anna1982 +beijing2008 +ewankosayo +swetik +bqktrqn844 +carl12 +mistie +magic9 +bacchus1 +270177 +091982 +cupcake6 +nylons +#1stunner +love1004 +love112 +bear99 +renee7 +131196 +boobies12 +bull123 +carmen23 +may1984 +200896 +williams11 +lover20 +santiago123 +2fuckyou +bedrock1 +2qwerty +snoopy99 +mimamima +240695 +catcat12 +babies123 +spokane +juice2 +greeneggs +yz450f +superman34 +142356 +golden +timmy3 +summerfun +popokatepetl +10121976 +anastacia1 +what2do +fener1 +dylan99 +junkyard1 +tony77 +chadreed22 +emmanuella +17091979 +jodeci +plummer +vasco1 +majeczka +071295 +li +speedy3 +23051997 +andreea1 +angela18 +buheirf +ninja! +dudule +1manuel +death3 +30011981 +19861013 +060381 +horosho +251208 +davidl +08031978 +sinful +samsung0 +ashley85 +corona123 +52013140 +alejandro123 +mahina +jessie69 +enterme +bonner1 +unique123 +090693 +minniemous +boomer5 +possible1 +moonman1 +bentley1 +462016 +120472 +bhagya +artemida +diana01 +20051996 +maraton +caregiver +kristina2 +560072 +heaven5 +12345zz +charcoal1 +rambutan +vandread +superman28 +020677 +nikola +24041978 +03101979 +lynnlynn +lamar2 +army11 +taipei +150496 +fake13 +a123123a +arsenal5 +notnot +samsung09 +14051977 +elijah13 +samogon +mango5 +210874 +bornfree +twostep +210876 +bookitty +getrdone +091294 +270678 +april2010 +sammy111 +12051977 +cookie44 +09111993 +super21 +nicole82 +101299 +vasilenko +miraflores +34563456 +nagano +rjgtqrf +zachary9 +ankit123 +krish123 +lovemebaby +kasabian +freedom0 +doris123 +nike01 +177777 +rachel08 +underscore +revenge! +19861126 +040795 +amooti +iamthebest1 +classof2012 +mizuki +270396 +111963 +courtney9 +19851220 +travis08 +enrique123 +65stang +waltdisney +denise69 +fktyf +timon1 +03061978 +251196 +hank123 +reference +manolete +rere12 +pokers +holsten +schmidt1 +1356 +post +london00 +fqi3p8arjg +vonvon +841020 +17051979 +21ainiyan +courtney +super007 +philippe1 +tbird +a9999999 +nasdaq +pinuccio +gangster14 +jackass01 +babygril +ladykiller +brooklyn01 +liverp00l +gangsta8 +lori123 +myman1 +cubs12 +moriarty +fattie +nicolas10 +280795 +pikachu25 +faraday +841012 +myspace83 +katie18 +qwaszx1234 +jayjay5 +bubble7 +anna2004 +love2me +roses12 +pfqxtyjr +bloodgang5 +guo150 +260677 +basspro +19861124 +110375 +austin25 +zenit +jamil +pumas12 +davina1 +pumpk1n +mimita +gigant +niceboy +28031996 +400003 +25091994 +marriott1 +poohbear20 +leothelion +lollypop! +120398 +140275 +toriamos1 +45874587 +luisa123 +sherlyn +ghjcgtrn +passw0rd! +gogetit +march01 +350chevy +ina123 +11021977 +smiles4u +04121981 +summer19 +fuckoff +birthvillage +240477 +1azerty +suleman +uekmyfp +olympic1 +fff123 +cancerian +redblack +missy1234 +151981 +190994 +som +1cheer +jakester1 +extremo +mypassw0rd +sofia12 +razvod +morientes +jordan34 +diana7 +music2008 +uyjvbr +sexlover +rock77 +26101978 +krishana +realman +baller45 +aggro1 +13701370 +getlow +170477 +29111994 +654321p +100996 +quicksilve +paolo123 +153486 +lolo22 +kopytko +198531 +david2006 +ricky01 +cooper14 +checho +140505 +24121978 +june1997 +diebitch1 +practice1 +passion4 +royston +pierina +bowwow11 +aud +30003000 +eurogunz +utvols +andres +activa +15051505 +rangers7 +my_komp_777 +j00000 +breebree1 +elvis11 +faktor +seductive +chiquitin +09071980 +ag1234 +basket10 +houghton +hottie44 +cheese15 +daddy'sgir +bibibibi +211096 +akinsanmi +gorman +my3dogs +creator1 +deadman8 +bmw325is +23031977 +saulute +jessica00 +55554444 +vball3 +ghostdog +zbyszek +230276 +concorde1 +2113 +bookbook +evybwf +198904 +getmoney22 +551976ms +tony06 +050794 +carlos28 +841024 +diedie1 +bowers +polo90 +02081975 +vincent13 +olivier +199302 +christiaan +t11111 +mg1234 +jambon +150296 +raul12 +mylove18 +anhmaiyeuem +1september +nou +theduke1 +please11 +stefy +shippuden1 +240575 +197928 +462001 +sasha17 +money2007 +cosmos0901 +kolejorz +dearmama +valerian +020796 +chameau +dashing +01121979 +20081975 +moejoe +maddie09 +reyes123 +2530 +dylan09 +oneway1 +bonghits +lilies +01051977 +laspalmas +khongnho +mendel +enrico1 +cameron02 +19733791 +james666 +xuliang +philly123 +leyla +breanna123 +123dima +bomba1 +10081976 +camera123 +02091994 +kleiner +cutie95 +jeff21 +nyuszi +nick19 +rhodes1 +scott +excaliber +minimum1 +destiny99 +fang2008 +lewis2 +19734682 +bignasty +lovekills1 +downhill1 +030994 +shannon6 +821020 +110707 +hottie93 +26121979 +lakers15 +00000q +tiff12 +qazqaz11 +251995 +anna25 +06081994 +thatbitch1 +zxasqw123 +allsaints +chuleta +angelo2 +22101997 +fish10 +1buttercup +101201 +punkie1 +truckin +battlefield2 +qqq333 +reddog123 +tinkabell1 +anarkia +rafter +181982 +hiphop10 +pillow123 +7891235 +hotmama123 +110775 +fartman1 +080695 +samuel12345 +23121997 +791111 +tiktok +zara123 +28021996 +bengal1 +emreemre +gerbil1 +melchior +011111 +bolleke +050795 +180779 +gabriel17 +26041981 +moomoo! +attorney1 +markjoseph +lollipop. +25292529 +blake11 +198229 +mallari +19791980 +donavan +28071976 +anagha +logitech1 +blizzard +winter98 +water21 +kyle07 +smiley69 +linkedin8 +sarahjane1 +amberlynn +fatkid +shabby +200296 +628628 +jean1234 +guitar77 +onelove4 +171977 +24081996 +eyeshield +aguacate +12345610 +math12 +14041979 +willy12 +wolfy +1tennis +310777 +driftking1 +babygirl1 +victor69 +findme1 +norcal1 +darkness66 +199421 +ramrod1 +nicolle1 +egshm1 +barcelona8 +duckhunter +groupd1 +megadeath +steelman +test99 +567567567 +flyer1 +gabrielle +v3uriah1 +dreams +twat +karan123 +wildcats10 +love209 +198109 +ledzeppeli +panda14 +krizia +lalala4 +22081979 +realsim07 +killer96 +flower45 +020578 +darkorbit +vanessa17 +torana +autumn +lefthand +oliver8 +america16 +sarmat +joejoe12 +130875 +suckit3 +adc123 +ahovbipw +95civic +matthew77 +1436 +1052 +cobra12 +qwerty911 +102500 +the1andonly +mewtwo1 +warcraft4 +060878 +femi +30011979 +2321 +mainman +198129 +united2 +rahima +halo3rules +26081995 +color123 +shifty1 +888888881 +daddad1 +pelle +boulou +123123123z +homey1 +05051976 +sasha2011 +manika +charl0tte +vlad12345 +yahoos1 +bubba99 +7nc4lqw7to +03031998 +80959002443 +asdfqwer123 +aqualung +asd098 +dirty12 +myfamily5 +mikey10 +s696969 +shelly2 +duran2 +jamboree +tony101 +anillo +041179 +julien +13111979 +contra1 +vaseline1 +123456ru +06011981 +wi11iam +chantilly +assmunch1 +130676 +52255225 +skater88 +tuan123 +140576 +scorpion7 +210496 +chloe6 +197210 +linton +dell10 +fktrcfylhf +240596 +duke33 +iiiiiii +21love +06071980 +041078 +copain +kailee1 +alabaster +charlotte0 +kornelia +270976 +agapito +savannah4 +czz224466 +po +heyhey11 +fidelio1 +phoenix8 +alyssa15 +1adgjmptw +21061979 +andrik +granny5 +forsale +tippie +landon05 +16051978 +borland +dorota1 +1minnie +addison2 +nuages +jaymie +13081979 +peanut101 +111156 +qwerty0987 +fuckyou321 +040779 +1jamaica +rand +heaven4 +020696 +boobie2 +fuckyou187 +chickboy +blue54 +vt +rammstein6 +jekjek +090679 +shane69 +surfer69 +02041973 +beaner2 +sorpresa +lions123 +nji90okm +klingon1 +emotion1 +borderline +121070 +060479 +mexican4li +annarose +sarah24 +mommy34 +040777 +23121978 +111111n +strawb3rry +dfy.if +wsxcde +kitty. +limestone +kuuipo +fefefe +victoria20 +ninjaman +23042304 +1google +rol +280578 +earth123 +red911 +7jokx7b9du +oliver77 +jersey2 +jhjhjh +hailey03 +gokil +butter13 +marina23 +matveev +righton1 +shade45 +slobodan +fatal1 +niewiem1 +bigjake +199519 +ipod11 +199224 +asking +251296 +coolcat2 +abby08 +chimie +12111978 +jessica90 +rajababu +2426 +onelove69 +katrina12 +shambala +482001 +fgh123 +mobius1 +jodie123 +++ +single2010 +igetmoney2 +disney13 +kennedy +buster44 +jjjjjj6 +jellytots +20091977 +s1mple +cheezy +120304 +nissan +05061995 +26121977 +979899 +azerty10 +486255 +weezy12 +09081981 +ilove9 +050576 +alessandro +199555 +45544554 +14061977 +d55555 +08101980 +fuckyou100 +110597 +banda1 +811225 +lauren02 +tristian +zero01 +frenchkiss +nownow +filemon +sierra117 +gilbert2 +debbie +bansal +01101994 +rayman1 +831024 +paresh +abhi1234 +24121996 +chris97 +eduardito +180396 +198317 +123321qaz +06021979 +08061980 +peanut00 +pinky4 +24081977 +eagles8 +asdfg +ybrjkm +florida06 +bayview +sexylexy +23121979 +spotlight1 +lagnaf +winston +yfl.if +madhumita +orange27 +dancing123 +pudge +jaelyn +naruto91 +101968 +lindsay123 +160195 +mine69 +delbert1 +230376 +baller16 +x870624x +170596 +05061996 +xxxxxxxxxxxx +inglewood +123568 +paperboy1 +rebelde3 +monster08 +19861030 +shelbie +rikardo +lordvader +amor25 +tatiana +2money +bhopal +mafille +jesusito +hope01 +iubireamea +beast3 +13071307 +smokey15 +frends +nokia3200 +woodman1 +amanda05 +weezyfbaby +random13 +xthysq +55555j +musa +060697 +spongecola +nasaud +alliyah +dru +thomas55 +060181 +122221 +10011975 +snowball7 +chloes +gateway200 +112800 +mko0nji9 +leandro123 +peace4all +ufptkm +finale +9191 +eagles69 +bowwow5 +140877 +drugsty +time12 +780405 +teddy101 +mckayla +wildcats7 +65432 +pimpin15 +model123 +fuckme420 +ihatemyself +lorella +familia10 +sharkbait +jacinta1 +star34 +freedom88 +010200 +bypass +callie11 +music2009 +meeeee +bobo22 +gators123 +lalala6 +jackblack1 +barney13 +basketball10 +realbetis +house3 +airline +0069 +yomom1 +starwars +malathi +191094 +asshat1 +21101978 +781025 +cheezit1 +anton1996 +allmeu112 +pas100 +angel2004 +pink100 +a951753 +penguin4 +jenn12 +1poopoo +132639 +zxcvb6 +mommie2 +copper22 +cool17 +melodie1 +elbert +dingle1 +02041975 +19871225 +angelina +danielito1 +webmaster123 +southside8 +44gatti +cristin +snails +amenamen +hjcnjd +deathcore +ghost7 +290178 +sophia08 +tygferrfddss +lakers33 +success4me +socialwork +10011997 +244 +chances +palesa +111166 +simply1 +megamega +capella +17091980 +internet! +mike66 +iloveemma +apple55 +131977 +valentinka +happiness7 +290878 +booty5 +114 +1477 +rockstar18 +chaplain +nirvana11 +rekha +ana12345 +poop15 +richy1 +harsh123 +puss +blackhole1 +ddzj49nb3 +pur +katie09 +01011962 +avengedsevenfold +trouble69 +12081976 +drinking1 +whiskas +jaimie1 +password37 +rjycnbnewbz +creat1ve +soundwave +junior26 +daftpunk1 +roxas13 +02111980 +bella99 +brainiac +evermore +aline123 +stormy123 +javier3 +time2die +wiener +0905 +nayarit1 +sanandres +bruder +chase13 +broke1 +yasin +199303 +geppetto +midas1 +nicole44 +reymisteri +130496 +0904 +catherin +kaitlyn123 +nikolay +crystalsaga +291078 +081178 +freccia +muggsy +bryan01 +jackson14 +honda85 +snoopy25 +costantino +kimura +rockstar17 +balazs +theghost +fatboy21 +icewater +theway +jade07 +artem1997 +freunde1 +0425 +sakura7 +11031977 +justincase +30041996 +preston12 +dragon83 +lokillo +freak! +bloomfield +hhhhhh7 +diddy +westside! +bunty +1truck +judgement +aleksandra1 +rushhour +tomino +patrizio +elvis69 +watchout +yxcvbnm123 +kritika +billings +shorty +shea +akuganteng +gerald123 +260795 +raymart +2p76xh2xhv +p1p2p3 +123a +lollipop10 +1350 +mixmaster +puffin1 +mcnabb +nad123 +yeuemnhieu +intan +beata1 +fatboy10 +tara1234 +hubertus +contractor +moliere +gordon24 +18031979 +sammyd +marino4ka +cheese88 +sodium +lindsay7 +lib +porfavor +nichol +gigglez1 +lunette +1593572486 +210476 +mainz05 +greenlantern +ilove17 +vbnvbn +jamielynn +15081996 +redsox4 +kitty +9797183185 +giggsy +purelove +junior420 +hazeleyes +manman11 +ragdoll1 +19216801 +flowers22 +irish12 +ponorogo +dalia +newport01 +denis1991 +charles! +bella25 +barby +9788960 +gfyt63gd +tigereye +021195 +sunset7 +190300 +30103010 +bekasi +harleydog +chico11 +nick +zxcvbasdfg +love1981 +anorexia +dima1988 +ryan20 +tink3rb3ll +amor17 +westfield1 +0525 +zuzia +celeste2 +uglybitch1 +oscardog1 +james87 +sasuke01 +liuyang +jenny07 +account2 +dragon79 +007911 +ponce +d1bd6bc58c1d74df41a957489c9942f5 +memphis2 +030373 +dmx123 +yousuck. +22081978 +1360 +plenty +cachorro1 +joker88 +123haha +emporio +fucker21 +kocicka +11111974 +thu +chinois +01101978 +cfvfzkexifz +bitchplz1 +phillip123 +lilla +iloveyouf +bitch111 +james2009 +rocky24 +sweetpea7 +farmhouse +edmund1 +290677 +261993 +sanluis1 +gingerale +roma1927 +199005 +2120 +010199 +1281 +151095 +password99 +sparkplug +772324 +grace23 +schoko +rosie11 +themis +afghan1 +140474 +hockey +easier +55555555555 +montesa +7546 +4545454545 +yellow27 +boogie01 +15051977 +davidt +alison +chyna +kayla1234 +chicago22 +dirty123 +21111995 +124365 +2357 +vance1 +armine +nastya2010 +giorgina +ilikepie123 +skater09 +massi +121214 +potapova +amanda92 +cassie69 +lesbians1 +kelly17 +ravenna +050494 +190993 +babyg123 +17111995 +19851023 +25081978 +chi-town +26061979 +dumbfuck1 +pooh24 +newport20 +thaddeus1 +2536 +hulk12 +paska123 +oluwadare +others +misty5 +beautifu +071177 +nallepuh +261276 +586586 +virendra +cellphone3 +dad101 +126 +intruder1 +dvorak +youbye1231 +donkey7 +samsam12 +19051996 +228228228 +colorado12 +thistle1 +murat123 +sketch1 +12101974 +showdown +19851217 +s0mething +090280 +ashton3 +197926 +199420 +86026403 +honda80 +calvert +ranger75 +060978 +220474 +17071996 +13041304 +tanning +polniypizdec0211 +123abc123abc +krystian1 +280677 +biker123 +cholito +volcom23 +beauty21 +bigdogg1 +gang123 +elmo15 +puspita +110674 +rock15 +7v8bv5teow +pebbles7 +kiki07 +1business +jamie08 +19971998 +adrian05 +nutcase +1344 +rfrfitxrf +imani +30121996 +w0rdpass +1237 +denis1996 +rfn +naiara +20021977 +jason28 +pandita +66chevelle +07061993 +molley +131072 +paris5 +andrea89 +sebastian12 +06041981 +040408 +12091996 +kaylee06 +14121996 +diva07 +050280 +chris1991 +15101975 +1teddy +lele12 +vlad777 +120199 +eclair +falcon5 +mjordan +alexandra1 +horsepower +301094 +02071995 +concours +number1son +ping123 +080183 +jessie08 +211296 +24021976 +chhaya +12781278 +gabriela2 +210277 +cassiopea +26031979 +shanky +coolbuddy +winthrop +domino11 +170378 +boxerdog +turtle8 +spence1 +123456gh +1hotbitch +160378 +elieli +12 +sugar69 +030695 +homegirl1 +amoeba +savage23 +conard +pekmabz +1oscar +angelo01 +crapola +madness7 +kondrat +260396 +050508 +111222333q +linsey +abigail +carrie2 +110200 +wowowo +jana123 +190194 +bilgisayar +toby13 +uuuuu +mistycat +barbara1 +11122 +221108 +angry1 +03031976 +nhf +sloeber +13577531 +rockwood +rihana +penny3 +011077 +mister2 +080294 +11071978 +oliver15 +diamonds +sexy86 +25021979 +ordinary +h0td0g +199626 +1234567896 +22052205 +helado +160794 +tiago123 +wedding65 +19861125 +06031978 +sureno1 +whatever09 +pumbaa +coastal1 +osasuna +wildhorses +wahyu +24111978 +devon11 +19861213 +sc1234 +howhigh +ammulu +pantera12 +fishing +bailey01 +joeboy +147159 +tomwaits +pueblo +stupido +dragon75 +poroto +denzil +bubblegum9 +38253825 +290893 +080281 +081983 +presto1 +here +chicony +connolly +newport3 +azules +12345 +carita +ilovejenny +ladida +pow +salah +ivy123 +champa +leonardo2 +sugarbabe +ff +bracelet +shannon21 +160022 +do +olawale1 +10061996 +if6was9 +fairy123 +07021982 +15101995 +savannah13 +cebucity +dragon31 +19091995 +quijote +04081995 +020272 +blissful +19851016 +17011977 +0313 +hello98 +miriam123 +horton1 +browser +060180 +juancamilo +delapan +a12345b +petro +030308 +suckers1 +oranges2 +antonio17 +adekunle1 +eyecandy1 +xavier04 +pokora +arthur2 +wifey +20101996 +ashton11 +austin19 +compac +453 +beatle1 +pizzeria +logan21 +01091977 +florence +141977 +16021978 +020377 +cass +kyla +751010 +bea123 +123456dj +linkedin77 +jamie15 +090181 +amanda26 +241992 +271980 +hope23 +050977 +170296 +ac3sg728 +bestie +dalibor +casey10 +carlos88 +04061995 +bartosz +519519 +pokemon1234 +beegee +151275 +13101976 +qwe12qwe +vampire11 +24101996 +tomaszek +freedom200 +myfamily4 +lilbro1 +199305 +airjordan23 +1bigcock +tee +melvin123 +tamara2 +25041977 +boulanger +amanaman +000099 +130796 +hitchcock +060709 +19021977 +lacrosse9 +skippy01 +dct: ++ +hardcore4 +psp71835 +cangrejo +woofie +silver16 +nokiae65 +mike31 +c7777777 +peter69 +ilovegreg +tangerang +clown123 +260377 +cth +chen +boyz123 +200195 +02061974 +130895 +dalmation1 +idontknow. +monterey1 +adm +.. +123012301230 +lauren24 +161077 +mylove16 +theman3 +xh247ahgum +getmoney24 +xxxxxxx1 +isabella09 +doraemon1 +travis. +busterdog +mari15 +trixie01 +iso9001 +schmoo +700084 +snake13 +backbone +07121980 +test2 +nowitzki41 +winxp +jambo +thequeen1 +fucklove23 +nascar6 +123dan +vanish +michelino +happy321 +120274 +13011977 +letmeout +handle +qwe987 +15081976 +080280 +silvia123 +;tytxrf +egitto +17041977 +091277 +latinos +sierra +bulilit +illusions +steph23 +babyboom +mohamed +perdana +hellosimon +091179 +bruce2 +daniel2007 +alternate +mis3amores +mike2006 +5string +jerkface +200895 +twins07 +casale +050409 +timbuktu +santoshi +m123456 +kevina +1brown +salut1 +doctor12 +700059 +vaz2112 +vanilla123 +hannibal +hutchinson +invent +dus +mirana +gotti +ladybug08 +jonathan07 +sk +lucky26 +aceshigh +cntgfyjd +tytyty1 +080680 +elephant123 +case +jamaica +300808 +31337 +emmalouise +scorpio12 +bdfyeirf +030295 +revenge2 +atienza +krusty1 +happylove +velosiped +приветик +031275 +wayne13 +gxtkrf +27021996 +081989 +ghtdtl123 +goducks1 +samaya +tanner7 +patates +rjhjdf777 +brutus11 +azsxdcf +puppies5 +beastly1 +1sabella +jasper08 +doit +24091979 +iloveme16 +katica +microwave1 +jackel +120906 +shields +52545658 +221272 +199319 +babyboo! +hansol1 +loyal1 +04091993 +yyyyy6 +thunder23 +hawthorn1 +30091995 +bobby101 +lucious1 +dragons3 +2loveu +joker9 +1122qq +lilliput +karolcia +nazar +qwaszxqwaszx +canuto +liverpoolf +061296 +maddie22 +maggy +swisher +hohohoho +mysterio619 +08091979 +jessie07 +a420420 +qavcx411 ++ +zxcv12345 +dimples2 +men123 +a753951 +green34 +erika2 +det313 +131194 +kobold +pepsi22 +sdf123 +19851210 +07061980 +102088 +aeiou12345 +sophia13 +shelia1 +mini14 +dashit1 +rina +0121 +brian! +duval1 +farrell1 +konakona +halibut +wigwam +oscars1 +251993 +140596 +nutty +270294 +841026 +danzig666 +eee333 +jonas10 +03111993 +010496 +motorola +vacance +basketball13 +smolensk +gn9gu44s +incase322 +slovan +cocacola11 +201030 +kolton +della +flyleaf +cbvcbv +richbitch1 +oneday1 +marie02 +bitchass12 +789456123b +241980 +q12345 +limoges +myface +blue47 +23111977 +dangermouse +111297 +08051981 +brice1 +chloe +13671367 +denise07 +sasuke15 +sinaloa13 +plastik +zeenat +alex82 +profissional +bikini1 +13081308 +jack33 +dj4life +divagirl1 +y3llow +300378 +291992 +iminlove2 +love38 +nounoune +anime2 +12123456 +milkshake2 +dungeon1 +miley10 +dododo1 +boys101 +23091977 +1915 +tweety20 +melvin12 +regan +charlo +tarelka +sk8tergirl +rocket21 +yyyyyyyyyy +minous +kthfkthf +ingrid +26111978 +2kids4me +killall1 +poohbear69 +190779 +17081978 +20061978 +lvbnhbtdf +eastpak +marduk666 +athena +121072 +istina +grad2006 +muffin23 +cesarin +danny06 +vikings1 +runescape9 +mammas +tahlia +sunshine87 +23031979 +150177 +ahmed12345 +wicked! +topspin +softail1 +samoan +335533 +duluth +nogueira +skyline +tootall +19861119 +guild +movado +krypto +backhoe +zukunft +blake13 +gregory123 +11011996 +786allah +110599 +caledonia +0325 +green66 +helikopter +import1 +17101710 +secret0 +stokecity1 +mercedez1 +callofduty2 +macho01 +lana123 +sixsix1 +wassa12345 +sallad +elo +56 +philly3 +weldon +muratti +280475 +11071977 +18041978 +hannah20 +060977 +espanha +esther +00114477 +manda123 +821011 +jerryg +perico1 +tweety25 +29081995 +081990 +201176 +21072107 +poohbear17 +choucroute +asdfghj +friends33 +october05 +godwin1 +pimpim +240995 +annieb +fengfeng +1299 +01101995 +sexyangel1 +traci1 +pimp02 +kharen +06061975 +588588 +kayley1 +19831015 +02081996 +mama1963 +lilbitch +15111979 +boston69 +honda8 +bonanza1 +wakana +queen4life +270496 +extasy +petardo +010601 +16021979 +babypink1 +cameron15 +040993 +pi31415 +cute07 +freemind +110274 +rose25 +120872 +987654321g +mark06 +raider11 +spanky13 +ismail123 +111555999 +bunnyhop +themoon +19851121 +jamie6 +mommy18 +hezekiah +lisaann +uuuuuuuu +monkeyass1 +13579246810 +mary +promise123 +louis12 +rose77 +060395 +030678 +vallarta +winfixer +18041979 +julian22 +241096 +051194 +281175 +sudarshan +propel1 +aswang +haley3 +death2u +smile09 +08090809 +thepassword +rinat +patriots2 +19271927 +elunico +fluff1 +nikita98 +jembut +roar +ryan19 +spider! +yellow19 +snipper +sm123456 +longhair1 +051078 +721721 +micron1 +ronnie +eddies +loh123 +090281 +lilboo1 +29121978 +spider6 +091279 +1marley +020201 +thankful1 +4beatles +11041976 +shorty1234 +minka +amazinggrace +040807 +10021997 +236589 +199406 +123456789ma +rosa1234 +dron +karina14 +mivida1 +bye123 +kiler +spike10 +03091979 +badboi1 +emily2005 +willie22 +robertito +150875 +199006 +natalie8 +2121321e +kennys +102489 +swordsman +eazye1 +p0pcorn +13071978 +14151617 +repmvbyf +besiktas1903 +letmesee +honeycomb +hihihi3 +pinecone1 +rocky111 +ilusion +yousmell +latina123 +marine11 +25091978 +iamcool! +focused +123156 +10toes +edward24 +jabari1 +kingsway +258456a +11041978 +isabel11 +hellboy123 +precious! +elizabeth123 +shubha +drexel +iris123 +cezar +trustme2 +lady14 +purple78 +jeep95 +sunshine45 +tintin123 +09091977 +renaldo +crazy8s +070596 +atlas123 +dfg123 +120805 +200008 +moneyme56 +060778 +citroenc4 +linkin12 +17041979 +cassie09 +daniel2000 +skater18 +sasha1990 +723723 +barata +toast123 +purple04 +271296 +angel4u +71chevelle +grace05 +danelle +123456abc +23132313 +19061978 +aaa444 +yuiyui +sweethart +magic69 +636332 +broncos1 +djhvbrc +09031994 +25071978 +01031975 +patria +the1man +02091976 +251075 +mindanao +kaylyn1 +minoucha +hotchicks1 +april1994 +brianna06 +pooper123 +a22j5bffci +540000 +tarifa +has202020 +mama18 +211174 +barreto +jaydog +lacrosse21 +whitley +10081975 +19021902 +cereza +198631 +babar +losers2 +240278 +fucklove10 +cali11 +091177 +vrushali +654321w +vanilla12 +wildcats3 +zverev +chelsy +redskins12 +191178 +victoria07 +14111979 +03081977 +roach +hotmamma1 +diana3 +aniani +100499 +igot5onit +maddie06 +clover7 +company123 +muzaffar +opus +girly12 +20032008 +indianer +ethan03 +1wilson +1godisgood +gentle1 +barnaby1 +cassie08 +jl1234 +killer27 +meriam +charles69 +minime123 +wayne11 +echelon +4everluv +smoky +wehttam +031278 +211994 +1december +06081979 +123spill +07011980 +loller +durham1 +loko12 +supercross +riogrande +hotboi1 +blue2222 +250676 +1qwerty2 +moose11 +asshole420 +221296 +denisov +pelota1 +airbag +energy123 +110105 +fatbitch +25101977 +magic10 +myprince +berlusconi +aaaaaaaaaaaaaaaa +acinom +professionaltools +hanover1 +slime +glover1 +putaputa +emily101 +100397 +101067 +jor23dan +123456mama +help4me +gracie09 +misael1 +ashokkumar +226012 +free2beme +faggot12 +poop24 +sweeti +biblioteka +kok +fizika +midnight9 +021102 +condorito +neha123 +sandpiper +babycakes7 +987654321t +sunilkumar +response +mercedes11 +jaydee1 +qwerty123321 +123321v +sprinter1 +luckyluke +hottstuff +skyline3 +bella77 +140676 +ariel2 +thegreatone +bubamara +208208 +slalom +taugammaph +albino1 +123210 +ilovejuan1 +fotograf +corey8 +ilovedj +brigida +reynold +fuckemall +joanna +123456 +07071978 +crypto +bandits1 +bigboy8 +811024 +assumption +1wayne +mehran +123mike +x8axspumez +mayfield1 +vinicio +lovers14 +macy +100175 +1340 +01092000 +05091995 +linda23 +577191 +suman123 +london4 +ineedu +joeboxer +mysterio61 +chode1 +adam12345 +sophia3 +encounter +14051995 +23052305 +07051980 +flameboy1 +brazzers +tophat1 +rodney123 +alicia23 +01111980 +monique4 +batch +123103 +rossie +11051996 +solange1 +olivia15 +david55 +playboy17 +meshmesh +edwardo +baby2004 +dst1913 +marmelade +heat32 +66996699 +outsider1 +mischa1 +darkmanx +180977 +july2005 +valerie ++ +cupcake09 +lynn09 +sydney22 +hemanth +jojo101 +lj352d1ib31 +celtic12 +14221422 +daryll +xi345bifvn +hanna12 +600089 +asdfg11 +20041889 +kittens12 +051178 +xyxy159753 +сашенька +amherst +badmus +encarta +troopers +руслан +elliemae1 +julian14 +4weaxq642e +1adgjm +step +10011977 +basket5 +betterdays +311275 +single18 +buba +15091977 +kenzie14 +aa123456 +22011995 +300878 +nolase +kadence +11121976 +loulou22 +testme +130276 +ha1234 +tennisball +rudi +26021979 +32143214 +debbie69 +jenner +cindy01 +jairus +puntacana +eqes606898 +3e3e3e +password73 +year2007 +customer1 +singapur +mary18 +natasha13 +dillon2 +190279 +woodbury +876876 +desdes +1katie +19091977 +sd1904 +bubba09 +comander +140195 +tasnim +880505 +admin2 +ginger33 +water10 +828828 +porridge +bigmama2 +ford88 +sam +snoopy. +09011993 +awesome8 +asscrack1 +alenka +abby22 +gerlinde +moto123 +6435 +03kids +mary16 +fairydust1 +andre13 +0919 +kotik +bubba24 +dipika +lastfmpass +sheba2 +beerbeer1 +nina10 +pointbreak +rjktcj +ashlee123 +bloodbath1 +misbebes +hawaii09 +skorpion +deathwish1 +venividivici +orlando5 +houston281 +121171 +4454708 +barber24 +jessica91 +090907 +06101981 +03051996 +hahaha6 +420024 +100109 +sandra. +lauris +trystan +theboys3 +198030 +twiglet +jakeman +19871989 +damien +crazy4life +mater1 +dodge99 +sloane +steve5 +massena00 +30041997 +freaky12 +robby123 +maravilhosa +viking123 +megusta +teardrop1 +211275 +west49 +eddie7 +hallow +greenday9 +dispatch1 +achraf +130775 +sayang87 +allinone +buster17 +06071996 +monkey83 +sexybabe12 +1sugar +monster33 +ciera1 +p1p2p3p4 +emopunk1 +irland +friendz1 +jndfkb +dorotea +dhiraj +blacklist +tiffany9 +211076 +28051995 +01041975 +zxcv0987 +marshall3 +smallboy +673kobby +bosshogg +0314 +prince09 +100296 +120102 +toma +morado1 +886688 +schultz1 +martinez +bubbagump1 +never2 +twinturbo +171296 +19841013 +yuri +slayer66 +sms123 +alpha3 +impretty +ernest97 +antihero +w1ll1ams +coolwhip +touch +355355 +saliva +diablo01 +julian5 +789512357 +nognog +nicolas01 +goodfriend +monkey911 +132313 +redred12 +18121977 +130303 +ivan1993 +norma123 +sasusaku +voyager +120471 +kalafior +mommy15 +161195 +21071978 +les123 +nomads +weasley +time2fly +chikis1 +diamond06 +justinbibe +roofing1 +03081995 +mexican10 +panganiban +270677 +560052 +hummer69 +jake2006 +16181618 +moonlight7 +shoes +221994 +nora123 +composer +060196 +28121976 +troy11 +17051978 +1gracie +kosmos1 +axe123 +mommygirl1 +sammie13 +rhtfnbd +21021978 +050478 +duke08 +15061995 +150196 +l33tsupah4x0r +basketball3 +20081996 +300778 +ittybitty1 +1433 +19841019 +02121977 +20031976 +kayla +pinky14 +faisal1 +pampers1 +sasha2001 +redzone1 +cooper! +piper2 +shawn21 +asdfg456 +trees123 +angel1988 +11101979 +1sebastian +gvqzvxub76 +kiki16 +bunda +thedark1 +101271 +ybrbnf +100574 +tiger98 +bella03 +jetson +cherry25 +18811938 +05121994 +122005 +reserve +ashely +080181 +290794 +albachiara +free4life +nehemiah1 +kader +opium +pierrick +25452545 +lorie +198677 +524524 +pepper02 +1password2 +rachel88 +allstar13 +meghan12 +sosososo +130897 +party5 +mc +axel123 +shay14 +greats +sabastian +0705 +hand +heatwave +mama00 +chase5 +a123321a +wrestling7 +mentiras +daisy06 +youness +serena12 ++ +030676 +10011996 +softball02 +199522 +rosie3 +weener1 +tinktink +1linda +elrey1 +gabgab +04051977 +rossi1 +staple +monkey82 +chopper3 +younger +05111980 +poopoo9 +ilovethisgame +dctdjkjl +kickass! +230176 +samtheman +morris +renan123 +snowshoe +jasper09 +040793 +334433 +motorka +golf22 +23101977 +dime10 +04011994 +mangala +labas123 +lasvegas7 +1434 +artemisia +mummum +getoff +myspace81 +160596 +born2kill +821228 +teresa11 +opelastra123 +mandee +telefonino +denden1 +wetwilly +himom1 +marcus99 +hamdan +lol1lol +xoxo12 +14031979 +gorillas +pengpeng +joejonas2 +414414 +jackie08 +brooklin +malgorzata +bowbow +life21 +nigga01 +tonitoni +29031980 +mahimahi +brad1234 +303132 +gopnik +flatout +solara +lukaszek +angie3 +superbee +abigail5 +micione +mwangi +henry +vasara +canaan +197519 +jaejoong +sone4ko +hokej +tpain1 +jktctymrf +i1234567 +020779 +108 +aa5201314 +sister11 +sexii +rtyuiop +7grandkids +271992 +dodges +taurus +shelby15 +lincon +07071998 +iloveumummy +xdl65b6666 +13121976 +lemondrop1 +feranmi +pazzainter +779977 +tosha1 +crazyass1 +crazykid1 +ashley28 +mimi21 +lynn08 +06121979 +daniel2009 +noble +heygirl +guacamole +1dennis +bmw540 +hayden09 +31081979 +thegame12 +golgo13 +biscuit2 +12347 +auction1 +24061995 +im2cute +tatianna +bizzle1 +booboo07 +fucku9 +autumn08 +tommy +morena13 +cxzcxz +bobbys1 +040577 +fister +120208 +gwiazda +crumpet +qwerty1981 +30051978 +iwantyou1 +21082108 +linked01 +ginger02 +15011996 +louis14 +andres01 +lovebug! +flamengo1 +manchester +minnie4 +carter13 +291990 +ellarose +190678 +12031977 +freak666 +hjlbntkb +heroes5 +divadiva +pumpkin9 +secretos +zzzzzzzzzx +starr123 +13011979 +1257 +minhamae +070994 +madrid10 +r111111 +torchwood1 +cookies10 +eric18 +tucker! +01071995 +iamrich +precious10 +zinnia +love73 +tess123 +firenze1 +jason +capricorni +tupac12 +gunshot +babyblu3 +crownvic1 +takedown +charmed! +inuyasha. +milligan +l654321 +piggies1 +suckmyballs +558855 +26031995 +qingqing +22031976 +fishing! + +downloads +gatogato +goodpussy +12qw34as +missy14 +14071977 +300979 +1234! +soccerman1 +19912009 +westside69 +kaylee07 +molly15 +fattie1 +fruitbat +120672 +19871028 +102345 +hotchick12 +brazilia +cricket11 +jackie09 +10121972 +cerveza1 +xxxx1234 +bambam23 +zoey11 +gage123 +bear08 +wizard01 +streetfighter +060295 +1122aa +callista +anglais +041992 +blackness +jasmine29 +teddy14 +fatamorgana +bente6 +rubberband +neviem +050481 +nathan19 +grammar +yoyoyoyo1 +isaiah4 +181178 +tipperary +moocow123 +postit +210375 +200377 +kurnia +cali1234 +melissa19 +luke13 +ainara +lsu123 +c11111 +lynda1 +liyah1 +u8u8 +7008 +renee15 +29041996 +super01 +bear101 +020405 +niyah1 +alysia +tennis08 +hotpocket1 +erzurum +19071978 +wizard +261173 +aaa147 +dean11 +anika1 +4mygirls +220876 +qoxrzwfr +070381 +texas4 +gypsie +230996 +300476 +2grandkids +nay123 +dylan02 +211176 +21081978 +notforyou +prettyme1 +gammaray +22071977 +291195 +baby420 +4pussy +lilrob +trusty +maria26 +king44 +flowerpot1 +121965 +111171 +080995 +lesedi +uiop +london2009 +harley33 +180794 +loveme0 +plombier +tracer1 +esp +180795 +longview1 +05121995 +cheeseman +lovelyday +seguro +greatday +sofie1 +dima2009 +211990 +wwwwwww1 +darkness3 +cheri +stone5 +christmas3 +babe16 +06111981 +bitch93 +angel72 +kfx400 +blb +piston1 +yellow66 +110899 +hunterx +21101976 +elgato1 +tinchen +super17 +27031978 +brooke06 +emerald7 +garfield7 +infinity +durand +doolittle +jacob17 +baseline +31071979 +01111981 +nikita2001 +george18 +chiqui1 +boricua21 +lovelyboy +colorful +jafjkshf7y6w34rjd +bluemonkey +smiley22 +scouse +catrina1 +fishboy +volcom8 +def123 +nathan1234 +badass! +irenka +avondale1 +cookie20 +anupriya +ghjcnj123 +pword +1029384756a +aj +fairlady +260977 +jellybean! +blue789 +connor4 +ilove$ +brooklyn! +banking1 +tumble1 +pashtet +yahoo.com1 +alexx +marines12 +oldies +020995 +kimberly1 +peeps +040678 +tiggers +marie90 +opanka +music12345 +manju123 +kaelyn +199013 +markjohn +19111979 +smiley23 +140476 +mmm333 +sandbox +kenjie +fuckthis12 +260778 +st1234 +eman +india321 +spliff1 +skills12 +harley9 +sub-zero +brianna09 +09021980 +acosta1 +schatzie +kaley1 +keshawn1 +5angels +rip2pac +sex777 +210278 +122805 +alumni +11061978 +tony1 +11051976 +20011977 +cellular +cassie +13451345 +m1space +qazwer +twilight8 +dance15 +alexis97 +ivor631996 +leafs +105 +270895 +cheer6 +icecream6 +raymond5 +email123 +greendog +yankees +grandma! +highheels +101064 +futsal +vbkkbjyth +sucette +monkeyz +070608 +fiatuno +29101995 +15101976 +vfktymrbq +08091995 +girafa +homie3 +aaron24 +babyboss +malik2 +romani +380008 +crystal08 +paradise7 +honey19 +sierra99 +stiven +scranton +rachel07 +001970 +adidass +besiktas1 +kittygirl +busola +20071979 +poiuy123 +goats +wan +sprinkle +albita +123987a +copyright1 +blessed11 +james31 +poetic1 +336688 +flip12 +11121975 +njqjnf +alexis20 +vjs9zdgyrn +playb0y +marvin13 +sammy24 +blackeye +goal +01041976 +junebug2 +30011994 +friend! +hahahehe +159630 +331133 +shrek3 +omolade +xxx123xxx +kenneth7 +199107 +numbers123 +diapers +enteng +199424 +veleno +19052005 +hayden3 +seasea +220674 +889889 +integer +160597 +weapons +luvme +britt16 +thuglife3 +12345hi +nkechi12 +px6gcr51 +burns +fernie +1water +fatcow1 +110697 +love4him +05081979 +sanasana +1linkedin +wade23 +beast11 +nothing11 +tierney +1x2x3x +rockers123 +harrison12 +stupid22 +18111995 +annamaria1 +razorbacks +winter23 +021196 +miller7 +leslie3 +puerta +quita1 +cheena +170576 +w1952a +cookies9 +08041978 +aaron +bball07 +imapimp +celestin +matrix00 +futbol7 +18091979 +ownage123 +sugarcane +wooden +inception +siemens123 +iphone123 +corrie1 +16899168 +010901 +london24 +1albert +101269 +torres +fritz123 +13011980 +diamonds12 +salford +summer67 +player18 +280277 +120508 +yfgjktjy +lunch +donvito1 +innov8510 +mascotte +loner1 +migrationsandeep +titanic +great8 +27111993 +hdfcbank +1boricua +31031978 +thunderstorm +rodzina +skylight +france +boriss +18081978 +oliver69 +erwann +vagarsh +11061976 +210101 +stephane1 +kathleen12 +torrey +sonyvaio1 +hershey7 +89 +3323 +simple01 +tulpan +dalailama +towtruck +schranz +jaxson1 +nefertari +teddy4 +allme1 +1qweasdzxc +vegemite +kucing123 +schizzo +fenwick +vainilla +whatthehel +rayray23 +fiddle1 +gonoles1 +jazzmin1 +102400 +youaremine +house11 +luis19 +inspector1 +sexi101 +sexygirl16 +spencer! +sublime7 +reptiles +nagato +170977 +leblanc +12061997 +jimmyjimmy +britt07 +dylan15 +30063006 +beba12 +pink321 +patrik1 +khushbu +03031997 +bambam! +270978 +busterboy +160377 +elmwood +madi +whatever14 +ilove! +101173 +090793 +seabreeze +p455w0rd +slyfox +chigger +110806 +matt77 +ftbfrvlg17 +422422 +ernestina +burnout3 +mercy123 +kyle08 +moxie1 +regina +2n6ezl7xhp +200295 +ikke +1q1q1q1 +torment +eminem313 +carrillo1 +snickers13 +panico +william03 +241275 +abucanda +130196 +??????????????? +lee12345 +schuster +vfvfif +hardman +250375 +babyboy24 +24061979 +yahoo69 +fuckme6 +080108 +shelly +cangri1 +belmonte +allie2 +autobots +hottie55 +110872 +as0000 +210674 +ranger6 +caca22 +s39jwbw5ia +kaczor +sora123 +anggun +566556 +9021090210 +141996 +space5 +luisalberto +newbie1 +daniil +cheese +badass22 +1824 +blessing123 +augusto1 +crusade +beetlejuice +raiders15 +tiger2010 +chopin1 +cirillo +300600 +123789abc +hardwork1 +yummy12 +summer96 +sideshow +090678 +1cor13 +maimaiyeuem +runner11 +28051979 +viki +asswhole +duncan12 +zoey1234 +27051977 +boriqua +a42904290 +christmas7 +nopasaran +ivan1995 +batman27 +joker007 +teamoamor +041194 +eminem15 +301176 +grade6 +caddie +marie86 +donita +romnick +frank21 +cintaq +25011979 +bs1234 +fernando. +coolguy2 +27011978 +125001 +juicy69 +whitewater +buddycat +231072 +medion123 +madoka +lovedetoi +toshka +fernande +sureboy +strawberr1 +young3 +091194 +rach86 +password40 +zxcv123456 +amb123 +satriani1 +150375 +555555555555555 +london12 +1388 +patient +270295 +niania +19871025 +collect1 +123951 +85207410 +love1313 +funny3 +090309 +fresh14 +booboo18 +usuck123 +fred1994 +felix13 +ronnie11 +iloveyou98 +rmz250 +04101981 +abel +clubber +colombiano +arun123 +pawelek1 +vicenza +fairplay +menmenmen +milkbone +18061996 +200378 +carter09 +wkgmmjh623 +myhumps1 +noah06 +cheese0 +alamo1 +011278 +kelly1234 +poopstain +santodomingo +tara11 +lop1346781 +kepompong +loveu7 +perro12 +19081977 +21021979 +15051996 +bonnie3 +bettis +garfield1 +treats +090694 +030608 +peanut1234 +cassidy12 +210376 +killa4 +london! +erection +69camero +melanie01 +lollipop8 +07091980 +kikelomo +cheer9 +penguin1 +loneliness +casper! +dorothy2 +28121977 +132456789 +darklight1 +lakers! +2266 +nichole123 +bunnies2 +hillview +john27 +yourgay2 +kiakia +841022 +password1. +24031979 +loveyu +blanchard +sexybum +april89 +110303 +mattew +zebras1 +150876 +198488 +chargers2 +03021977 +twenty5 +nostress +joelito +dirtbiker1 +timothy5 +golfer2 +198731 +foshizzle1 +11111995 +09041977 +love1love +score1 +renee09 +johnny16 +covergirl +195900 +studman +raymond1 +gothic12 +john26 +qeadzc +steelers +getatme1 +26091994 +gfhjkm12345 +samana +callum12 +bullshit3 +sportage +16111978 +daniel2010 +johnmayer +ora +southside9 +romans828 +manu4eva +blonde12 +5demayo +onemoretime +chicago8 +adrian16 +bubbles99 +250695 +sona +pink32 +delvalle +plato1 +fuckuall1 +mamie +hunter01 +abcdefgh +snoopy08 +priest1 +070194 +football04 +minty +acqwah +crystal09 +walker11 +bluerose1 +cheater! +иришка +mario4 +13071979 +j121212 +jeep99 +sexyblack2 +anycall123 +bella19 +greygoose +11091978 +corkey +justin1 +ranger88 +newlife2011 +scooby08 +hash +soccer10 +rose07 +bodensee +spaceballs +london55 +020777 +801225 +children7 +happines +afghan123 +230874 +new +dude77 +diksha +babyt1 +submarine1 +hevhk43n9j +a7758521 +070694 +crazy111 +180596 +20021975 +120272 +15031503 +gampang +emma09 +tyler. +1234567890a +01121978 +beirut +chicken99 +magic21 +george17 +20031997 +1234567891234 +chopper7 +maddi1 +149149 +06121995 +13051979 +19061994 +821210 +filippo1 +phantom7 +potters +spellbound +mama1961 +frosty12 +bruno01 +neymar11 +w1953a +justin91 +ellie2 +hokuto +alquimia +pallas +922j5cefcj +040498 +tyler97 +india12 +peaches10 +costas +macduff +greshnik +raiders20 +140298 +414200 +9119 +091295 +gege +523252 +lolman123 +thebible +1brian +oleg1998 +zxcvb1234 +doughnut1 +amoah2010 +65 +qwertyuiop789 +jamesy +mykids04 +swab123 +ladybug22 +magdalo +angel1998 +hannah1 +shanes +kaylee11 +howard123 +minger +alexander11 +32 +orgazm +kristina +14121976 +801123 +caitlin +george1 +303 +dawkins +balanar +12345678963 +admin01 +messy1 +sagopakajmer +imissyou! +mmouse +sadness1 +231296 +cavaliere +261275 +12051976 +toasty1 +saintseiya +fairytale1 +090409 +grissom +129 +nigger420 +belgarion +phalanx +20011996 +lac +061979 +vegeta +hunter666 +lafrance +240996 +thuylinh +tem +fishfood1 +azerazer +flowers. +bruxinha +030503 +05021978 +mattmatt1 +123abc1 +babybash +1potato +nikki24 +bookmark1 +hedimaptfcorp +8x2h4fccap +karen15 +penguin22 +19111996 +lucy08 +marley08 +wmtmufc1 +catseye +fall2007 +skater99 +v123098 +16021977 +19841121 +06071979 +camry1 +01051996 +29101978 +234649 +ferndale +bubububu +21212 +grunge1 +louise23 +muffin14 +bk4life +09021978 +cowboyz1 +021296 +dalila1 +mandy11 +boomer +codybear1 +viking12 +orange66 +130377 +ha123456 +181983 +boredom +cowboy9 +hunter94 +suplada +buxton +21051997 +anthony29 +20081978 +massey1 +kmdbwf +oreo01 +boss22 +02071975 +281095 +djkrjd +dragrace +tema +hamster3 +atown1 +backdraft +elzbieta +deltas +babyfat1 +patricio1 +210505 +house5 +05021996 +automotive +noworries +thatguy +kenny69 +sexygirl! +fireboy +250476 +0923 +donkey3 +memere +camisa +hotmama12 +kenz4u +fuckyou90 +198013 +hotmail5 +music06 +jackie6 +oreo14 +pimpette1 +riding +zaira +fourier +160376 +cookie02 +britt15 +bigboy08 +lucas +toni12 +galatasara +28082008 +fire10 +210574 +pirates12 +atlanta123 +iloveyou.. +lovebug10 +27051995 +sumeet +notme1 +2bhappy +26101979 +kkk999 +murphy7 +211006 +1alejandro +sarahann +reject1 +longhorns7 +140299 +06061977 +030477 +snow22 +kissme23 +masha1998 +carrera4 +timmy01 +102001 +eros +buttercup5 +falcon13 +homeslice1 +bunny21 +rimbaud +mickey27 +redtruck1 +badazz2 +polinochka +sssaaa +cuddle1 +k1mberly +katie +useruser +19861110 +ilovehim10 +steph21 +cutiepie23 +fishing01 +panthers5 +spike69 +crayons1 +ps2ps2 +damien123 +olga12 +deaddog +snowman7 +smartone +ghjcnbvtyz +brunswick1 +pepsi23 +princess1 +gazebo +thorpe +asd147 +2513 +source1 +25111995 +kekette +thommy +andrey1996 +latifah +faithy +linger +mason5 +redsox14 +awesome101 +booya +gonavy1 +manomano +23031996 +orlando11 +pejsek +ohmygod! +jackson24 +antiflag1 +080681 +jenny24 +dr.dre +ingegnere +cowboys33 +11121977 +161994 +ego +slipknot22 +ricardo22 +kroger +hulkhogan1 +25031978 +kisskiss2 +11031975 +getit +killer777 +maddux31 +bettylou +400091 +green00 +31051977 +boarding +fire21 +welcome0 +30081995 +260278 +atenas +digger +daddy25 +dreads +kobra11 +310794 +potter13 +jess16 +turnip1 +19851223 +mushrooms1 +abcdefg3 +7399 +kingdom +jamie07 +monkey81 +bf1942 +slipknot14 +powerplay +snowbird1 +07111992 +markovka +alex76 +caleb3 +janine +stormers +170496 +ramboo +19860214 +2joints +sharron +bidadari +mari10 +liberate +281980 +fhbyjxrf +010166 +honda1234 +dascha +spike5 +2q2w3e +ilovesoccer +pw123 +200609 +1barbara +030281 +nadine123 +tommyg +scrappy13 +251175 +beverley1 +17091976 +101510 +jameslee +2jab4x2c +jbaby1 +institute +yygjmy333 +sss777 +080182 +heinz +28101978 +victoria15 +29121995 +larissa123 +zenobia +sodiq1 +1313131 +keanu +c0c0nut +harvey2 +02091975 +tete123 +emma14 +whi +poligon +confident1 +16081977 +dub +freefood +123car +hug +money888 +1234567ab +beast5 +scoobydoo7 +mike92 +050572 +110573 +backflip1 +120700 +qaz147 +diamond18 +1617 +kandi +1christine +10101973 +joselyn1 +linkedin23 +pragati +protege +mentira1 +america07 +517501 +fuck1 +wacker +savannah08 +samuel09 +george16 +warrington +jesse18 +gipper +line +ch1ck3n +kakka1 +helloall +fatass3 +jordan90 +carmen69 +jessie09 +080394 +longdick +310576 +fuckyoutoo +der123 +hola12345 +eliza123 +power8 +p00000 +chevy2500 +1orlando +brn521 +truffle1 +diversion +jayme1 +070309 +1qazxsw23 +kurgan +dmedcn23sd +manunited7 +hunter89 +hodges +innainna +bab123 +smile4ever +natalee +raj12345 +kolesnik +berkshire +fandango1 +computer69 +200275 +131296 +diletta +simon13 +aaliyah08 +7412 +quiero +193746 +08081973 +barney10 +serafino +xhh787qpcd +7117 +foxxy1 +hopscotch +ketrin +password7 +3tb8xl42bj +poekie +marissa13 +abcdef4 +821024 +cheetah12 +poiuyt123 +headbanger +102578 +fuck66 +913913 +c6djvmskcx +jalaram +lilly08 +kobayashi +marco11 +fender! +xochitl +130373 +joker45 +goldie2 +001966 +090593 +lwf1681688 +koalabear +polinesia +lambo +11223345 +john0316 +spaceball1 +p1assword1 +dallas05 +#1nigga +hockey89 +417417 +10071996 +daughters3 +alicia21 +19032003 +corrina +329329 +angie23 +bilal1 +stpaul +111198 +021992 +theone01 +nanner +kissm3 +gummy +20032007 +19831022 +jourdan +jc12345 +system +prince! +rebecca4 +ramada +whitegirl +15041996 +11121996 +3311 +821225 +uhbujhmtdf +7355608 +kelly15 +superman30 +whoami1 +matt25 +micael +mistyblue +190895 +27071978 +kupa123 +brandy21 +g00dluck +11041997 +150475 +110574 +04071996 +2214 +crusaders1 +ras123 +remember7 +soccermom1 +0601 +dylan +raider2 +bovine +roxyroxy +16011996 +1244 +cream123 +werewere +jonathan69 +abcde2 +charlyn +andrew86 +life09 +hadassah +ricky4 +jake +wo123456 +blue91 +find1234 +alejandro +luis20 +821022 +munkey1 +alejandra3 +lovesex69 +hjlbjy +poirot +061078 +1cocacola +333aaa +120107 +n00dle +1patricia +hossam +panda! +repeat +gemelas +brenda15 +66 +south2 +melo +att123 +myspace.1 +11794591 +sadie07 +idinahui +010597 +dandan123 +genuine1 +parker13 +ilovebritt +things1 +toto22 +310775 +qwaszx +tipsy +muzica +sliders +emmanuel123 +marge1 +autumn3 +angelo +emily17 +070280 +prince33 +october01 +crazyone +awdrgy +120569 +85chevy +poke123 +mojo69 +sunray +kahuna1 +123456sd +silver18 +skripka +rock88 +fucknut +gegege +hap +280377 +wasdqe +metall1ca +25011978 +daisy09 +071982 +guru123 +princess82 +locos1 +tigers84 +terter +504boyz +september22 +airplanes +jilipollas +valval +rocks123 +19870101 +199124 +norita +jirafa +allison13 +fuckl0v3 +january09 +deadfish +alex32 +faisalabad +090183 +verynice +gurl123 +asdfasdf2 +krasava +wilson5 +barabas +neisha +121261 +jigglypuff +setting +qazxswed +300877 +201100 +landon3 +fuckyou45 +froggies1 +thing +110197 +emoney +sommer123 +2345678z +warthog1 +tigger67 +13121975 +z7895123 +sharon11 +sereja +demented +rocknroll! +papang +bogdana +cvbcvb +new-york +sofias +pooh69 +hotdamn +paradigma +almita +198630 +natasha3 +tiger27 +eddie5 +ferrari01 +lafamilia1 +27051978 +eddie4 +phoebe01 +alejo +selvam +nidhi +123m456 +mirabel +biking1 +19051997 +5point +shahida +monster16 +justice01 +garrett3 +fire101 +sampson2 +tanktank +smokey8 +310197 +junior33 +33221100 +inlovewith +пїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕпїѕ +yelhsa +babydoll7 +041296 +february26 +09081980 +lounge +22041997 +pragya +14241424 +tysons +boomer4 +120774 +vanpersie +allen21 +cocacola13 +080581 +athena12 +espero +smile24 +ripped +galahad +behemoth1 +guntur +rafferty +1corona +cfdxtyrj +brijesh +02091995 +270279 +7777777n +15031977 +120198 +chronic2 +emachines2 +kenny6 +myspace82 +desiree12 +20111976 +twilight9 +green111 +010165 +robert44 +190694 +15092007 +frank7 +115533 +alican +ams123 +230796 +motherhood +crystal16 +2020202020 +index0088 +angela. +1147 +khan12 +040979 +031990 +golf4fun +jackaroo +nikki1234 +hallodu1 +lovelove! +050403 +00123 +alley +halo12345 +samuel4 +omar23 +22071979 +bookert +coop +nichola +milo11 +4thofjuly +asshole99 +lala07 +trippin +zafiro +z19721226 +parkur +25071977 +silas +19011977 +28041979 +500 +fourfour +cooper06 +sliver1 +25132513 +denizli +qwaszxqw +poczta1 +monika11 +09051994 +amiramir +kisame +detroit7 +021202 +money321 +montel +apolonia +190179 +muggle +money1 +joker8 +bella02 +kandice1 +mason06 +sunny1234 +zachary! +ybrbnby +pinarello +damon123 +coco1 +821013 +091093 +197219 +sweety22 +pollo12 +190278 +241994 +zizou10 +bitch56 +makeme1 +pollop +nokian81 +nigger8 +200696 +deniska +mundial +gate13 +piglet01 +bulaklak +ilovewill +hello456 +honey27 +110474 +jdnazp972x +munchen + +tobby1 +loverboy3 +210275 +22031975 +peyton08 +parker10 +special1 +13111995 +rosebud7 +sercan +lindsay12 +mooo +pickle13 +descent +041278 +09111981 +300596 +myhope +dabulls +jake18 +julio11 +23082308 +westbrook1 +connie2 +332 +tequiero2 +finestra +cntkkf +shammi +chancey +loveme4ever +twilight123 +teamomiamor +yosemite1 +marcus15 +vfvfvbz +lover06 +java123 +pirate12 +120497 +ryan2005 +sanyika +summer45 +140276 +sports21 +c54p7uikgb +nivram +sandydog1 +boo1boo +25142514 +heaven10 +bobs +0000aa +redsoxs1 +21041996 +231074 +sonson1 +98chevy +christine5 +04121994 +brandon00 +attila1 +bask3tball +tyler12345 +deadman2 +bikerboy1 +simon7 +money2011 +doctor +pebdfcz3yx +delatorre +lillies +acid +maryjane. +opopopop +30101996 +813813 +luvya +athletics1 +tinker8 +fuckyou44 +hs16andi3z +19851203 +golden22 +ilovemike! +20101975 +brittney2 +camaleonte +kulikova +15935789 +mayito +adele1 +020476 +password51 +chad1234 +benji12 +maksmaks +01101977 +hotels +qq123000 +fucku. +warhead +16041977 +francesco +cr125r +rebelde10 +acc123 +110100 +namaskar +homestar1 +29061996 +lapine +excel +chuck2 +kingme1 +david87 +121068 +waterwater +aziza +emma +flipper2 +abigael +197722 +ballen +brigadeiro +brandee +lamar123 +1kenneth +blondie01 +salad +circuit +were12 +180898 +29081981 +454 +lambretta1 +pink!! +199325 +tallyho +indian12 +sarkis +julian23 +kirankumar +horse10 +uranium +marcus06 +bigboy! +sheckler +team123 +21252125 +deepsea +apple08 +sun2shine +iloveyou56 +200009 +goons1 +macie1 +199405 +kari123 +urmomma1 +pa88word +sarvesh +eee123 +fcinter +funkytown +bernie +unitedkingdom +141979 +19101978 +fishy2 +malaguti +7777777k +onlyyou1 +1213141516171819 +nemesis +watch1 +16121977 +22051996 +doublej +dic +nancy13 +cruz123 +madremia +goggles +811020 +ravshan +lilmama4 +199014 +klaus1 +19932008 +house4 +keyshawn +glenwood1 +27121978 +040709 +190879 +pacute +henry13 +010168 +5550666 +nicki123 +mohitb123 +020307 +135qet +fredy1 +connor02 +icefire +beepbeep1 +95camaro +superman45 +angel2001 +sammy05 +jack25 +drifting +absinthe +teeth1 +16121996 +maggiedog +061980 +canarino +ghjgecr +pasta123 +17071978 +18031978 +suck123 +bitch321 +558899 +love63 +minime2 +kesha +14jesus +mexico90 +newfoundland +q2w3e4r5t +justus3 +ou812345 +blessings7 +karibu +b-ball1 +yo12345 +010278 +garance +nunu12 +oleg1996 +arbiter +200406 +lerolero +bicth1 +loveydovey +diva4life +lisa15 +16101610 +sexybitch5 +dfhtybr +wunderbar +19861215 +ilovezac1 +bitch90 +bljs2v85pt +nirvana1 +mima +hjvfyjd +dontask +master12 +saturn12 +lovebug69 +alberto10 +kirill1998 +cheyenne13 +21031996 +cheyenne01 +myself123 +kristo +ch3cooh +papucho +07111981 +dallas15 +deion21 +140675 +198018 +girl69 +luluzinha +0807 +tampa813 +adgjmptw +851125 +star93 +claremont +131980 +joseph00 +kocka +killa9 +lammas +instructor +phatboy1 +cars11 +kenneth1 +ncabeax2vx +schaefer +290779 +petshop +sudha +19841224 +angels69 +midnight69 +568568 +290477 +star28 +amor20 +outlaw69 +rodney12 +123david +braeden1 +princess83 +hmfan1 +heavy +singleagain +articuno +sylvan +mantis1 +290695 +78917891 +031076 +sixtynine6 +rocky25 +seronoser +gamaliel +500076 +tylerd +insect +olivia16 +storm11 ++ +12101975 +carson2 +wolf01 +maremma +franka +eyeballs +stupid0 +donnelly +chester8 +241097 +alexie +veczhec +rattle +diana +170696 +надежда +alone4ever +742617000027 +harold123 +mariapaula +251981 +170976 +slippery1 +29091977 +2turtles +231200 +100374 +1corazon +dantdm +1sexygurl +robert66 +hellyea +gallito +internet3 +05051971 +miranda11 +dildo69 +wilson13 +lolomg +alf123 +27121977 +1tucker +04041974 +dibble +famous21 +lemons123 +240675 +britton1 +02061972 +zaneta +steelseries +0246813579 +hfcgbplzq +swami +11121974 +julia3 +superduty +08101981 +stming4 +ghazal +making +compaq +mexican15 +fred20 +21081996 +elektra1 +edward25 +vincent01 +060195 +2letmein +919919 +dlnvhvu492 +chem +coolblue +pebefcz3yx +ethan09 +19111994 +limanlly +hunting12 +froggy01 +121600 +vin123 +navara ++++ +panther9 +trener +28101979 +roby +251979 +renee23 +eastside23 +imbecil +willwill +omarbravo9 +level +rebelle +10091978 +tweetypie +jack17 +bulldogs13 +slim12 +nokia5 +winter02 +louis12345 +wolves +hardbody1 +221022 +cortland +albano +bunny9 +sumit +mathers +ahmedahmed +mali +060506 +camaro01 +matrixx +educate +f76t94prm4 +ricky5 +wendy2 +irock13 +trouducul +singlemom +ethan10 +suzuki250 +821017 +030494 +woainia +fishlips +ransom1 +chris84 +chitchat +250397 +27041977 +rdfhnfk1 +darya +bobster +bebep2x +bobcat12 +bubulle +m123321 +leopard2 +121256 +silver14 +cooper +monchi +nirvana5 +jujubee1 +l123123 +pegasus +411 +modeling1 +cirebon +brayden3 +pizzaboy +elton1 +kelly! +allegra1 +030696 +rayallen20 +24081978 +87651234 +thtajehzsp +199991 +sabrine +010708 +anniversary +grandma11 +qwsxzas +21011979 +teepee +croquette +escargot +cartoon10 +nikkisixx +bear15 +mikala +eljefe +1peter +ireland3 +jeremy8 +gosiaczek +huntress +wizard13 +jkz123 +shadow26 +nigg3r +03011995 +billou +prasad123 +bombshell1 +felix11 +chris1993 +711 +090594 +lalla +nuncamas +jysgy2yd87 +gig +132123 +toosexy1 +satheesh +512345 +thong +jess18 +denis1992 +babicka +121388 +ट +westwind +toothfairy +datuna +julian05 +asskicker1 +iamcrazy +02011995 +lfc1892 +tiger66 +kentavr +lifestyle1 +bluecat1 +linux1 +makanan +cracker12 +tkfkdgo0 +231274 +12051997 +flexible1 +angel76 +teamare +cipher +hunter26 +jyotsna +sahhas1221 +chris4life +1sucker +ruby10 +dare +cheerbabe1 +chula12 +burton123 +sasuke101 +boateng +ermakova +thomas44 +barnyard +sonusonu +outdoor +18011981 +oakcliff1 +joseph77 +pamela11 +03121996 +sidorenko +vagina. +09081993 +guitare1 +horseshit +sweetman +nata12 +mcr666 +jordan44 +3369 +twentysix +02051972 +alessandro +christine! +pingu +19391939 +silver24 +marmeladka +only14me +balto1 +renee08 +pilchard +hello2u2 +redneck5 +16051997 +ninenine +desiree123 +blarney +nugget12 +19871020 +sudden +retriever +821226 +282002 +jackass101 +skate420 +fred10 +equity +johana1 +1316 +heart14 +tinker15 +rusty13 +12111995 +verdao +yodude +12091977 +landon09 +stormy2 +sweet90 +jesusis1 +indian +alyanna +191295 +199007 +teamomama +lucy23 +19801982 +horny4u +sumsung +eddy12 +gennadiy +jhonjhon +papermate +tippmann1 +stepup1 +juli123 +june1979 +d0023500 +omg12345 +werken +170196 +michelle29 +england10 +arnold +linked1 +bul5tacumi +flipside1 +199621 +bibigon +chris83 +bayarea +loka12 +18021996 +corgan +sherwin1 +123.com +grinder1 +balla2 +06041979 +foxracing2 +hiphop! +chato +le_den_ec +aron +fashion! +yourmom6 +carolin1 +bitch92 +230476 +ihatemen1 +apples10 +meme10 +wanker123 +120871 +try123 +mathilde +220776 +meloman +861229 +19901991 +lolazo +matthew26 +hanger18 +colts21 +fallou +smores +195000 +szgd4ey287 +weeds1 +taburetka +bachir +cashmoney5 +19021978 +79transam +teacher5 +lilflip +superdave +eminem1234 +cleocat +060995 +handel +06041980 +22091979 +flatline +amber06 +oleg1997 +300478 +liljoe1 +icecream23 +mamimami +tiwari +18081979 +14041978 +300500 +18071979 +maddie05 +cry +chica13 +october03 +redneck16 +0806 +dhillon +michaels1 +hello56 +alessandro1 +963123 +400009 +fhtylf +000022 +01011910 +198118 +mistico +incoming +michal12 +merrick1 +310795 +18031997 +owner@hr.com +rocket69 +cordova1 +campanile +максимка +marist +1366 +biggie2 +hotdog23 +bestbuds +az123456789 +hashish +32615948worms +multik +loveisall +663366 +1remember +joselito1 +thomas97 +layne1 +mailliw +marijuana2 +simple7 +forza +shaniqua +s987654321 +2222ww +amerikanblend +r11111 +211003 +20091975 +20012003 +fuck50 +janet12 +natalie06 +john5646 +techno2009 +vaughan1 +22101977 +rafael01 +secret08 +naruto123 +chelly1 +ash12345 +04120412 +z223856 +bananas11 +simon11 +jablko +artem2010 +daniyar +june1998 +perkele1 +indore +karpova +210896 +p@55word +kool23 +sweetie8 +12521252 +17021997 +281978 +andreu +arabian1 +141276 +310377 +augie1 +2300 +29091976 +ivanovich +xavier4 +25011996 +samuel15 +donkeys +1738 +kyllian +ha +dimepiece1 +fishpond +purple87 +k.,bvfz +iloveluis +qecegda3zx +bluesman1 +280378 +agency +hailey7 +hotmale +26021996 +breanna3 +jack2009 +robertpatt +zaqxswcde123 +nfvthkfy +19021975 +student12 +21011977 +070680 +danville +24121995 +tinydancer +doggy4 +261980 +swastik +moosey1 +west14 +chuck12 +zxcv4321 +castor1 +wer123456 +251994 +roma2010 +damian +ws123456 +hellya1 +141000 +batman44 +ninochka +bluegirl1 +loveu13 +pontianak +kamogelo +london2008 +281992 +bryan5 +24031977 +peach12 +statistics +miranda5 +earnest +nick05 +19861115 +felix01 +pelayo +050909 +110102 +vova1997 +ihateu12 +heather17 +racecar2 +logic1 +thomas28 +tidbit +789523 +gamestop1 +zimmerman1 +qazxcdews +pink143 +juan17 +vtkmybr +galvez +doggy6 +842655 +120469 +qwerty1985 +abc123def456 +maadurga +pp +division1 +bitch!! +b1b1b1 +jeanlouis +dcba4321 +redbul +tegan1 +mantha +gateway2000 +kj1234 +freedom55 +totenkopf +201212 +7thward +mandy01 +ranchero +uloveme +kisses69 +richard18 +rasta420 +thomas91 +martes +19041978 +felixthecat +197925 +monster18 +timothy01 +sephiroth7 +bepositive +fatcow +yxp7wbewpk +050778 +destiny69 +sepatu +minnie5 +angga +godsson1 +no1butme +medtech +yomomma! +nitrous1 +oceanic +smile9 +harris123 +megaman3 +qazwsx13 +mayo +harley. +chinenye +tyler2000 +beaner13 +mona1234 +05101978 +tatita +georgia01 +darkdevil +socom +berto +19041979 +lotto +lord1234 +bloodymary +cole13 +daisy123 +freddy! +reymark +stalin1 +devin13 +rebell +1cowgirl +l11111 +060675 +stayout! +ytrewq123 +elijah23 +toontown1 +hardaway +melvin2 +lawlaw +motorola +s123456 +197419 +azerty77 +fuck111 +dominator1 +sean14 +asdzxcqwe +seanjohn1 +kissit +11021998 +life23 +3three +noah07 +aubree1 +070195 +amoremiotiamo +28091980 +murphy22 +dedication +jayjay6 +littlelady +r1r2r3r4 +singel +lacrosse4 +259758 +brown22 +scrappy12 +roro123 +train123 + +130013 +hiphop5 +jumpoff1 +new2me +payton01 +imsofly1 +fucklove09 +loveable2 +171995 +silver! +1surfer +hotboy7 +jannet +bulldog1 +thug13 +pinky69 +trabzonspor +dune2000 +kzktxrf +cameron04 +16081996 +klausi +tantan1 +1jenny +21011978 +801020 +aa111111 +29041979 +195700 +fancypants +stella! +fellini +300575 +rencontres +100871 +malhotra +mauri +oneman +fresh10 +120498 +peanut04 +mj12345 +merino +chester10 +charles8 +big +xavier +097531 +mickey00 +booger13 +difficult +22061977 +0zero0 +19851001 +27061979 +bigdick7 +oliver9 +special123 +arusha +12sexy +1louise +funny7 +rdfpbvjlj +asdfgh3 +110506 +badalona +peppone +menmen +dasha1996 +gillingham +pirates123 +831022 +yendor +girl15 +mitsou +13091309 +ladonna +19861103 +fuckyou02 +emma23 +mama19 +110309 +200675 +purplelove +oliver6 +dinesh123 +black26 +140894 +revathy +brenda69 +jackie18 +ctvtyjd +241098 +cutie69 +sweetstuff +tinotenda +march1993 +040280 +punjab1 +cuddles12 +malala +duhast +kittycat! +cby +bossss +antonio69 +france12 +kathy2 +chiquis1 +mama1997 +theused2 +hailie1 +bojana +surfin +voltage1 +celine +gurunanak +juana +pieface1 +romano1 +ethan4 +mackay +hustlin1 +panocha1 +14011401 +16101977 +bluelight +fractal +hello66 +xiaobai +7890uiop +manuela +0912345678 +18041977 +112369 +lilone13 +papako +lynn07 +gil123 +joel23 +0xzryx +260196 +kitty25 +melena +janay1 +southgate +230795 +811228 +tobi123 +kisses23 +diamond17 +05101979 +iloveyouja +dragonballz1 +belen1 +texasmade1 +pussy. +downey +soulfood +hotbabes +tootsie +181995 +steph15 +dylan23 +nathan98 +811018 +sara15 +grandma01 +olioli +deanna12 +track12 +bigal +skittlez1 +04011980 +whatif +cyt +midnight8 +30061979 +luisteamo +kriska +209209 +150276 +taniya +jax123 +duhduh1 +dachshund +eeyore2 +stella10 +wanderlust +loveworld +stayoff1 +1277 +261174 +scrapper1 +carlotta1 +porcinet +271172 +th +mexico00 +080194 +fatty5 +nabilah +asilas +wonder123 +12381238 +surfen +terriers +ginger18 +hitman11 +fuckit5 +jason420 +zombie2 +sensation1 +daniel83 +matylda +sophie1 +coconut12 +851123 +teeth +crissangel +s112233 +dinamita +231000 +debora1 +15121975 +12457896 +tomahawk1 +hearts11 +sugarsugar +bobbyd +getdown +liza12 +bandit14 +sn0wball +patman +poet +mysoul +gallant +hardcore3 +7895123z +kingss +sabertooth +beauty101 +ilovezack1 +relax1 +dalia1 +bribri123 +rjhjkmbien +mildseven +twins06 +love210 +gizmo69 +08121994 +shotta +omg999 +180196 +torpedo1 +rubyrose +lincoln8187 +joker99 +newlook +larisa1 +iggy +sawsaw1212 +reminder +0521 +digger12 +anna06 +parrish1 +frenchfrie +aqq997 +shanell1 +26061977 +andrey1997 +sassydog +ytq9bkr +deicide666 +thesame1 +banana14 +ballas +shayshay12 +bassfish +margarette +faygo1 +henkie +190495 +anatolii +benoit1 +22121996 +ra1ders +jalisco13 +andrew55 +senior04 +christ3 +cocacola10 +myspace999 +1580@welca +200404 +sidekick08 +sergserg +frosty +phat +priyanka1 +199428 +meeka1 +bengbeng +13031977 +johncena8 +zermatt +251975 +000911 +balla22 +surface +041989 +go49ers +jenna3 +stephen11 +lamar12 +eric08 +maxmax123 +muggins +buffalo2 +dianaa +221172 +mia1234 +lisa25 +azerty78 +842001 +101970 +jeetkunedo +624624 +justin92 +suspect +7samurai +volley11 +jepoy +safety123 +060480 +2882 +javier7 +jeanny +yourgay! +0423 +natalie23 +110298 +testes +pavlin +04061977 +01021974 +katena +sparticus +pulguita +11111118 +130574 +olumide1 +kolakola +pekanbaru +24021978 +judge +karebear1 +apple111 +220775 +151175 +ratona +alfa33 +12081975 +cocomero +together2 +ich123 +jamesl +jmc123 +viruss +married06 +26071979 +wlafica +cowboy8 +hobie1 +070894 +gabriela7 +tecate1 +yousuck69 +050109 +ryan2000 +abuela1 +nokia3120 +dragster1 +240000 +23081978 +300179 +karim123 +alejandra9 +jake77 +0822 +myband1 +qxvbgfibuq +frank1234 +antonanton +wales +916916 +chess123 +boxter +16041979 +reset12345 +nicolas7 +beth11 +perlas +guesswhat1 +030197 +3630000 +woogie1 +17121978 +sonofabitch +mousetrap +alarcon +dakoda1 +011095 +tester! +sydney! +kissa123 +291175 +brown7 +tanner5 +ronja +station3 +wroclaw +031296 +jairam +bigboi2 +christine1 +070693 +gator12 +197906 +280978 +hendrix2 +666666j +571632 +011983 +pointjor +551155 +darkness11 +potter11 +pheobe1 +cowgirlup1 +ilovemary1 +charles9 +270178 +060795 +borntorun +011078 +dora11 +080309 +loveandpeace +anna19 +lavelle +se +q1w1e1 +25041996 +rockland +21121976 +1babylove +17071979 +cc12345 +witcher +020306 +170000 +r00ster +281274 +ginger1234 +luis24 +status1 +khanna +aubergine +444422 +snickers4 +meteora1 +nikita2 +tink1234 +246789 +12121972 +duncan123 +marinho +sabrina! +0000000000o +gretta1 +152436 +dancing2 +cass123 +fou +bebe18 +rachel09 +oluwa +relientk1 +harley95 +17021996 +fiat +martina123 +sevenseven +chicago08 +skynyrd +112511 +14071997 +chumley +wet +mustang500 +cody07 +hottie05 +1wordpass +1derrick +rocky17 +astonvilla1 +akinsola +cro +freddurst +281296 +159753m +080876 +eagle01 +delphine1 +puppy22 +maimuna +03cobra +luv2fish +chabela +netwerk +malibu2 +douglas1 +18wheeler +30111978 +199619 +victor4 +lauren19 +drpepper7 +teamo100 +lightning +kilo123 +chipmunks +ihatehim +nirvana8 +ferrarif430 +twinkie2 +icross +whorebag1 +246891 +gangster23 +rock99 +rocky007 +021977 +wilfred1 +gaspare +homo12 +131096 +reset1 +brigade +hatelife +160677 +jerry11 +chaochao +srilatha +kevin27 +daniel82 +21222122 +karenina +snake7 +mygirls4 +120599 +091276 +lajolla +horny2 +sable123 +081275 +240976 +kjkszpj1 +creations +myspace121 +primetime2 +gungrave +19841125 +454545a +k3zechmext +dance16 +231995 +220675 +09031980 +lasttime +465465 +pingouin +18101810 +78 +hailey13 +121588 +harvick +varshini +goodrich +mario18 +iluvmymom1 +thegr81 +highspeed +angels07 +hd764nw5d7e1vb1 +toohot4u +frog69 +adgjmptw0 +09111980 +sugarfree +happy06 +useless1 +evelyn2 +nikita2002 +xavier22 +654321abc +manuelito1 +bodega +marsmars +26121996 +hottie88 +kimberly5 +redman123 +1721 +lollipop5 +060179 +snowangel +usmarine +mahmoud1 +rebel3 +pinkrose1 +yamazaki +hottie95 +jared2 +241993 +startup +turntable1 +3.141592654 +sk1234 +jefferson2 +poepie +270797 +suki +110698 +260675 +199425 +080897 +chaitu +070480 +010381 +carlos99 +03041996 +051176 +04121993 +13531353 +collie1 +missthang +budweiser2 +______ +22031977 +011192 +melnikova +punk1234 +andre5 +lorenzo +566566 +fatime +romeo01 +06111980 +spokane1 +gfyfcjybr +0605 +91919191 +bratwurst +noregrets1 +luckys1 +dandandan +fernandotorres +avalon +success8 +kevinn +outreach +lowlife +01061975 +eminem17 +al3xand3r +921921 +busted123 +timber2 +020207 +sehnsucht +jennjenn +imanuel +staycool +26091979 +lollipop00 +021096 +250976 +stars4 +prairie +290976 +ceylan +satsuma +041295 +123qwe,./ +dream13 +199114 +myyolo +16091995 +honey20 +12011977 +derfderf +110472 +23692369 +primrose1 +mohanlal +teenie +2heaven +ilovemary +cordero1 +rhino123 +brittany07 +cvbn123 +dreamweaver +peeps1 +whitney7 +23081977 +ilovebrad1 +mapache +archie +jiushiaini +stern1 +shahbaz +hj: +mike87 +titty1 +guitar8 +200211 +felipe13 +24121977 +kingston12 +aurelia1 +231979 +27021978 +tisha +berta1 +23041995 +sutter +shellie1 +cody08 +produce1 +198804 +klubnichka +0987654321z +shesthe1 +040977 +ghbdtngjrf +meriva +ilovelaura +jessica95 +london88 +280977 +m1i2k3e4 +roxy08 +adrian28 +cityboy1 +070495 +090695 +metal! +snoopy9 +naples1 +050396 +killers2 +101198 +220597 +star2006 +alcatraz1 +kwame1 +coffee4me +boston4 +e7yvsskj +123_abc +killer78 +yvonne123 +m1911a1 +soraya1 +197826 +tampon1 +110673 +fall2011 +pohoda +23121977 +vishakha +redapple1 +1sexy1 +darius123 +zoidberg +settle +samuel08 +retard! +buddy88 +robrob +19821028 +connecting +boss13 +poprocks1 +sibelius +chenjian +patricia3 +nokia6210 +325 +kleber +hubba1 +goodtogo +mylife11 +220497 +195800 +jesusislove +qwqwqwqwqw +elenas +121800 +hotdog6 +grandmom1 +lupe13 +passwordd1 +bradley4 +beaner123 +chubby2 +capitol +memphis901 +teacher12 +entrada +3321 +jake88 +viv +profeta +kimera +leandra1 +lovebunny +31011997 +rock24 +49erss +19860101 +ronan +thelaw +fastball1 +190778 +beauty08 +blessyou +hoppy1 +br123456 +05071978 +21051978 +monsta1 +northshore +xavier14 +laoboi. +window12 +31051996 +panda4 +sukisuki +220673 +pr1nce +an1234 +oakdale +kakka123 +09041979 +skate88 +iheartyou2 +destiny04 +oliwka +06011995 +herbst +110372 +harris +holden123 +410000 +19821209 +smartest1 +190277 +amanda03 +black89 +sk8ter1 +ma12345 +71310615 +231977 +253253 +hiphop01 +30123012 +r0b3rt +pepper1234 +thesecret1 +110973 +karpenko +rainbow15 +05121978 +merve +honeybabe +12122000 +18051979 +elmatador +anwar +ndubuisi +tyrone123 +teddy +mireya1 +watchtower +210996 +26121978 +package +060996 +tester2 +numero10 +martin25 +hottie00 +honey88 +passerotto +vitamina +vonnie1 +spookie1 +flutes +241175 +vesna +johnny55 +anoushka +iluvgod1 +candela1 +sexyt1 +qweasdqweasd +thisis1 +280196 +02051974 +connect123 +7cr2gubvmg +unnamed +qtpie1 +trademark +20071996 +mike29 +carmen5 +spartak +17101975 +1missy +pimpin16 +emmalou1 +14101976 +061981 +10051976 +tendai +abc666 +boavista +matarani +hermann1 +lilman11 +mike4ever +skaterboy2 +pusspuss1 +aaronc +cdflm: +kurenai +stage1 +136913 +11011977 +emerica2 +2qaz2wsx +ginger1 +voting +vbitkm +iloveny1 +280696 +frogs2 +21111978 +isiah1 +23011978 +02081973 +darkness! +11551155 +6thgrade +0323 +maryanne1 +hrenota1 +15041977 +wankers +locksmith +hockey35 +william02 +181176 +zzzaaa +ervin +alma12 +play69 +nbuhbwf +l00000 +vtufgjkbc +ilikeeggs +bratva +012589 +idlewild +a520520 +recipe +chaney +zack13 +16051977 +071194 +ariella +yorktown +kakaska +03091977 +holyholy +010906 +jesus89 +god111 +akindele +21051977 +banana88 +daniel31 +lindsey! +08051994 +19851211 +mermaid2 +jaya +bitch32 +aline1 +07051979 +100203 +alice +lonley1 +hockey00 +food1234 +aramis1 +smoochie1 +robert101 +porker +blessing2 +chevy10 +roflmao123 +theo123 +diego11 +alfred123 +3333331 +kendra123 +bryan22 +ananth +5963 +louis2 +dave22 +ambrosio +02041971 +bytheway +jchrist +15011979 +joebob1 +nicegirl1 +papusa +19851018 +gemini17 +poznan +kamil12 +tiatia +elie3173 +199103 +gordon123 +drummer3 +saddle1 +czekolada1 +bosox1 +missy08 +hotmamma +hawaii06 +70000 +max1994 +bobbin +flavien +p2ssword +lucky44 +b43m6xhife +trytry +selvaggia +iverson3 +deathnote2 +swamisamarth +getsmart +sexyma +22081977 +123456789ok +sangha +semaj +freddie123 +courtney1 +5005 +panthers23 +20061997 +150178 +daisy69 +madrid +americanpie +wayne5 +ded +nur +10121974 +mamasha +daquan +johnny. +dajana +koko11 +riccio +020876 +cagayan +swanny +kaitlyn3 +jake02 +ohio123 +azul12 +usausa1 +fedor +sunshine30 +adam88 +teddy6 +scooby8 +turtle14 +hochzeit +hotrod12 +26021995 +pulsar180 +mariquita +chanel11 +sanika +freeman2 +adelle +shavon1 +guatemala2 +nastasia +flash5 +friendship1 +oliver16 +francisco +details +disney22 +2516 +070180 +april1987 +instant1 +230575 +291979 +bonnie13 +lucycat +02030203 +broncos12 +280596 +bobbob12 +ringer1 +211981 +tinker09 +17071997 +candide +xandra +summer2005 +skopje +ricorico +197333 +pumas13 +matthew95 +allison! +tool123 +mattingly +ribena +4wdaxp642f +bogota1 +nazanin +grad06 +waynerooney +fregna +sidharth +dillon11 +g0ldfish +ilovey +o67l2xzfvn +66667777 +sophie05 +sweeet +jorge23 +560050 +pokemon12345 +corazon +100272 +sanfran49 +45214521 +whitehead +janeth1 +mike03 +starz123 +14131413 +mickey20 +211112 +shane22 +chito1 +777777777777 +chiamaka +federica1 +william77 +jess08 +cochise1 +alianza1 +fucku09 +moumita +chocha1 +myspace67 +pakistan12345 +fuckyou86 +monisia +basketbol +120369 +09121994 +020802 +george25 +jammers +sheepy +javi +1stephen +kiss100 +shameless1 +lineika +suganya +frodon +james143 +roma12 +marie99 +endlesslove +risingsun +12021974 +08061977 +peter10 +shakeit +giacomo1 +442244 +110397 +chibi +jealous +jacoba +regulator +101004 +drowssap12 +1raider +090295 +septembrie +031989 +single5 +020708 +ratata +19841002 +lester123 +131200 +jesse1234 +andrew29 +audrey01 +trecool +lame12 +toto90 +sweet92 +musiclove1 +sdfsdfsd +denver2 +firewire +08081974 +ciaociaociao +mybitch +soda123 +lfybkjdf +dragon97 +mazsola +130675 +19902000ttt +loser99 +vball14 +121172 +123344 +123... +asdfgh1234 +shawty13 +florida6 +pokerstar +leelou +london66 +kennedi1 +lacie1 +150976 +251174 +april +xchange +pooo +killers123 +140179 +kelly16 +kookai +jesus2006 +linkedin2012 +kiran1 +car0line +lorraine +sora12 +123123n +njkmrjz +kickball +fairbanks +vwjetta +giuseppe +lora +hernan1 +aksaray68 +loco23 +blaze3 +bubuka +oriente +825825 +diesel69 +angels9 +10091977 +phoenix69 +beibei +060595 +29111978 +camaro123 +hfvd3425f +3rdeye +veronica10 +boggie1 +aerial +momndad1 +conan123 +020968 +capitan1 +sara14 +jazmin12 +musica10 +tanglewood +20101976 +enter7 +abababab +lowlife1 +callofduty1 +rockon7 +thought1 +jussi69 +kuningan +050779 +cracka1 +savithri +tigerboy +55225522 +nicole34 +julia5 +guilherme1 +ajalaa +god12345 +ottoman +badlands +011193 +041978 +gorams +laura! +mickey02 +bowwow4 +bobbob123 +poiuyt12 +29011996 +penshoppe +haha12345 +harrison2 +zdenka +fuckbuddy +danang +bulldogs +adgjmp +blister +benni +32123212 +dasha2010 +byakugan +rassvet +fuckall1 +lenina +may1998 +30051996 +knockknock +talented1 +golfer123 +rayray14 +d00kie +281982 +020308 +dominic1 +whatever08 +06101979 +vflbyf +121964 +06091979 +29101996 +azsxdcfv1 +africa12 +085213 +abramov +120298 +madonna +102008 +salad1 +facial +03011994 +tigger87 +pepsi21 +kashmoney1 +realist1 +lutheran +1natasha +cardigan +andre22 +salim123 +howdy123 +monkie +vincent11 +noddy1 +cassidy3 +booty3 +v12345678 +fusion12 +longboard1 +781012 +ema123 +chasseur +david45 +pollack1 +elinor +jumpjump +19041977 +0531 +241981 +01091976 +abkbgg +camer0n +its +zapatero +drowssap2 +261196 +110031 +stickers +isaiah +jaylee +mariaisabel +ihave2kids +1435 +jasmine20 +mysons +cherrys +doodah +sydney08 +j1j2j3 +991199 +21041977 +15061996 +charlotte9 +hackthis1 +mnbvc1 +adrian24 +200976 +necro666 +apple09 +hulaanmo +slurpee1 +bball! +1233321 +myplace1 +daffodil1 +04091994 +martin20 +204204 +lalala +catarina1 +030375 +821014 +ihateyou6 +etravelmoleoptin +serega777 +jersey12 +555555s +mikey21 +04051996 +suhana +barbarita +lynda +breonna1 +#1chick +bella1 +130874 +mexico77 +1238 +octagon +030596 +none12 +gavgav +wayne22 +nikos +10101998 +vivalafica +dgkallday +4079 +18021977 +bursaspor +051978 +225500 +01071976 +romeo22 +brian15 +allens +nanito +241196 +140776 +julio2 +lavern +froggy101 +char123 +tanuja +johnny15 +cambria1 +bienvenido +20012007 +player08 +janjanjan +999123 +amor2009 +130476 +batman66 +max1998 +minority +corvette69 +2813308004 +angles1 +hahaha +penis666 +marge +suffolk +queen10 +innamorata +245678 +grindcore +10011976 +april88 +dcwdcw +07121979 +mohamed12 +viewsonic +121223 +karolinka1 +charles. +murdoch +realty +dude55 +201206 +arjun123 +emma03 +160496 +campbell +charlie123 +mamapapa123 +nagaraju +lovepussy1 +2221 +justblaze1 +101055 +120470 +marla1 +06031996 +skincare +auburn12 +brook123 +butter8 +mast3r +sasha16 +290877 +david666 +201196 +darius2 +241295 +greg11 +27041978 +robbie11 +frank10 +nbvjityrj +bushido123 +lastname +internet5 +jmjmjm +animal13 +kmg365 +avantika +cupcake. +iiiiiiiiii +asdfghjk12 +frijolito +naruto33 +willow +propane +martin77 +logan23 +1georgia +alskdjfhg1 +maureen ++ +bryan3 +bryan23 +phoebe12 +killa69 +blahblah123 +waterh20 +kristen3 +120670 +gamble1 +snowflake3 +13091979 +321654987a +blinkblink +andras +j3ss1ca +19121996 +nurses1 +112002 +mariah10 +playful1 +notreal +koala123 +111170 +charlie200 +jakeyboy +forum123 +12091976 +skunk2 +03101996 +25312531 +gringa +seashells +estrella13 +3u7wrkaa8j +12111977 +reddog12 +505 +daylight1 +eman123 +fake08 +anna777 +star2010 +make +meli +sports101 +ilovejc +pumpkin22 +realmadrid7 +0099887766 +aminlove +lintang +iscool +20031975 +boots12 +535535 +bitches01 +madhukar +booboo1234 +fagboy1 +120998 +30011995 +280179 +wolverine7 +baby777 +logan04 +khuljasimsim +mariarita +signup1 +zsazsa1 +frannie1 +stmarys +powerslave +smile07 +hottness +thor123 +zw5a1u5evw +yousuf +whale +01061976 +229229 +19871021 +071195 +demarcus +allen20 +2mndonaaa +748748 +game11 +7777777v +13021977 +fatboy99 +retraite +rolland +facebook11 +accident +prince1234 +15021977 +super100 +mouse11 +quatre +sniper +scruffy123 +001965 +454454 +sassy07 +qazxswe +richa +jadensmith +canabis1 +meow1234 +tigers33 +nastik +pipi1000 +sweetpea! +redsun +lovesu +treats1 +dctulf +mybaby4 +joelmadden +310876 +pr +billy21 +roseann1 +161276 +peachie +kenzie2 +lover89 +tamilan +autobot +050479 +20091978 +sergio01 +trevor13 +filsdepute +270878 +number1dad +001995 +privet1 +birdies +1monday +pazyamor +pup123 +190294 +cool56 +91mustang +hamsters1 +rockstar19 +1860 +karelia +nikito +sirocco +plovdiv +19821020 +alexdelpiero +091298 +mammam +zabuza +hearts5 +jess5377 +antonio16 +pagani +maddie4 +anhthu +grafton +grunt1 +010161 +man111 +soltera +baller17 +campari +483483 +deyanira +ewqdsacxz +hanakimi +sassy09 +291277 +1foryou +ble +ljxehrf +320000 +hawaii99 +lucifer +gavrik +ilovecheese +rosebud12 +villareal +140274 +gizmos1 +llama2 +mommy32 +varun +asiamarketing +leon01 +bertone +chris1989 +redsox05 +wardog +dozer123 +raven69 +ert +guerreiro +jayde1 +misspriss1 +rocky06 +brandon27 +jimmy +marsha11 +farcry2 +gonzaga1 +jos123 +doremi123 +dimon1 +pwisdiwhs +little5 +09051978 +matt19 +081200 +morenike +bluearmy +pulsar1 +tommygirl1 +dumbshit1 +runfast +2225 +21101977 +kisslove +bulldog +30031978 +karlee1 +abigail11 +katter +pusinka +kokanee +mistica +loveme4eva +221200 +people9 +060777 +sivasiva +mercer1 +maslo123 +janajana +04121977 +dianita1 +560058 +wingzero1 +121316 +2539 +28061979 +jenni123 +06121978 +marlboro12 +connor7 +farted +tanika +derf +manofsteel +090881 +marie91 +020274 +100102 +jacob18 +unilever +1jellybean +marius123 +trickster1 +crocus +12021975 +18031977 +sarah. +sidney12 +justin0 +081991 +cubs123 +051991 +tasha01 +peter23 +1johncena +5254 +1327 +vtkmybrjdf +j54321 +masini +5566778899 +shorty77 +270378 +barcelona5 +iloveaj +amanda95 +220574 +monkeypoo +gaurav123 +claudie +brasilien +kingmaker +marina88 +islander1 +duckduck1 +0159753 +185185 +daniel1994 +vitoria1 +appels +denise15 +helmet1 +123wert +potential +iloveyouu1 +zgmfx20a +18191819 +nanda123 +danny20 +ilovebeer1 +coffee7 +patriots +16071978 +124680 +depressed +melanie11 +1froggy +manita +123asdqwe +chicken15 +foobar1 +casey21 +jamal2 +kaylas +luvu4eva +inuyasha6 +aseret +20061977 +311208 +sammyjo1 +02051996 +scoala +223300 +jkz +190295 +antibes +021990 +antifa +katrinka +solana +15071977 +16011978 +catdog13 +flipmode1 +abacabb +401101 +penny5 +littled +archie01 +noodle12 +cinta123 +smokey101 +08031977 +dominic5 +kayla03 +08031996 +kylekyle +123456** +nick88 +kill11 +101207 +23061996 +bashful1 +200276 +topless +bulldog21 +kisskiss12 +please3 +materia +allison4 +enamorada1 +chrisc +hotlove +432 +howareyou123 +schecter1 +ford2001 +0813 +26011979 +oskarek +neopets13 +milan22 +ensemble +eugene12 +tuncay +akucinta +sureshot +sucram +noobie +mylove6 +cl +crippin1 +nokia3650 +motocros +111105 +sancarlos +lalala13 +lovers8 +19851122 +041980 +120900 +motown1 +nick33 +warhawk +wayne21 +15071996 +bitch2008 +wtf +drpepper3 +popop +gumbo1 +watergate +cicciona +janice123 +cashmere1 +buttercup! +110176 +120807 +100276 +sevillafc +charger2 +disco123 +ryan12345 +bonghit +ramsay +primo +chico3 +8383 +bubluk +endeavour +richard08 +1bradley +don12345 +june88 +miriam +schaap +123321e +gd4life +30071994 +black27 +lilmoney1 +myparents +258012 +lxgiwyl +lovers10 +161096 +3dognight +scott10 +laur3n +sexyangel +ilusha +franz1 +guwahati +project8 +blake10 +qwedcxz +dixie3 +15081508 +pimp92 +bol +kaylan +makaroni +johncena01 +wassila +harshini +kool101 +181981 +edgard +nada123 +kathrina +robvandam +rantanplan +nn +valmont +izumrud +hola10 +luke22 +lucy14 +dogfight +eddie69 +110300 +noah2007 +22041976 +blue4ever +11235 +britt5 +gofuckyour +hulkster1 +1725 +affinity +barnaul +nastygirl +maslova +armyof2 +11111976 +25111979 +14301430 +florencio +missy8 +22051977 +azerty59 +kiesha1 +takamine1 +jaffa1 +chaka +seller +1retard +chelsea05 +armando2 +i5stwf1rcx +yamaha135 +joeyboy +05041979 +22041979 +makana +robert00 +060896 +dm1234 +06081977 +140603 +250596 +orthodox +isabella13 +spiegel +mika12 +123456jb +lilly09 +230576 +197505 +chance5 +95279527 +sie +londyn +aa456852 +09021977 +darth +joanne +viking11 +cougar12 +bhabyko +pleasant1 +appleseed1 +180995 +5200 +meiling +johnny77 +lilypad1 +bouvier +hadouken +13041996 +sonyericss +alan13 +warcraft1 +piknik +berkley1 +brother4 +hotbitch +sansiro +060908 +bebe17 +marissa5 +skyliner +chander +designs +1light +fatass69 +28051978 +16111979 +hellokitty +04061978 +reena +annie13 +eric24 +asda123 +cognita +aurora +marvelous1 +fiorello +199527 +bubba! +zoegirl +cindys +czarna +p2xcfgjcvr +meonly1 +5455 +1bighead +090480 +060279 +nastygirl1 +javier15 +170177 +ranger23 +fisher12 +0111 +georgia11 +santas +narusegawa +banana77 +garcia +fluffy +freaky123 +pepsie +bigwill1 +amorino +katherine0 +19871111 +lixiang +260876 +201274 +mario8 +25032503 +turtle9 +йфяцычувс +azbest777 +madonna2 +220011 +vivera +wolverine3 +shabbir +cassie15 +andrey1995 +madura +vorobei +t090571 +95chevy +marylin +braves95 +michael50 +chatter1 +eagles25 +luzmaria +sensei1 +bizzle +collin12 +pepsi10 +gasparin +ultimatum +magdeburg +kopilka +lovers4eve +hottie27 +laura1234 +board +sunflower +rally +5577 +301987 +811029 +10111976 +m2g7u6o397 +anima +pendeja +25002500 +frosty123 +700040 +lolitas +20012005 +jerkface1 +benji2 +1192296 +texas14 +lovesick1 +clemente21 +kismat +7344555 +36987 +1q2w3easd +kopernik +28061977 +21031997 +120372 +jojo18 +savage3 +blondie11 +yannou +haley6 +vfvfxrf +snickers22 +william0 +morenito +tranquil +lovebug101 +happyfamily +heriberto +taco11 +pastorius +chase4 +waynes +hggih +qweewq123 +trans1 +pearl2 +dreday1 +panget +050994 +milkdud1 +faithingod +dude33 +rafael13 +bunnyrabbit +sasuke1234 +lucky02 +kenny10 +181175 +1212qq +charlieb +cookies6 +robert87 +munchy1 +tanner4 +threesome3 +shepard1 +821224 +micheal3 +future123 +22011996 +windows2000 +3830182 +tristan01 +964123 +chrisp +0825 +445566a +witchy +thickness +020181 +polk +sexyback12 +ihateyou9 +nate01 +vivayo +alex1972 +mimi88 +jenny +01071975 +235 +akoako +zztop +courtney22 +01011959 +punk14 +loser17 +applejack1 +18111976 +spencer13 +841015 +meeko +becca2 +rockhopper +skyliner33 +amanda86 +071198 +iloveyou97 +bullshit7 +homie12 +djeter +chick2 +gupta +cowboy88 +22041977 +mxyzptlk +arsch123 +dsadsadsa +11111p +chinaman1 +sparky101 +holly22 +panthers13 +michael84 +arcticcat +mcbride +poopdick +200375 +170876 +richman1 +acuario1 +jayann +30091978 +nguyen4 +cowboys +ttt111 +milan7 +bigbutts +loveday +tinkerbell +utythfk +15011977 +kieran123 +bike4life +3690 +lisa14 +nicolina +duke07 +199308 +internet01 +851210 +usher2 +burnley1 +170376 +akmaral +811023 +charing +nene23 +jesus03 +252526 +parker22 +nirankar +saving +hawaii3 +dhanya +evolution2 +maksimov +a741852 +verdun +uiuiui +000321 +miley16 +shrek123 +motivated +felisa +bulgakov +muthafucka +christina4 +160277 +fireman12 +bigdaddy11 +kristyn +pokemon90 +mossberg +03081979 +panther6 +foshizzle +momma12 +leonardo10 +shay16 +131313q +rfhlbyfk +koller +061196 +merlin7 +boss74 +louisvuitton +james94 +honey05 +fierce1 +240777 +qwert67 +199205 +anisoara +misiek123 +modernwarfare +20022007 +poodie1 +18021979 +shock +0blivion +trtrtr +alex123 +diana23 +capricorn7 +lili1234 +newsletter +business123 +puff +lilcutie1 +071421 +541788 +luna10 +070605 +060906 +angel2003 +cool20 +australia0 +beatbox1 +lover#1 +ricky23 +sexymama11 +shoelace1 +nininini +13081996 +artem1998 +control2 +snickers01 +kyuubi +logical1 +iforgot! +father +chrissy +200676 +rosegarden +heather15 +horseshoe1 +willyou +andi123 +zavala +cegthvty +diva16 +yeager +pantera3 +080874 +adidas777 +19851127 +hondacr +070701 +victor16 +210875 +ab12345678 +amazonia +fuckyou26 +nena23 +123aye +301070 +1lesbian +calhoun1 +851023 +biggdogg +marley09 +bitch +haze420 +kulkarni +7000 +millsberry +3l3m3nt +leyton +paintball8 +bassoon1 +smiley10 +looser123 +sergei ++ +aka +kaila +czarny +kiss01 +angeldog +chicago4 +8657 +22011997 +04111993 +tomtom11 +hairball1 +samsung14 +ocean13 +monique01 +kenyatta1 +goddamn1 +culture1 +flowers8 +020302 +amaya +463395727 +piotrus +april1988 +letmein99 +bandit07 +woaimama +170277 +jkl456 +mickey33 +petey123 +monomono +volcom9 +121170 +19851224 +070979 +denver07 +22051997 +soccer11 +omgomg123 +88chevy +gothika +fifafifa +dupeczka +831018 +cowgirls +bellisima +milonga +pritam +rocky! +070775 +jhon +14061976 +20031977 +sasha98 +north123 +naima +passer1 +buddy12345 +1pebbles +laura17 +300894 +fraud +naruhina +blacky2 +firestone1 +750750 +perumal +100772 +richelle1 +040677 +purple76 +patata1 +pappas +gfhjk123 +leafs1 +casey22 +01091996 +hafida +lily07 +britneys +cupcake69 +14theroad +queen14 +regenboog +102030q +21111977 +james007 +12401240 +julian09 +overflow +bitch2010 +track2 +hihihihi1 +purple90 +arriba +tiddles1 +fhutynbyf +bernie01 +shadow420 +14051996 +khadija1 +shakey1 +imortal +ctht:f +11031997 +julian15 +200206 +bonethug1 +maddog11 +20011975 +bear16 +gundam123 +sarrah +ski123 +bootylicious +19861002 +210775 +aviator1 +marquette1 +miller10 +cyberman +may1980 +0.123456 +froglegs1 +143256 +thomas0 +shane7 +121314z +shravani +040475 +15051976 +bubblegum5 +lawless1 +family#1 +delmar1 +kozlik +thomas30 +giggity1 +sweetie22 +wildcats! +121009 +june1999 +197805 +bellsouth +taylor27 +781021 +20022006 +0908070605 +wilkinson1 +686686 +fatfuck1 +cubs23 +green123 +falcon10 +1bigred +160476 +pointers +vendredi13 +green42 +eagles +snoopy09 +q3538004 +imgay12 +aluminum +pepsi24 +draper +italia +jesus4me +madison. +viernes +80baby +1234rr +pigman +4always +yyyyyy1 +qwewq +money1 +infante +forget12 +bulldog8 +google8 +sabrina22 +nonnie1 +zolushka +spy123 +rjn`yjr +killer12345 +recruiter1 +27041979 +freddy7 +heidi2 +suckit5 +harekrsna +qazwsxedc2 +pa +170679 +jjjjjjjjj +johnny07 +barcelona3 +dragon81 +sword123 +201003 +30121979 +ivancito +afshan +dugong +melodia +tadashi +emanon +onelove13 +loco10 +cappy1 +madalyn +jackie16 +abrikos +isolde +romaine +east12 +blonde! +109 +edmond1 +hottie20 +dexter22 +25121976 +energizer1 +190894 +poppop12 +quake1 +ric123 +culiacan1 +cascada1 +aa3030316 +19851028 +841027 +23071978 +21342134 +space01 +christian12 +16101976 +lilsaint +spider21 +cracker12 +taufik +lucky100 +jumpin +#1diva +tigger28 +detroit3 +barbie1234 +q1q1q1q1q1 +london9 +wipro +moomoo7 +chinchin1 +escondido +joey07 +elettra +15071979 +p0rnstar +21011996 +sealteam6 +banned +161275 +03071996 +tinker +brasil12 +gohard +2215 +zsolti +goldcoast +mrbear +anna89 +197806 +12345sex +0000oooo +justice11 +xfactor1 +trevor10 +fitch1 +1234567890f +1theman +lady08 +1lilwayne +gemini18 +5609867 +trinity8 +milan4ever +mccormick +sassy1234 +29081979 +football46 +bodie1 +120609 +eritrea +power12345 +trindade +king34 +211995 +qwedcxza +aldwin +a7xrocks +cossie +hickey +siegheil88 +king420 +apples +mateusz12 +vova1998 +qwerty31 +fulvio +199622 +24262426 +qwerty06 +123695 +happy2bme +lizard2 +thumper3 +suntan +07041978 +080395 +260296 +yourmom22 +brucewayne +tyler2006 +lexy123 +megan6 +adidas01 +13021997 +stang +sonny12 +198283 +jai123 +rebel10 +101171 +bigtits2 +cookies01 +anadolu +rose19 +monster77 +newyork. +hemi +barbie07 +poppoppop +190178 +philip12 +dc +famous! +q1w2e3 +06011980 +2n76xg2yiu +kenmore +199427 +papermate1 +choosen1 +071077 +freeland +100674 +shaniya1 +haller +komarov +equinox1 +sophie15 +diego01 +raiders6 +jeremy24 +canada13 +will11 +patches11 +080184 +saibot +lilmama7 +123401 +12steps +21091977 +mangusta +noranora +sanguine +*star* +andre01 +playas1 +devilish1 +dexter5 +badger123 +chipster +120572 +sara21 +pirate123 +2ofakind +a88888 +hassen +chico01 +flyer +skidrow1 +150796 +31031979 +001996 +carlino +13171317 +ficker +180575 +popcorn. +giresun28 +succeed +darkangel6 +kappa1911 +1.2.3. +davidbeckham +28071977 +murder666 +mafiawars +maria05 +cutes +madhura +toot +john44 +nounette +w3lc0m3 +the +18101996 +timurka +sixteen1 +21011974 +sugarlips1 +truelove13 +echoecho +55555lvl +kamron +sachiko +dragons5 +25071979 +04041997 +yellow02 +g00gl3 +050309 +agrawal +ewunia +dipali +capcom1 +jayar +9595 +122800 +pitagoras +peddler +orellana +icarly1 +hehehe123 +adeoye +020906 +aa1234567 +12345678qwertyui +061077 +tyler25 +080781 +ahmed12 +granny3 +meanie1 +buthole1 +lalito1 +nfyz123 +sadie! +dima2002 +pantera6 +perseus +lynwood1 +marysia1 +yankee11 +aaaa +14051997 +musick +190377 +02061996 +mom4life +fargo1 +sixela +noshit +270996 +elvis13 +fucker +chatnoir +cupcake24 +dragons13 +s123321 +1ninja +zniqpnk733 +detroit12 +durant35 +steelhead1 +wilhelmina +pies +26041979 +muffin6 +gfhjkmm +lovelove7 +grandmom ++ +rawrrawr +twisted2 +element14 +float +734001 +myspace98 +didou +1187 +juanmiguel +ilovericky +angeleyes2 +boomboom2 +30081981 +september13 +minnie22 +guardians +yfdctulf +minh123 +papaye +22312231 +7770777 +monkfish +shailendra +alex1973 +tyrone3 +kociak +glo +manboy +olga1234 +grinding +millard +black92 +asd159 +google69 +12play +29031979 +03121976 +29111979 +grady +mayita +amanda0 +voodoo13 +31081977 +alexandre +yamaha6 +kodabear +expensive +121345 +silverado2 +cena11 +joseph89 +del123 +19841120 +maloney +may1982 +241074 +piggy5 +5million +priyam +15031975 +snoppy1 +sideways +urbano +dominion1 +apple44 +24081995 +dante12 +johnnyb +redred2 +chappy1 +buster01 +20111977 +150376 +ayomide1 +verdade +joaopaulo +07061978 +202002 +asd777 +cowboy24 +memyselfi +trevor3 +801124 +1lollipop +nudist +shay15 +apple18 +iloveyou4ever +say +dog123456 +jacksonville +diogo123 +imran1 +19861211 +nikita1999 +13051976 +08121979 +top100 +cutie19 +werule1 +shadowman1 +zxcasd1 +gatsby1 +buenos +26061997 +666beast +3698 +bitches13 +290496 +taylor56 +charles6 +solveig +102102102 +glass123 +141076 +music45 +green89 +07101995 +dave23 +239239 +dadang +heyjude1 +trinity05 +jose27 +11223344556677889900 +sunnepa1 +impulse101 +princess56 +anton1995 +kings2 +batgirl1 +master777 +munna +chloe23 +ricky10 +1907fener +lilman07 +851120 +koston +pluisje +520999 +katie06 +jerbear +mybabyboy +emma02 +donavan1 +tamagotchi +14041997 +polki +200776 +20102000 +tatung +kata +fylhttdyf +borabora1 +adidas88 +piesek1 +broucek +nodnarb1 +bobo13 +selena11 +123456qa +opossum +260378 +ceilidh +peniss +1417 +royalflush +carol2 +awesome22 +110898 +19851213 +dumbbitch +chamois +03071977 +cuttiepie1 +valdes +201203 +kaylee08 +froggy22 +c9p5au8naa +tonkpils +amilcar +kayla101 +redrover1 +buddyholly +starsky1 +920920 +simbacat +asdfqwer1 +200796 +mafia13 +punkrock! +1234mm +100199 +210774 +2bigballs +maxime +warranty +cowboy09 +shanika +waffles2 +3663 +maria2010 +galaxia +kangaroo2 +laura +zzr1100 +060895 +28071979 +honey28 +cbcmrf +abc777 +manu11 +751002 +ferien +jamestown +spanky7 +morenaza +kittyy +400098 +linda69 +nomorerack +go4itnow +roses2 +pakistani1 +2q87xi3wgw +destiny02 +ford351 +bassboat +05021979 +intuition +samuel1234 +toybox +197828 +roxy18 +floyd123 +saxena +jesse16 +123698547 +vball2 +freight +kehinde1 +kennwort +belka +dfg +purple97 +falcon3 +babe10 +1truluv +samadhi +dolly12 +2dollars +kakka +951753654 +mz.sexy +corner1 +77779999 +speed12 +vishwa +1mnbvcxz +zxcxz +08091977 +050305 +novice +nisse +moustic +110598 +tyson11 +266266 +babyoneone +trinacria +261296 +encule +harley17 +hunting101 +volcom14 +plumes +15021976 +31031977 +eatadick +1dance +matt20 +1w2e3r4t +blue420 +applebees1 +guyssuck1 +hannah01 +chris1988 +sammy123 +freak11 +199624 +albert3 +klk123 +samosa +26011996 +gougou +sweet77 +wildcat7 +tumelo +amanda93 +fghfghfgh +ardian +htt//members.cumfiesta.com/ +gaffer +samuel02 +nana18 +nx74205 +301275 +elway07 +liljj1 +stevenson1 +147890 +kokito +28051996 +1sunday +flex ++ +poiuyt5 +sniper69 +gracie03 +250574 +wilson21 +asd123zxc +hiphop. +hearts13 +manjit +butta1 +sorellina +drm199019902323 +daisuke1 +actionman +002211 +buddy02 +adalberto +wolves11 +dur +junior77 +nicole1 +latina2 +giggles12 +qwerty30 +280777 +bryant08 +kasablanka +nokian90 +lesnik +cokacola +bowwow7 +hospice +ilovebill +250376 +feb +watts1 +05101995 +110911 +07121994 +2455 +kelly101 +jaleel +wrexham +watchdog +britni +intense1 +725725 +markis +100376 +songs1 +100866 +06071978 +shradha +2040 +terezinha +0714 +desmond123 +28041977 +247001 +821121 +821218 +teamo! +19081995 +tiffany17 +1zyybyt82a +25041997 +1little +ginogino +bulldogs5 +elnegro1 +pfuflrf +pes2009 +jayjay14 +antares1 +123456jc +maggie55 +rayhan +cornhole +insight1 +playmaker +beyond1 +makayla5 +040596 +smokey88 +pimpin0 +success! +shaka +mollie2 +squadup1 +21111979 +alinuta +18061978 +buster18 +painislove +soboleva +fresh22 +saloma +fyzfyz +zxasqw1 +green06 +16111995 +bellavita +onyebuchi +rocky77 +pipe +hellsing +oliver00 +061206 +141175 +lawrence2 +alabama1 +ask +desiderata +250807 +popcorn101 +lovebug5 +300995 +050898 +jonas7 +09091088 +condition +lucky888 +george09 +stop12 +refresh1 +megabyte +roper1 +micheal7 +scorpion13 +151174 +keksik +01021973 +julian06 +standup +o8lhe2z7bo +ycei62p395 +psytrance +taco1234 +king66 +grace06 +sparky23 +starla1 +fifnfy +super88 +27101977 +vwpassat +++ +aol +gizzy +hotgurl +angelle +18111978 +latinoheat +donald356 +andriana +cadeau +07111993 +gjkzrjdf +sh0pping +mother8 +yankee3 +sangam +un4given +tanya12 +220907 +spartan7 +251206 +azertyuio +newgirl +dani22 +alcool +benjamin22 +jackryan +jones +1abcdefgh +300496 +skikda +hermitage +freddy3 +heaven09 +05031996 +skyler123 +nichole7 +badfish +johnson11 +godgrace +matter1 +dessie +brenda7 +lucas5 +bear24 +lofasz +brian18 +keanu1 +badoo2012 +chinacat +kkkkkk6 +mcafee +rafael2 +040778 +shyamala +unleashed1 +951753123 +usasf1234 +081094 +15111995 +aisha123 +slk230 +11vote +angela4 +gfdkjd +addie +flores12 +nevaeh06 +101268 +emma1 +cash23 +270776 +sophie6 +251106 +20121975 +sexyguy1 +lilman08 +noah08 +ilmiocane +lilliana +jk +dustin23 +carolina15 +adeade +joker17 +13281328 +kupukupu +irish3 +qwert! +dodgers3 +puddy1 +fafnir +lazareva +anthony1 +charlie01 +21051976 +1212aa +james93 +estetica +cacahuate +/.,mnb +papa10 +sexygurl2 +japierdole +newyork69 +199203 +oldfart1 +donnas +bribri12 +100273 +ilovesam! +fidelidade +decade +chaparro1 +231097 +luisluis +mini1234 +samantha06 +alain1 +haley13 +dogbreath1 +17021979 +azsxdc12 +07071976 +dragons11 +140976 +leonard +maxine123 +timmy5 +chase22 +joselo +calore +salvador2 +little4 +verizon123 +201070 +5152535455 +britbrat1 +sarath +nick2000 +millhouse +jackie17 +sadie10 +penguin9 +17061978 +kissmebaby +01061996 +101169 +ra1234 +1234kids +12061976 +1estrella +bobik +1sassy +200476 +bandito1 +diller +chesca +tedesco +31081978 +outubro +eight88 +91camaro +eagles99 +pizza21 +199207 +18101978 +homie2 +25061996 +choupinou +170877 +hawk12 +griselda1 +1grandpa +arabella1 +hacker2 +mari11 +hasina +tuning1 +jaimatadi1 +vbvjpf +shokoladka +789741 +robert04 +tiamotanto +psppsp +010475 +aiaiai +milamber +120173 +mugwump +zxcqwe123 +courtney16 +sn0wman +03081978 +080875 +mister12 +jasmina1 +z7777777 +emma2010 +w1950a +wonderboy1 +210196 +brutus2 +punkers +piapia +199404 +811026 +licker1 +123bnm +agung +chicana +miami11 +resist +150907 +dustin7 +19961997 +campinas +mikaella +jamesk +z1z1z1z1 +thrash1 +210675 +142753869 +niklas1 +251273 +vegas2 +021076 +000000b +azazello +ilovezach +14041976 +smoove1 +lampada +bigdog +basket13 +thermo +angie21 +harley15 +ak +16031977 +eastside4 +kiki89 +necronomicon +mommy27 +h36js3ggof +03121995 +07041979 +liar +thelast1 +030794 +suger1 +crazzy1 +199327 +virginia12 +102498 +starfleet +040181 +01021975 +oddjob +310176 +kennedy12 +legend01 +naledi +qazwsxedc12345 +gordo2 +dannyb +rc. +198113 +suicidal1 +rainbow16 +iloveyew +chinky1 +10041974 +pappagallo +qwerty121 +07011994 +19871016 +01011900 +deedee13 +doozer +230475 +yourspace1 +devin23 +tiffany. +150596 +levski1914 +cowboy +waiting1 +dolina +mcgrath +alfred +popcorn1 +niki12 +manchitas +corazoncito +841018 +talitha +hirondelle +18091978 +hutch +chaddy +3syqo15hil +soinlove +kingjames23 +hottie4u +bunky1 +tennis14 +maplewood +nevets1 +rushrush +love444 +smile08 +daniela10 +qwerty97 +creek1 +ferda +father12345 +29061979 +030194 +saturnus +fishing11 +hari123 +95123 +joejonas! +1231235 +smokey16 +emokid123 +fffjjj +alex1234 +13071977 +imback1 +maggie25 +lululu1 +compound +candy55 +consumer +001212 +601601 +dinosaurus +ratten +tarasenko +blue74 +cool98 +754321 +y6p67ftrqj +vfkzdrf +brittni +12031976 +kush +rosa11 +star03 +banana33 +shawn69 +dustin14 +salento12 +killerbee1 +03111976 +sweet33 +samson10 +ctcnhtyrf +230597 +19861106 +woodduck +13081977 +maltese1 +jiujitsu1 +08071994 +l0vel0ve +ilove143 +donna2 +prdel +100472 +willpower +ilovekate +19821023 +sasha1989 +handoi +caprisun1 +sexy40 +naty123 +199407 +27021979 +cherry88 +197802 +130808 +harley97 +alania +march2007 +pirate2 +30071979 +rochdale +january +21071977 +timmy9 +bethany12 +whodat1 +pizarro +anita2 +dedicated +roma1996 +021277 +corsica1 +april1992 +slipknot21 +25061979 +jessica33 +qwaser +fupyuxtb66 +1w2q3r4e +ishika +winwinwin +miyamoto +20051975 +cornelis +london2011 +annoying1 +retamozo +blazer01 +canes +lizzie01 +nagrom +fucklove4 +robert45 +garant +amanda33 +blue62 +rainbow08 +jimjones +lafleur +taylor26 +666666t +youknowit +eric17 +120604 +super99 +animal3 +campeones +stockholm1 +harbor1 +sergio11 +moments +apurva +061990 +exitos +amoreco +coke45 +gaygaygay +08061979 +sapato +050209 +penis22 +zacky1 +lucy101 +bluebird2 +stokrotka1 +truelove08 +gogetta +987654321w +poochie2 +trinity +bomberos +111298 +katelyn12 +molly24 +coco77 +102201 +camomilla +18001800 +14031977 +butthole2 +337733 +purple67 +kfkfkf +7419635 +lf +ayanda +c0raplok +193193 +0424 +123456ms +luthien +lovedad +andy16 +kiki101 +jerry5 +123456ass +docker +svitlana +paramon +mounika +lifehouse1 +mexico2009 +johnny9 +25041978 +donttouch +20021967 +rosy +shelby99 +190876 +22772277 +madhouse1 +shelter1 +sasha2002 +monmouth +15011978 +star7827 +ancora +22101976 +xxx555 +dunno1 +skittles69 +gibson01 +lo +030777 +baghera +savannah07 +19031997 +jaymark +katherine7 +090477 +chanel +06101978 +uuuuuuu +budlight3 +hampshire +gator2 +fuckoff09 +adrian1234 +qwe123321 +pookie08 +inl0ve +iluvhim! +manina +bigwill +020183 +161995 +110498 +rednose +fuckit11 +1337ness +420blaze +lytdybr +198655 +mimimi1 +codyboy1 +1365 +star02 +melissa25 +groceries +2315 +chicco1 +jessie. +248624 +besitos +marco +22061976 +123fake +christen1 +hareram +tooter1 +151976 +pablo10 +280875 +angela08 +michael34 +koenig +jason30 +hastalavista +1christoph +rooster +nonna +kalpesh +timmy11 +ilovemyboo +sambuca1 +lovebug4 +braves25 +700027 +chicago01 +jansport1 +barney! +pannekoek +kidskids +deathtoall +lovely20 +lunar +pass23 +120571 +elaine01 +terra123 +nursing08 +gordon12 +hott123 +261978 +gthdsq +misspriss +yabloko +23061976 +20252025 +glacier1 +vilma +261992 +timmy69 +alsace +ivan10 +mommy143 +92camaro +1wildcat +kaitlyn7 +12011976 +berlin12 +chupala +2341 +deputy1 +198566 +1freeman +29051978 +hangman1 +19821012 +thepower +wheeling +03041977 +197904 +04041975 +deardear +east123 +fritzie +7fperlangel +thegreat12 +hijack +yvonne12 +lacroix +panda21 +bradley11 +theforce1 +16041976 +arsenal22 +oksana1 +denise18 +mike30 +1234jk +over +shelby06 +scrap +viper13 +pass420 +almaz +valerie12 +21071979 +crawfish1 +316 +zazaza1 +130375 +1carter +manmohan +holly23 +147852369q +altamira +greengirl +brontolo +potato12 +baller03 +yuriko +keke09 +vans +hockey97 +dana11 +music666 +pookie +superman78 +091178 +1131 +rolyat +billy07 +19841225 +nokia95 +lauraa +xzibit1 +chevy55 +pavankumar +24121976 +tyler2008 +dima1984 +pitbull23 +bulldogs! +sydney00 +sapfir +41234123 +alexis96 +karen22 +1nurse +nickle +jerrod +lolo00 +caroli +thomas94 +boston04 +telkom +gefccgag +noxious +secret24 +chevere +emmanuel7 +adidas14 +120869 +ilovehim23 +cherrytree +camaro99 +volcom21 +panda6 +indiana +181296 +myspace75 +zanessa1 +asdfqwer1234 +scania1 +october02 +keely1 +blackpanther +27011979 +lonsdale1 +fishy12 +dmwdmw +mariz +sun1shine +folks6 +optiplex1 +maksim1 +jeans +april420 +pierre +redneck11 +honeygirl1 +netscape1 +trudy +060178 +shadow007 +diesel11 +071094 +scotty01 +puppies7 +fergie12 +my3loves +bradley5 +anubhav +nopasswo +password@123 +freefall1 +winston01 +ilovepat +p00per +12345me +shadow777 +ferrary +blue43 +meneses +08081998 +beb +myfriend1 +czesio +ker +sabrina9 +789987789 +10081977 +glorious1 +tigers. +fefe +0000123 +parker08 +contour +1wetpussy +kevin123 +18011979 +finite +kubus +optical1 +dino11 +ber217an +123one +calimero1 +lauren00 +choctaw +tina10 +mickey. +keke10 +richard15 +7700 +ganja123 +180277 +crossroad \ No newline at end of file diff --git a/crates/core/database/assets/revolt_source_list.txt b/crates/core/database/assets/revolt_source_list.txt new file mode 100644 index 000000000..9b715d24a --- /dev/null +++ b/crates/core/database/assets/revolt_source_list.txt @@ -0,0 +1,555 @@ +this is an assorted list of known disposable email providers + +#region nobody will ever have an email @example.com so we can safely block it +---- +example.com + +#region list provided by michenriksen at https://gist.github.com/michenriksen/8710649 +---- +0815.ru +0wnd.net +0wnd.org +10minutemail.co.za +10minutemail.com +123-m.com +1fsdfdsfsdf.tk +1pad.de +20minutemail.com +21cn.com +2fdgdfgdfgdf.tk +2prong.com +30minutemail.com +33mail.com +3trtretgfrfe.tk +4gfdsgfdgfd.tk +4warding.com +5ghgfhfghfgh.tk +6hjgjhgkilkj.tk +6paq.com +7tags.com +9ox.net +a-bc.net +agedmail.com +ama-trade.de +amilegit.com +amiri.net +amiriindustries.com +anonmails.de +anonymbox.com +antichef.com +antichef.net +antireg.ru +antispam.de +antispammail.de +armyspy.com +artman-conception.com +azmeil.tk +baxomale.ht.cx +beefmilk.com +bigstring.com +binkmail.com +bio-muesli.net +bobmail.info +bodhi.lawlita.com +bofthew.com +bootybay.de +boun.cr +bouncr.com +breakthru.com +brefmail.com +bsnow.net +bspamfree.org +bugmenot.com +bund.us +burstmail.info +buymoreplays.com +byom.de +c2.hu +casualdx.com +cek.pm +centermail.com +centermail.net +chammy.info +childsavetrust.org +chogmail.com +choicemail1.com +clixser.com +cmail.net +cmail.org +coldemail.info +cool.fr.nf +courriel.fr.nf +courrieltemporaire.com +crapmail.org +cust.in +cuvox.de +d3p.dk +dacoolest.com +dandikmail.com +dayrep.com +dcemail.com +deadaddress.com +deadspam.com +delikkt.de +despam.it +despammed.com +devnullmail.com +dfgh.net +digitalsanctuary.com +dingbone.com +disposableaddress.com +disposableemailaddresses.com +disposableinbox.com +dispose.it +dispostable.com +dodgeit.com +dodgit.com +donemail.ru +dontreg.com +dontsendmespam.de +drdrb.net +dump-email.info +dumpandjunk.com +dumpyemail.com +e-mail.com +e-mail.org +e4ward.com +easytrashmail.com +einmalmail.de +einrot.com +eintagsmail.de +emailgo.de +emailias.com +emaillime.com +emailsensei.com +emailtemporanea.com +emailtemporanea.net +emailtemporar.ro +emailtemporario.com.br +emailthe.net +emailtmp.com +emailwarden.com +emailx.at.hm +emailxfer.com +emeil.in +emeil.ir +emz.net +ero-tube.org +evopo.com +explodemail.com +eyepaste.com +fakeinbox.com +fakeinformation.com +fansworldwide.de +fantasymail.de +fightallspam.com +filzmail.com +fivemail.de +fleckens.hu +frapmail.com +friendlymail.co.uk +fuckingduh.com +fudgerub.com +fyii.de +garliclife.com +gehensiemirnichtaufdensack.de +get2mail.fr +getairmail.com +getmails.eu +getonemail.com +giantmail.de +girlsundertheinfluence.com +gishpuppy.com +gmial.com +goemailgo.com +gotmail.net +gotmail.org +gotti.otherinbox.com +great-host.in +greensloth.com +grr.la +gsrv.co.uk +guerillamail.biz +guerillamail.com +guerrillamail.biz +guerrillamail.com +guerrillamail.de +guerrillamail.info +guerrillamail.net +guerrillamail.org +guerrillamailblock.com +gustr.com +harakirimail.com +hat-geld.de +hatespam.org +herp.in +hidemail.de +hidzz.com +hmamail.com +hopemail.biz +ieh-mail.de +ikbenspamvrij.nl +imails.info +inbax.tk +inbox.si +inboxalias.com +inboxclean.com +inboxclean.org +instant-mail.de +ip6.li +irish2me.com +iwi.net +jetable.com +jetable.fr.nf +jetable.net +jetable.org +jnxjn.com +jourrapide.com +jsrsolutions.com +kasmail.com +kaspop.com +killmail.com +killmail.net +klassmaster.com +klzlk.com +koszmail.pl +kurzepost.de +lawlita.com +letthemeatspam.com +lhsdv.com +lifebyfood.com +link2mail.net +litedrop.com +lol.ovpn.to +lolfreak.net +lookugly.com +lortemail.dk +lr78.com +lroid.com +lukop.dk +m21.cc +mail-filter.com +mail-temporaire.fr +mail.mezimages.net +mail1a.de +mail21.cc +mail2rss.org +mail333.com +mailbidon.com +mailbiz.biz +mailblocks.com +mailbucket.org +mailcat.biz +mailcatch.com +mailde.de +mailde.info +maildrop.cc +maileimer.de +mailexpire.com +mailfa.tk +mailforspam.com +mailfreeonline.com +mailguard.me +mailin8r.com +mailinater.com +mailinator.com +mailinator.net +mailinator.org +mailinator2.com +mailincubator.com +mailismagic.com +mailme.lv +mailme24.com +mailmetrash.com +mailmoat.com +mailms.com +mailnesia.com +mailnull.com +mailorg.org +mailpick.biz +mailrock.biz +mailscrap.com +mailshell.com +mailsiphon.com +mailtemp.info +mailtome.de +mailtothis.com +mailtrash.net +mailtv.net +mailtv.tv +mailzilla.com +makemetheking.com +manybrain.com +mbx.cc +mega.zik.dj +meinspamschutz.de +meltmail.com +messagebeamer.de +mezimages.net +ministry-of-silly-walks.de +mintemail.com +misterpinball.de +moncourrier.fr.nf +monemail.fr.nf +monmail.fr.nf +monumentmail.com +mt2009.com +mt2014.com +mycleaninbox.net +mymail-in.net +mypacks.net +mypartyclip.de +myphantomemail.com +mysamp.de +mytempemail.com +mytempmail.com +mytrashmail.com +nabuma.com +neomailbox.com +nepwk.com +nervmich.net +nervtmich.net +netmails.com +netmails.net +neverbox.com +nice-4u.com +nincsmail.hu +nnh.com +no-spam.ws +noblepioneer.com +nomail.pw +nomail.xl.cx +nomail2me.com +nomorespamemails.com +nospam.ze.tc +nospam4.us +nospamfor.us +nospammail.net +notmailinator.com +nowhere.org +nowmymail.com +nurfuerspam.de +nus.edu.sg +objectmail.com +obobbo.com +odnorazovoe.ru +oneoffemail.com +onewaymail.com +onlatedotcom.info +online.ms +ordinaryamerican.net +otherinbox.com +ovpn.to +owlpic.com +pancakemail.com +pcusers.otherinbox.com +pjjkp.com +plexolan.de +poczta.onet.pl +politikerclub.de +poofy.org +pookmail.com +privacy.net +privatdemail.net +proxymail.eu +prtnx.com +putthisinyourspamdatabase.com +putthisinyourspamdatabase.com +quickinbox.com +rcpt.at +reallymymail.com +realtyalerts.ca +recode.me +recursor.net +reliable-mail.com +rhyta.com +rmqkr.net +royal.net +rtrtr.com +s0ny.net +safersignup.de +safetymail.info +safetypost.de +saynotospams.com +schafmail.de +schrott-email.de +secretemail.de +secure-mail.biz +senseless-entertainment.com +services391.com +sharklasers.com +shieldemail.com +shiftmail.com +shitmail.me +shitware.nl +shmeriously.com +shortmail.net +sinnlos-mail.de +slapsfromlastnight.com +slaskpost.se +smashmail.de +smellfear.com +snakemail.com +sneakemail.com +sneakmail.de +snkmail.com +sofimail.com +solvemail.info +sogetthis.com +soodonims.com +spam4.me +spamail.de +spamarrest.com +spambob.net +spambog.ru +spambox.us +spamcannon.com +spamcannon.net +spamcon.org +spamcorptastic.com +spamcowboy.com +spamcowboy.net +spamcowboy.org +spamday.com +spamex.com +spamfree.eu +spamfree24.com +spamfree24.de +spamfree24.org +spamgoes.in +spamgourmet.com +spamgourmet.net +spamgourmet.org +spamherelots.com +spamherelots.com +spamhereplease.com +spamhereplease.com +spamhole.com +spamify.com +spaml.de +spammotel.com +spamobox.com +spamslicer.com +spamspot.com +spamthis.co.uk +spamtroll.net +speed.1s.fr +spoofmail.de +stuffmail.de +super-auswahl.de +supergreatmail.com +supermailer.jp +superrito.com +superstachel.de +suremail.info +talkinator.com +teewars.org +teleworm.com +teleworm.us +temp-mail.org +temp-mail.ru +tempe-mail.com +tempemail.co.za +tempemail.com +tempemail.net +tempemail.net +tempinbox.co.uk +tempinbox.com +tempmail.eu +tempmaildemo.com +tempmailer.com +tempmailer.de +tempomail.fr +temporaryemail.net +temporaryforwarding.com +temporaryinbox.com +temporarymailaddress.com +tempthe.net +thankyou2010.com +thc.st +thelimestones.com +thisisnotmyrealemail.com +thismail.net +throwawayemailaddress.com +tilien.com +tittbit.in +tizi.com +tmailinator.com +toomail.biz +topranklist.de +tradermail.info +trash-mail.at +trash-mail.com +trash-mail.de +trash2009.com +trashdevil.com +trashemail.de +trashmail.at +trashmail.com +trashmail.de +trashmail.me +trashmail.net +trashmail.org +trashymail.com +trialmail.de +trillianpro.com +twinmail.de +tyldd.com +uggsrock.com +umail.net +uroid.com +us.af +venompen.com +veryrealemail.com +viditag.com +viralplays.com +vpn.st +vsimcard.com +vubby.com +wasteland.rfc822.org +webemail.me +weg-werf-email.de +wegwerf-emails.de +wegwerfadresse.de +wegwerfemail.com +wegwerfemail.de +wegwerfmail.de +wegwerfmail.info +wegwerfmail.net +wegwerfmail.org +wh4f.org +whyspam.me +willhackforfood.biz +willselfdestruct.com +winemaven.info +wronghead.com +www.e4ward.com +www.mailinator.com +wwwnew.eu +x.ip6.li +xagloo.com +xemaps.com +xents.com +xmaily.com +xoxy.net +yep.it +yogamaven.com +yopmail.com +yopmail.fr +yopmail.net +yourdomain.com +yuurok.com +z1p.biz +za.com +zehnminuten.de +zehnminutenmail.de +zippymail.info +zoemail.net +zomg.info + +#region public emails provided by mail.tm +---- +trythe.net +leadwizzer.com +metalunits.com +scpulse.com diff --git a/crates/core/database/src/drivers/mod.rs b/crates/core/database/src/drivers/mod.rs index df9a56efd..8b3591023 100644 --- a/crates/core/database/src/drivers/mod.rs +++ b/crates/core/database/src/drivers/mod.rs @@ -2,16 +2,7 @@ mod mongodb; mod reference; -use authifier::config::Captcha; -use authifier::config::EmailVerificationConfig; -use authifier::config::PasswordScanning; -use authifier::config::ResolveIp; -use authifier::config::SMTPSettings; -use authifier::config::Shield; -use authifier::config::Template; -use authifier::config::Templates; -use authifier::config::EmailExpiryConfig; -use authifier::Authifier; + use rand::Rng; use revolt_config::config; @@ -112,143 +103,3 @@ impl DatabaseInfo { } } } - -impl Database { - /// Create an Authifier reference - pub async fn to_authifier(self) -> Authifier { - let config = config().await; - - let mut auth_config = authifier::Config { - password_scanning: if config.api.security.easypwned.is_empty() { - Default::default() - } else { - PasswordScanning::EasyPwned { - endpoint: config.api.security.easypwned, - } - }, - email_verification: if !config.api.smtp.host.is_empty() { - EmailVerificationConfig::Enabled { - smtp: SMTPSettings { - from: config.api.smtp.from_address, - host: config.api.smtp.host, - username: config.api.smtp.username, - password: config.api.smtp.password, - reply_to: Some( - config - .api - .smtp - .reply_to - .unwrap_or("support@stoat.chat".into()), - ), - port: config.api.smtp.port, - use_tls: config.api.smtp.use_tls, - use_starttls: config.api.smtp.use_starttls, - }, - expiry: EmailExpiryConfig { - expire_verification: 3600 * 24 * 7, - expire_password_reset: 3600 * 24, - expire_account_deletion: 3600 * 24, - }, - templates: if config.production { - Templates { - verify: Template { - title: "Verify your Stoat account.".into(), - text: include_str!("../../templates/verify.txt").into(), - url: format!("{}/login/verify/", config.hosts.app), - html: Some(include_str!("../../templates/verify.html").into()), - }, - reset: Template { - title: "Reset your Stoat password.".into(), - text: include_str!("../../templates/reset.txt").into(), - url: format!("{}/login/reset/", config.hosts.app), - html: Some(include_str!("../../templates/reset.html").into()), - }, - reset_existing: Template { - title: "You already have a Stoat account, reset your password." - .into(), - text: include_str!("../../templates/reset-existing.txt").into(), - url: format!("{}/login/reset/", config.hosts.app), - html: Some( - include_str!("../../templates/reset-existing.html").into(), - ), - }, - deletion: Template { - title: "Confirm account deletion.".into(), - text: include_str!("../../templates/deletion.txt").into(), - url: format!("{}/delete/", config.hosts.app), - html: Some(include_str!("../../templates/deletion.html").into()), - }, - welcome: None, - } - } else { - Templates { - verify: Template { - title: "Verify your account.".into(), - text: include_str!("../../templates/verify.whitelabel.txt").into(), - url: format!("{}/login/verify/", config.hosts.app), - html: None, - }, - reset: Template { - title: "Reset your password.".into(), - text: include_str!("../../templates/reset.whitelabel.txt").into(), - url: format!("{}/login/reset/", config.hosts.app), - html: None, - }, - reset_existing: Template { - title: "Reset your password.".into(), - text: include_str!("../../templates/reset.whitelabel.txt").into(), - url: format!("{}/login/reset/", config.hosts.app), - html: None, - }, - deletion: Template { - title: "Confirm account deletion.".into(), - text: include_str!("../../templates/deletion.whitelabel.txt") - .into(), - url: format!("{}/delete/", config.hosts.app), - html: None, - }, - welcome: None, - } - }, - } - } else { - EmailVerificationConfig::Disabled - }, - ..Default::default() - }; - - auth_config.invite_only = config.api.registration.invite_only; - - if !config.api.security.captcha.hcaptcha_key.is_empty() { - auth_config.captcha = Captcha::HCaptcha { - secret: config.api.security.captcha.hcaptcha_key, - }; - } - - if !config.api.security.authifier_shield_key.is_empty() { - auth_config.shield = Shield::Enabled { - api_key: config.api.security.authifier_shield_key, - strict: false, - }; - } - - if config.api.security.trust_cloudflare { - auth_config.resolve_ip = ResolveIp::Cloudflare; - } - - Authifier { - database: match self { - Database::Reference(_) => Default::default(), - #[cfg(feature = "mongodb")] - Database::MongoDb(MongoDb(client, _)) => authifier::Database::MongoDb( - authifier::database::MongoDb(client.database("revolt")), - ), - }, - config: auth_config, - #[cfg(feature = "tasks")] - event_channel: Some(crate::tasks::authifier_relay::sender()), - #[cfg(not(feature = "tasks"))] - event_channel: None, - } - } -} diff --git a/crates/core/database/src/drivers/reference.rs b/crates/core/database/src/drivers/reference.rs index e02eae644..66c9e9b6f 100644 --- a/crates/core/database/src/drivers/reference.rs +++ b/crates/core/database/src/drivers/reference.rs @@ -5,7 +5,7 @@ use futures::lock::Mutex; use crate::{ Bot, Channel, ChannelCompositeKey, ChannelUnread, Emoji, File, FileHash, Invite, Member, MemberCompositeKey, Message, PolicyChange, RatelimitEvent, Report, Server, ServerBan, Snapshot, - User, UserSettings, Webhook, + User, UserSettings, Webhook, Account, AccountInvite, Session, MFATicket }; database_derived!( @@ -30,5 +30,9 @@ database_derived!( pub servers: Arc>>, pub safety_reports: Arc>>, pub safety_snapshots: Arc>>, + pub accounts: Arc>>, + pub account_invites: Arc>>, + pub sessions: Arc>>, + pub tickets: Arc>>, } ); diff --git a/crates/core/database/src/events/client.rs b/crates/core/database/src/events/client.rs index 31864cee3..a55e7171a 100644 --- a/crates/core/database/src/events/client.rs +++ b/crates/core/database/src/events/client.rs @@ -1,4 +1,3 @@ -use authifier::AuthifierEvent; use revolt_result::Error; use serde::{Deserialize, Serialize}; @@ -11,7 +10,7 @@ use revolt_models::v0::{ UserVoiceState, Webhook, }; -use crate::Database; +use crate::{Account, Database, Session}; /// Ping Packet #[derive(Serialize, Deserialize, Debug, Clone)] @@ -329,7 +328,20 @@ pub enum EventV1 { }, /// Auth events - Auth(AuthifierEvent), + CreateAccount { + account: Account, + }, + CreateSession { + session: Session, + }, + DeleteSession { + user_id: String, + session_id: String, + }, + DeleteAllSessions { + user_id: String, + exclude_session_id: Option, + }, /// Voice events VoiceChannelJoin { diff --git a/crates/core/database/src/models/account_invites/mod.rs b/crates/core/database/src/models/account_invites/mod.rs new file mode 100644 index 000000000..4d801b73e --- /dev/null +++ b/crates/core/database/src/models/account_invites/mod.rs @@ -0,0 +1,5 @@ +mod model; +mod ops; + +pub use model::*; +pub use ops::*; diff --git a/crates/core/database/src/models/account_invites/model.rs b/crates/core/database/src/models/account_invites/model.rs new file mode 100644 index 000000000..88ec7f14d --- /dev/null +++ b/crates/core/database/src/models/account_invites/model.rs @@ -0,0 +1,25 @@ +use crate::{if_false, Database}; +use revolt_result::Result; + +auto_derived_partial!( + /// Account invite ticket + pub struct AccountInvite { + /// Invite code + #[serde(rename = "_id")] + pub id: String, + /// Whether this invite ticket has been used + #[serde(skip_serializing_if = "if_false", default)] + pub used: bool, + /// User ID that this invite was claimed by + #[serde(skip_serializing_if = "Option::is_none")] + pub claimed_by: Option, + }, + "PartialAccountInvite" +); + +impl AccountInvite { + /// Save model + pub async fn save(&self, db: &Database) -> Result<()> { + db.save_account_invite(self).await + } +} diff --git a/crates/core/database/src/models/account_invites/ops.rs b/crates/core/database/src/models/account_invites/ops.rs new file mode 100644 index 000000000..c17c995a5 --- /dev/null +++ b/crates/core/database/src/models/account_invites/ops.rs @@ -0,0 +1,16 @@ +use revolt_result::Result; + +use crate::AccountInvite; + +#[cfg(feature = "mongodb")] +mod mongodb; +mod reference; + +#[async_trait] +pub trait AbstractAccountInvites: Sync + Send { + /// Find invite by id + async fn fetch_account_invite(&self, id: &str) -> Result; + + /// Save invite + async fn save_account_invite(&self, invite: &AccountInvite) -> Result<()>; +} diff --git a/crates/core/database/src/models/account_invites/ops/mongodb.rs b/crates/core/database/src/models/account_invites/ops/mongodb.rs new file mode 100644 index 000000000..f9c71e684 --- /dev/null +++ b/crates/core/database/src/models/account_invites/ops/mongodb.rs @@ -0,0 +1,31 @@ +use crate::{AbstractAccountInvites, AccountInvite, MongoDb}; +use bson::to_document; +use mongodb::options::UpdateOptions; +use revolt_result::Result; + +const COL: &str = "account_invites"; + +#[async_trait] +impl AbstractAccountInvites for MongoDb { + /// Find invite by id + async fn fetch_account_invite(&self, id: &str) -> Result { + query!(self, find_one_by_id, COL, id)?.ok_or_else(|| create_error!(InvalidInvite)) + } + + /// Save invite + async fn save_account_invite(&self, invite: &AccountInvite) -> Result<()> { + self.col::(COL) + .update_one( + doc! { + "_id": &invite.id + }, + doc! { + "$set": to_document(invite).map_err(|_| create_database_error!("to_document", COL))?, + }, + ) + .with_options(UpdateOptions::builder().upsert(true).build()) + .await + .map_err(|_| create_database_error!("upsert_one", COL)) + .map(|_| ()) + } +} diff --git a/crates/core/database/src/models/account_invites/ops/reference.rs b/crates/core/database/src/models/account_invites/ops/reference.rs new file mode 100644 index 000000000..9003400dc --- /dev/null +++ b/crates/core/database/src/models/account_invites/ops/reference.rs @@ -0,0 +1,21 @@ +use crate::{AbstractAccountInvites, AccountInvite, ReferenceDb}; +use revolt_result::Result; + +#[async_trait] +impl AbstractAccountInvites for ReferenceDb { + /// Find invite by id + async fn fetch_account_invite(&self, id: &str) -> Result { + let invites = self.account_invites.lock().await; + invites + .get(id) + .cloned() + .ok_or_else(|| create_error!(InvalidInvite)) + } + + /// Save invite + async fn save_account_invite(&self, invite: &AccountInvite) -> Result<()> { + let mut invites = self.account_invites.lock().await; + invites.insert(invite.id.to_string(), invite.clone()); + Ok(()) + } +} diff --git a/crates/core/database/src/models/accounts/axum.rs b/crates/core/database/src/models/accounts/axum.rs new file mode 100644 index 000000000..5ac9dc617 --- /dev/null +++ b/crates/core/database/src/models/accounts/axum.rs @@ -0,0 +1,22 @@ +use axum::{extract::{FromRef, FromRequestParts}, http::request::Parts}; + +use revolt_result::{Error, Result}; + +use crate::{Account, Database, Session}; + +#[async_trait] +impl FromRequestParts for Account +where + Database: FromRef, + S: Send + Sync +{ + type Rejection = Error; + + async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { + let db = Database::from_ref(state); + + let session = Session::from_request_parts(parts, state).await?; + + db.fetch_account(&session.user_id).await + } +} diff --git a/crates/core/database/src/models/accounts/mod.rs b/crates/core/database/src/models/accounts/mod.rs new file mode 100644 index 000000000..4e58da725 --- /dev/null +++ b/crates/core/database/src/models/accounts/mod.rs @@ -0,0 +1,11 @@ +#[cfg(feature = "axum-impl")] +mod axum; +mod model; +mod ops; +#[cfg(feature = "rocket-impl")] +mod rocket; +#[cfg(feature = "rocket-impl")] +mod schema; + +pub use model::*; +pub use ops::*; diff --git a/crates/core/database/src/models/accounts/model.rs b/crates/core/database/src/models/accounts/model.rs new file mode 100644 index 000000000..5608ecfce --- /dev/null +++ b/crates/core/database/src/models/accounts/model.rs @@ -0,0 +1,656 @@ +use iso8601_timestamp::{Duration, Timestamp}; + +use nanoid::nanoid; +use revolt_config::config; +use revolt_result::Result; +use serde_json::json; + +use crate::{ + events::client::EventV1, + util::{ + email::{email_templates, normalise_email, send_email}, + password::hash_password, + }, + Database, MFATicket, Session, +}; +use revolt_models::v0; + +auto_derived_partial!( + /// Account model + pub struct Account { + /// Unique Id + #[serde(rename = "_id")] + pub id: String, + + /// User's email + pub email: String, + + /// Normalised email + /// + /// (see https://github.com/insertish/authifier/#how-does-authifier-work) + pub email_normalised: String, + + /// Argon2 hashed password + pub password: String, + + /// Whether the account is disabled + #[serde(default)] + pub disabled: bool, + + /// Email verification status + pub verification: EmailVerification, + + /// Password reset information + pub password_reset: Option, + + /// Account deletion information + pub deletion: Option, + + /// Account lockout + pub lockout: Option, + + /// Multi-factor authentication information + pub mfa: MultiFactorAuthentication, + }, + "PartialAccount" +); + +auto_derived!( + /// Email verification status + #[serde(tag = "status")] + pub enum EmailVerification { + /// Account is verified + Verified, + /// Pending email verification + Pending { token: String, expiry: Timestamp }, + /// Moving to a new email + Moving { + new_email: String, + token: String, + expiry: Timestamp, + }, + } + + /// Password reset information + pub struct PasswordReset { + /// Token required to change password + pub token: String, + /// Time at which this token expires + pub expiry: Timestamp, + } + + /// Account deletion information + #[serde(tag = "status")] + pub enum DeletionInfo { + /// The user must confirm deletion by email + WaitingForVerification { token: String, expiry: Timestamp }, + /// The account is scheduled for deletion + Scheduled { after: Timestamp }, + /// This account was deleted + Deleted, + } + + /// Lockout information + pub struct Lockout { + /// Attempt counter + pub attempts: i32, + /// Time at which this lockout expires + pub expiry: Option, + } + + /// MFA configuration + #[derive(Default)] + pub struct MultiFactorAuthentication { + /// Allow password-less email OTP login + /// (1-Factor) + // #[serde(skip_serializing_if = "is_false", default)] + // pub enable_email_otp: bool, + + /// Allow trusted handover + /// (1-Factor) + // #[serde(skip_serializing_if = "is_false", default)] + // pub enable_trusted_handover: bool, + + /// Allow email MFA + /// (2-Factor) + // #[serde(skip_serializing_if = "is_false", default)] + // pub enable_email_mfa: bool, + + /// TOTP MFA token, enabled if present + /// (2-Factor) + #[serde(skip_serializing_if = "Totp::is_empty", default)] + pub totp_token: Totp, + + /// Security Key MFA token, enabled if present + /// (2-Factor) + // #[serde(skip_serializing_if = "Option::is_none")] + // pub security_key_token: Option, + + /// Recovery codes + #[serde(skip_serializing_if = "Vec::is_empty", default)] + pub recovery_codes: Vec, + } + + /// MFA method + #[derive(Hash)] + pub enum MFAMethod { + Password, + Recovery, + Totp, + } + + #[derive(Default)] + #[serde(tag = "status")] + pub enum Totp { + /// Disabled + #[default] + Disabled, + /// Waiting for user activation + Pending { secret: String }, + /// Required on account + Enabled { secret: String }, + } +); + +impl MultiFactorAuthentication { + // Check whether MFA is in-use + pub fn is_active(&self) -> bool { + matches!(self.totp_token, Totp::Enabled { .. }) + } + + // Check whether there are still usable recovery codes + pub fn has_recovery(&self) -> bool { + !self.recovery_codes.is_empty() + } + + // Get available MFA methods + pub fn get_methods(&self) -> Vec { + if let Totp::Enabled { .. } = self.totp_token { + let mut methods = vec![MFAMethod::Totp]; + + if self.has_recovery() { + methods.push(MFAMethod::Recovery); + } + + methods + } else { + vec![MFAMethod::Password] + } + } + + // Generate new recovery codes + pub fn generate_recovery_codes(&mut self) { + static ALPHABET: [char; 32] = [ + '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z', + ]; + + let mut codes = vec![]; + for _ in 1..=10 { + codes.push(format!( + "{}-{}", + nanoid!(5, &ALPHABET), + nanoid!(5, &ALPHABET) + )); + } + + self.recovery_codes = codes; + } + + // Generate new TOTP secret + pub fn generate_new_totp_secret(&mut self) -> Result { + if let Totp::Enabled { .. } = self.totp_token { + return Err(create_error!(OperationFailed)); + } + + let secret: [u8; 10] = rand::random(); + let secret = base32::encode(base32::Alphabet::RFC4648 { padding: false }, &secret); + + self.totp_token = Totp::Pending { + secret: secret.clone(), + }; + + Ok(secret) + } + + /// Enable TOTP using a given MFA response + pub fn enable_totp(&mut self, response: v0::MFAResponse) -> Result<()> { + if let v0::MFAResponse::Totp { totp_code } = response { + let code = self.totp_token.generate_code()?; + + if code == totp_code { + let mut totp = Totp::Disabled; + std::mem::swap(&mut totp, &mut self.totp_token); + + if let Totp::Pending { secret } = totp { + self.totp_token = Totp::Enabled { secret }; + + Ok(()) + } else { + Err(create_error!(OperationFailed)) + } + } else { + Err(create_error!(InvalidToken)) + } + } else { + Err(create_error!(InvalidToken)) + } + } +} + +impl Totp { + /// Whether TOTP information is empty + pub fn is_empty(&self) -> bool { + matches!(self, Totp::Disabled) + } + + /// Whether TOTP is disabled + pub fn is_disabled(&self) -> bool { + !matches!(self, Totp::Enabled { .. }) + } + + // Generate a TOTP code from secret + pub fn generate_code(&self) -> Result { + if let Totp::Enabled { secret } | Totp::Pending { secret } = &self { + let seconds: u64 = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_secs(); + + Ok(totp_lite::totp_custom::( + totp_lite::DEFAULT_STEP, + 6, + &base32::decode(base32::Alphabet::RFC4648 { padding: false }, secret) + .expect("valid base32 secret"), + seconds, + )) + } else { + Err(create_error!(OperationFailed)) + } + } +} + +impl Account { + /// Save model + pub async fn save(&self, db: &Database) -> Result<()> { + db.save_account(self).await + } + + /// Create a new account + pub async fn new( + db: &Database, + email: String, + plaintext_password: String, + verify_email: bool, + ) -> Result { + // Get a normalised representation of the user's email + let email_normalised = normalise_email(email.clone()); + + // Try to find an existing account + if let Some(mut account) = db + .fetch_account_by_normalised_email(&email_normalised) + .await? + { + // Resend account verification or send password reset + if let EmailVerification::Pending { .. } = &account.verification { + account.start_email_verification(db).await?; + } else { + account.start_password_reset(db, true).await?; + } + + Ok(account) + } else { + // Hash the user's password + let password = hash_password(plaintext_password)?; + + // Create a new account + let mut account = Account { + id: ulid::Ulid::new().to_string(), + + email, + email_normalised, + password, + + disabled: false, + verification: EmailVerification::Verified, + password_reset: None, + deletion: None, + lockout: None, + + mfa: Default::default(), + }; + + // Send email verification + if verify_email { + account.start_email_verification(db).await?; + } else { + account.save(db).await?; + } + + // Create and push event + EventV1::CreateAccount { + account: account.clone(), + } + .global() + .await; + + Ok(account) + } + } + + /// Create a new session + pub async fn create_session(&self, db: &Database, name: String) -> Result { + let config = config().await; + + let session = Session { + id: ulid::Ulid::new().to_string(), + token: nanoid!(64), + + user_id: self.id.clone(), + name, + + last_seen: Timestamp::now_utc(), + + origin: Some(config.environment), + subscription: None, + }; + + // Save to database + db.save_session(&session).await?; + + // Create and push event + EventV1::CreateSession { + session: session.clone(), + } + .global() + .await; + + Ok(session) + } + + /// Send account verification email + pub async fn start_email_verification(&mut self, db: &Database) -> Result<()> { + let config = config().await; + + if !config.api.smtp.host.is_empty() { + let templates = email_templates().await; + + let token = nanoid!(32); + let url = format!("{}{}", templates.verify.url, token); + + send_email( + &config.api.smtp, + self.email.clone(), + &templates.verify, + json!({ + "email": self.email.clone(), + "url": url + }), + )?; + + self.verification = EmailVerification::Pending { + token, + expiry: Timestamp::now_utc() + .checked_add(Duration::seconds( + config.api.smtp.expiry.expire_verification, + )) + .unwrap(), + }; + } else { + self.verification = EmailVerification::Verified; + } + + self.save(db).await + } + + /// Send account verification to new email + pub async fn start_email_move(&mut self, db: &Database, new_email: String) -> Result<()> { + // This method should and will never be called on an unverified account, + // but just validate this just in case. + if let EmailVerification::Pending { .. } = self.verification { + return Err(create_error!(UnverifiedAccount)); + } + + let config = config().await; + + if !config.api.smtp.host.is_empty() { + let templates = email_templates().await; + + let token = nanoid!(32); + let url = format!("{}{}", templates.verify.url, token); + + send_email( + &config.api.smtp, + new_email.clone(), + &templates.verify, + json!({ + "email": self.email.clone(), + "url": url + }), + )?; + + self.verification = EmailVerification::Moving { + new_email, + token, + expiry: Timestamp::now_utc() + .checked_add(Duration::seconds( + config.api.smtp.expiry.expire_verification, + )) + .unwrap(), + }; + } else { + self.email_normalised = normalise_email(new_email.clone()); + self.email = new_email; + } + + self.save(db).await + } + + /// Send password reset email + pub async fn start_password_reset( + &mut self, + db: &Database, + existing_account: bool, + ) -> Result<()> { + let config = config().await; + + if !config.api.smtp.host.is_empty() { + let templates = email_templates().await; + + let template = if existing_account { + &templates.reset_existing + } else { + &templates.reset + }; + + let token = nanoid!(32); + let url = format!("{}{}", template.url, token); + + send_email( + &config.api.smtp, + self.email.clone(), + template, + json!({ + "email": self.email.clone(), + "url": url + }), + )?; + + self.password_reset = Some(PasswordReset { + token, + expiry: Timestamp::now_utc() + .checked_add(Duration::seconds( + config.api.smtp.expiry.expire_password_reset, + )) + .unwrap(), + }); + } else { + return Err(create_error!(OperationFailed)); + } + + self.save(db).await + } + + /// Begin account deletion process by sending confirmation email + /// + /// If email verification is not on, the account will be marked for deletion instantly + pub async fn start_account_deletion(&mut self, db: &Database) -> Result<()> { + let config = config().await; + + if !config.api.smtp.host.is_empty() { + let templates = email_templates().await; + + let token = nanoid!(32); + let url = format!("{}{}", templates.deletion.url, token); + + send_email( + &config.api.smtp, + self.email.clone(), + &templates.deletion, + json!({ + "email": self.email.clone(), + "url": url + }), + )?; + + self.deletion = Some(DeletionInfo::WaitingForVerification { + token, + expiry: Timestamp::now_utc() + .checked_add(Duration::seconds( + config.api.smtp.expiry.expire_password_reset, + )) + .unwrap(), + }); + + self.save(db).await + } else { + self.schedule_deletion(db).await + } + } + + /// Verify a user's password is correct + pub fn verify_password(&self, plaintext_password: &str) -> Result<()> { + argon2::verify_encoded(&self.password, plaintext_password.as_bytes()) + .map(|v| { + if v { + Ok(()) + } else { + Err(create_error!(InvalidCredentials)) + } + }) + // To prevent user enumeration, we should ignore + // the error and pretend the password is wrong. + .map_err(|_| create_error!(InvalidCredentials))? + } + + /// Validate an MFA response + pub async fn consume_mfa_response( + &mut self, + db: &Database, + response: v0::MFAResponse, + ticket: Option, + ) -> Result<()> { + let allowed_methods = self.mfa.get_methods(); + + match response { + v0::MFAResponse::Password { password } => { + if allowed_methods.contains(&MFAMethod::Password) { + self.verify_password(&password) + } else { + Err(create_error!(DisallowedMFAMethod)) + } + } + v0::MFAResponse::Totp { totp_code } => { + if allowed_methods.contains(&MFAMethod::Totp) { + if let Totp::Enabled { .. } = &self.mfa.totp_token { + // Use TOTP code at generation if applicable + if let Some(ticket) = ticket { + if let Some(code) = ticket.last_totp_code { + if code == totp_code { + return Ok(()); + } + } + } + + // Otherwise read current TOTP token + if self.mfa.totp_token.generate_code()? == totp_code { + Ok(()) + } else { + Err(create_error!(InvalidToken)) + } + } else { + unreachable!() + } + } else { + Err(create_error!(DisallowedMFAMethod)) + } + } + v0::MFAResponse::Recovery { recovery_code } => { + if allowed_methods.contains(&MFAMethod::Recovery) { + if let Some(index) = self + .mfa + .recovery_codes + .iter() + .position(|x| x == &recovery_code) + { + self.mfa.recovery_codes.remove(index); + self.save(db).await + } else { + Err(create_error!(InvalidToken)) + } + } else { + Err(create_error!(DisallowedMFAMethod)) + } + } + } + } + + /// Delete all sessions for an account + pub async fn delete_all_sessions( + &self, + db: &Database, + exclude_session_id: Option, + ) -> Result<()> { + db.delete_all_sessions(&self.id, exclude_session_id.clone()) + .await?; + + // Create and push event + EventV1::DeleteAllSessions { + user_id: self.id.clone(), + exclude_session_id, + } + .private(self.id.clone()) + .await; + + Ok(()) + } + + /// Disable an account + pub async fn disable(&mut self, db: &Database) -> Result<()> { + self.disabled = true; + self.delete_all_sessions(db, None).await?; + self.save(db).await + } + + /// Schedule an account for deletion + pub async fn schedule_deletion(&mut self, db: &Database) -> Result<()> { + self.deletion = Some(DeletionInfo::Scheduled { + after: Timestamp::now_utc() + .checked_add(Duration::weeks(1)) + .unwrap(), + }); + + self.disable(db).await + } + + /// Removes all information from the account and marks it as fully deleted + pub async fn mark_deleted(&mut self, db: &Database) -> Result<()> { + self.email = format!("Deleted User {}", &self.id); + self.email_normalised = format!("Deleted User {}", &self.id); + self.deletion = Some(DeletionInfo::Deleted); + + self.save(db).await?; + + Ok(()) + } +} diff --git a/crates/core/database/src/models/accounts/ops.rs b/crates/core/database/src/models/accounts/ops.rs new file mode 100644 index 000000000..912593912 --- /dev/null +++ b/crates/core/database/src/models/accounts/ops.rs @@ -0,0 +1,34 @@ +use revolt_result::Result; + +use crate::Account; + +#[cfg(feature = "mongodb")] +mod mongodb; +mod reference; + +#[async_trait] +pub trait AbstractAccounts: Sync + Send { + /// Find account by id + async fn fetch_account(&self, id: &str) -> Result; + + /// Find account by normalised email + async fn fetch_account_by_normalised_email( + &self, + normalised_email: &str, + ) -> Result>; + + /// Find account with active pending email verification + async fn fetch_account_with_email_verification(&self, token: &str) -> Result; + + /// Find account with active password reset + async fn fetch_account_with_password_reset(&self, token: &str) -> Result; + + /// Find account with active deletion token + async fn fetch_account_with_deletion_token(&self, token: &str) -> Result; + + /// Find accounts which are due to be deleted + async fn fetch_accounts_due_for_deletion(&self) -> Result>; + + // Save account + async fn save_account(&self, account: &Account) -> Result<()>; +} diff --git a/crates/core/database/src/models/accounts/ops/mongodb.rs b/crates/core/database/src/models/accounts/ops/mongodb.rs new file mode 100644 index 000000000..3c5ce3db2 --- /dev/null +++ b/crates/core/database/src/models/accounts/ops/mongodb.rs @@ -0,0 +1,118 @@ +use crate::{AbstractAccounts, Account, MongoDb}; +use bson::{to_bson, to_document}; +use iso8601_timestamp::Timestamp; +use mongodb::options::{Collation, CollationStrength, FindOneOptions, UpdateOptions}; +use revolt_result::Result; + +const COL: &str = "accounts"; + +#[async_trait] +impl AbstractAccounts for MongoDb { + /// Find account by id + async fn fetch_account(&self, id: &str) -> Result { + query!(self, find_one_by_id, COL, id)?.ok_or_else(|| create_error!(UnknownUser)) + } + + /// Find account by normalised email + async fn fetch_account_by_normalised_email( + &self, + normalised_email: &str, + ) -> Result> { + query!( + self, + find_one_with_options, + COL, + doc! { + "email_normalised": normalised_email + }, + FindOneOptions::builder() + .collation( + Collation::builder() + .locale("en") + .strength(CollationStrength::Secondary) + .build(), + ) + .build() + ) + } + + /// Find account with active pending email verification + async fn fetch_account_with_email_verification(&self, token: &str) -> Result { + query!( + self, + find_one, + COL, + doc! { + "verification.token": token, + "verification.expiry": { + "$gte": to_bson(&Timestamp::now_utc()).unwrap() + } + } + )? + .ok_or_else(|| create_error!(InvalidToken)) + } + + /// Find account with active password reset + async fn fetch_account_with_password_reset(&self, token: &str) -> Result { + query!( + self, + find_one, + COL, + doc! { + "password_reset.token": token, + "password_reset.expiry": { + "$gte": to_bson(&Timestamp::now_utc()).unwrap() + } + } + )? + .ok_or_else(|| create_error!(InvalidToken)) + } + + /// Find account with active deletion token + async fn fetch_account_with_deletion_token(&self, token: &str) -> Result { + query!( + self, + find_one, + COL, + doc! { + "deletion.token": token, + "deletion.expiry": { + "$gte": to_bson(&Timestamp::now_utc()).unwrap() + } + } + )? + .ok_or_else(|| create_error!(InvalidToken)) + } + + /// Find accounts which are due to be deleted + async fn fetch_accounts_due_for_deletion(&self) -> Result> { + query!( + self, + find, + COL, + doc! { + "deletion.status": "Scheduled", + "deletion.after": { + "$lte": to_bson(&Timestamp::now_utc()).unwrap() + } + } + ) + } + + // Save account + async fn save_account(&self, account: &Account) -> Result<()> { + self.col::(COL) + .update_one( + doc! { + "_id": &account.id + }, + doc! { + "$set": to_document(account).map_err(|_| create_database_error!("to_document", COL))? + }, + ) + .with_options(UpdateOptions::builder().upsert(true).build()) + .await + .map_err(|_| create_database_error!("find_one", COL)) + .map(|_| ()) + } +} diff --git a/crates/core/database/src/models/accounts/ops/reference.rs b/crates/core/database/src/models/accounts/ops/reference.rs new file mode 100644 index 000000000..d30a374c8 --- /dev/null +++ b/crates/core/database/src/models/accounts/ops/reference.rs @@ -0,0 +1,99 @@ +use crate::{AbstractAccounts, Account, DeletionInfo, EmailVerification, ReferenceDb}; +use iso8601_timestamp::Timestamp; +use revolt_result::Result; + +#[async_trait] +impl AbstractAccounts for ReferenceDb { + /// Find account by id + async fn fetch_account(&self, id: &str) -> Result { + let accounts = self.accounts.lock().await; + accounts + .get(id) + .cloned() + .ok_or_else(|| create_error!(UnknownUser)) + } + + /// Find account by normalised email + async fn fetch_account_by_normalised_email( + &self, + normalised_email: &str, + ) -> Result> { + let accounts = self.accounts.lock().await; + Ok(accounts + .values() + .find(|account| account.email_normalised == normalised_email) + .cloned()) + } + + /// Find account with active pending email verification + async fn fetch_account_with_email_verification(&self, token_to_match: &str) -> Result { + let accounts = self.accounts.lock().await; + accounts + .values() + .find(|account| match &account.verification { + EmailVerification::Pending { token, .. } + | EmailVerification::Moving { token, .. } => token == token_to_match, + _ => false, + }) + .cloned() + .ok_or_else(|| create_error!(InvalidToken)) + } + + /// Find account with active password reset + async fn fetch_account_with_password_reset(&self, token: &str) -> Result { + let accounts = self.accounts.lock().await; + accounts + .values() + .find(|account| { + if let Some(reset) = &account.password_reset { + reset.token == token + } else { + false + } + }) + .cloned() + .ok_or_else(|| create_error!(InvalidToken)) + } + + /// Find account with active deletion token + async fn fetch_account_with_deletion_token(&self, token_to_match: &str) -> Result { + let accounts = self.accounts.lock().await; + accounts + .values() + .find(|account| { + if let Some(DeletionInfo::WaitingForVerification { token, .. }) = &account.deletion + { + token == token_to_match + } else { + false + } + }) + .cloned() + .ok_or_else(|| create_error!(InvalidToken)) + } + + /// Find accounts which are due to be deleted + async fn fetch_accounts_due_for_deletion(&self) -> Result> { + let now = Timestamp::now_utc(); + let accounts = self.accounts.lock().await; + + Ok(accounts + .values() + .filter(|account| { + if let Some(DeletionInfo::Scheduled { after }) = &account.deletion { + after <= &now + } else { + false + } + }) + .cloned() + .collect()) + } + + // Save account + async fn save_account(&self, account: &Account) -> Result<()> { + let mut accounts = self.accounts.lock().await; + accounts.insert(account.id.to_string(), account.clone()); + Ok(()) + } +} diff --git a/crates/core/database/src/models/accounts/rocket.rs b/crates/core/database/src/models/accounts/rocket.rs new file mode 100644 index 000000000..a78ddde7e --- /dev/null +++ b/crates/core/database/src/models/accounts/rocket.rs @@ -0,0 +1,32 @@ +use crate::{Account, Database, Session}; +use revolt_result::Error; +use rocket::{ + http::Status, + request::{FromRequest, Outcome}, + Request, +}; + +#[rocket::async_trait] +impl<'r> FromRequest<'r> for Account { + type Error = Error; + + async fn from_request(request: &'r Request<'_>) -> Outcome { + match request.guard::().await { + Outcome::Success(session) => { + if let Ok(account) = request + .rocket() + .state::() + .expect("`Database`") + .fetch_account(&session.user_id) + .await + { + Outcome::Success(account) + } else { + Outcome::Error((Status::InternalServerError, create_error!(InternalError))) + } + } + Outcome::Forward(_) => unreachable!(), + Outcome::Error(err) => Outcome::Error(err), + } + } +} diff --git a/crates/core/database/src/models/accounts/schema.rs b/crates/core/database/src/models/accounts/schema.rs new file mode 100644 index 000000000..a1d863ebd --- /dev/null +++ b/crates/core/database/src/models/accounts/schema.rs @@ -0,0 +1,32 @@ +use revolt_okapi::openapi3::{SecurityScheme, SecuritySchemeData}; +use revolt_rocket_okapi::{ + gen::OpenApiGenerator, + request::{OpenApiFromRequest, RequestHeaderInput}, +}; + +use crate::Account; + + +impl<'r> OpenApiFromRequest<'r> for Account { + fn from_request_input( + _gen: &mut OpenApiGenerator, + _name: String, + _required: bool, + ) -> revolt_rocket_okapi::Result { + let mut requirements = schemars::Map::new(); + requirements.insert("Session Token".to_owned(), vec![]); + + Ok(RequestHeaderInput::Security( + "Session Token".to_owned(), + SecurityScheme { + data: SecuritySchemeData::ApiKey { + name: "x-session-token".to_owned(), + location: "header".to_owned(), + }, + description: Some("Used to authenticate as a user.".to_owned()), + extensions: schemars::Map::new(), + }, + requirements, + )) + } +} \ No newline at end of file diff --git a/crates/core/database/src/models/admin_migrations/ops/mongodb/init.rs b/crates/core/database/src/models/admin_migrations/ops/mongodb/init.rs index 4a422cbba..c3bfc5a8f 100644 --- a/crates/core/database/src/models/admin_migrations/ops/mongodb/init.rs +++ b/crates/core/database/src/models/admin_migrations/ops/mongodb/init.rs @@ -98,6 +98,18 @@ pub async fn create_database(db: &MongoDb) { .await .expect("Failed to create pubsub collection."); + db.create_collection("sessions") + .await + .expect("Failed to create sessions collection."); + + db.create_collection("account_invites") + .await + .expect("Failed to create account_invites collection."); + + db.create_collection("mfa_tickets") + .await + .expect("Failed to create mfa_tickets collection."); + db.run_command(doc! { "createIndexes": "users", "indexes": [ @@ -263,5 +275,89 @@ pub async fn create_database(db: &MongoDb) { .await .expect("Failed to create ratelimit_events index."); + db.run_command(doc! { + "createIndexes": "accounts", + "indexes": [ + { + "key": { + "email": 1 + }, + "name": "email", + "unique": true, + "collation": { + "locale": "en", + "strength": 2 + } + }, + { + "key": { + "email_normalised": 1 + }, + "name": "email_normalised", + "unique": true, + "collation": { + "locale": "en", + "strength": 2 + } + }, + { + "key": { + "verification.token": 1 + }, + "name": "email_verification" + }, + { + "key": { + "password_reset.token": 1 + }, + "name": "password_reset" + }, + { + "key": { + "deletion.token": 1 + }, + "name": "account_deletion" + } + ] + }) + .await + .unwrap(); + + db.run_command(doc! { + "createIndexes": "sessions", + "indexes": [ + { + "key": { + "token": 1 + }, + "name": "token", + "unique": true + }, + { + "key": { + "user_id": 1 + }, + "name": "user_id" + } + ] + }) + .await + .unwrap(); + + db.run_command(doc! { + "createIndexes": "mfa_tickets", + "indexes": [ + { + "key": { + "token": 1 + }, + "name": "token", + "unique": true + } + ] + }) + .await + .unwrap(); + info!("Created database."); } diff --git a/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs b/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs index 174a81a62..01d6b3e76 100644 --- a/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs +++ b/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs @@ -17,6 +17,7 @@ use iso8601_timestamp::Timestamp; use rand::seq::SliceRandom; use revolt_permissions::{ChannelPermission, DEFAULT_WEBHOOK_PERMISSIONS}; use serde::{Deserialize, Serialize}; +use ulid::Ulid; use unicode_segmentation::UnicodeSegmentation; #[derive(Serialize, Deserialize)] @@ -25,7 +26,7 @@ struct MigrationInfo { revision: i32, } -pub const LATEST_REVISION: i32 = 50; // MUST BE +1 to last migration +pub const LATEST_REVISION: i32 = 51; // MUST BE +1 to last migration pub async fn migrate_database(db: &MongoDb) { let migrations = db.col::("migrations"); @@ -573,20 +574,145 @@ pub async fn run_migrations(db: &MongoDb, revision: i32) -> i32 { if revision <= 15 { info!("Running migration [revision 15 / 04-06-2022]: Migrate Authifier to latest version."); - let db = authifier::Database::MongoDb(authifier::database::MongoDb(db.db())); - db.run_migration(authifier::Migration::M2022_06_03EnsureUpToSpec) + if !db + .db() + .collection::("mfa_tickets") + .list_index_names() .await - .unwrap(); + .unwrap_or_default() + .contains(&"token".to_owned()) + { + // Make sure all collections exist + let list = db.db().list_collection_names().await.unwrap(); + let collections = ["accounts", "sessions", "invites", "mfa_tickets"]; + + for name in collections { + if !list.contains(&name.to_string()) { + db.db().create_collection(name).await.unwrap(); + } + } + + // Setup index for `accounts` + let col = db.db().collection::("accounts"); + col.drop_indexes().await.unwrap(); + + db.db() + .run_command(doc! { + "createIndexes": "accounts", + "indexes": [ + { + "key": { + "email": 1 + }, + "name": "email", + "unique": true, + "collation": { + "locale": "en", + "strength": 2 + } + }, + { + "key": { + "email_normalised": 1 + }, + "name": "email_normalised", + "unique": true, + "collation": { + "locale": "en", + "strength": 2 + } + }, + { + "key": { + "verification.token": 1 + }, + "name": "email_verification" + }, + { + "key": { + "password_reset.token": 1 + }, + "name": "password_reset" + } + ] + }) + .await + .unwrap(); + + // Setup index for `sessions` + let col = db.db().collection::("sessions"); + col.drop_indexes().await.unwrap(); + + db.db() + .run_command(doc! { + "createIndexes": "sessions", + "indexes": [ + { + "key": { + "token": 1 + }, + "name": "token", + "unique": true + }, + { + "key": { + "user_id": 1 + }, + "name": "user_id" + } + ] + }) + .await + .unwrap(); + + // Setup index for `mfa_tickets` + let col = db.db().collection::("mfa_tickets"); + col.drop_indexes().await.unwrap(); + + db.db() + .run_command(doc! { + "createIndexes": "mfa_tickets", + "indexes": [ + { + "key": { + "token": 1 + }, + "name": "token", + "unique": true + } + ] + }) + .await + .unwrap(); + } } if revision <= 16 { info!("Running migration [revision 16 / 07-07-2022]: Add `emojis` collection and Authifier migration."); - let authifier_db = authifier::Database::MongoDb(authifier::database::MongoDb(db.db())); - authifier_db - .run_migration(authifier::Migration::M2022_06_09AddIndexForDeletion) + if !db + .db() + .collection::("accounts") + .list_index_names() .await - .unwrap(); + .expect("list of index names") + .contains(&"account_deletion".to_owned()) + { + db.db() + .run_command(doc! { + "createIndexes": "accounts", + "indexes": [ + { + "key": { + "deletion.token": 1 + }, + "name": "account_deletion" + } + ] + }) + .await + .unwrap(); + } db.db() .create_collection("emojis") @@ -1085,7 +1211,7 @@ pub async fn run_migrations(db: &MongoDb, revision: i32) -> i32 { enum Channel { Group { owner: String }, TextChannel { server: String }, - VoiceChannel { server: String } + VoiceChannel { server: String }, } let webhooks = db @@ -1099,7 +1225,12 @@ pub async fn run_migrations(db: &MongoDb, revision: i32) -> i32 { .await; for webhook in webhooks { - match db.col::("channels").find_one(doc! { "_id": &webhook.channel_id }).await.unwrap() { + match db + .col::("channels") + .find_one(doc! { "_id": &webhook.channel_id }) + .await + .unwrap() + { Some(channel) => { let creator_id = match channel { Channel::Group { owner, .. } => owner, @@ -1141,10 +1272,51 @@ pub async fn run_migrations(db: &MongoDb, revision: i32) -> i32 { "Running migration [revision 32 / 12-05-2025]: (Authifier) Add last_seen to sessions." ); - let db = authifier::Database::MongoDb(authifier::database::MongoDb(db.db())); - db.run_migration(authifier::Migration::M2025_02_20AddLastSeenToSession) - .await - .unwrap(); + loop { + #[derive(Deserialize)] + struct SessionId { + _id: String, + } + + let sessions: Vec = db + .db() + .collection("sessions") + .find(doc! { + "$or": [ + { "last_seen": { "$exists": false } }, + { "last_seen": "1970-01-01T00:00:00.000Z" } + ] + }) + .limit(50_000) // about 400 batches for 2 million + .await + .expect("Failed to create cursor for sessions!") + .map(|doc| doc.expect("id and username")) + .collect() + .await; + + if sessions.is_empty() { + break; + } + + for session in sessions { + let timestamp = iso8601_timestamp::Timestamp::from(Ulid::from_string(&session._id).unwrap().datetime()); + + db.db() + .collection::("sessions") + .update_one( + doc! { + "_id": &session._id.to_string(), + }, + doc! { + "$set": { + "last_seen": timestamp.format().to_string() + } + }, + ) + .await + .expect("Failed to update a session."); + } + } } if revision <= 40 { @@ -1240,7 +1412,7 @@ pub async fn run_migrations(db: &MongoDb, revision: i32) -> i32 { "channel_type": "TextChannel", "voice": {} } - } + }, ) .await .expect("Failed to update voice channels"); @@ -1292,10 +1464,7 @@ pub async fn run_migrations(db: &MongoDb, revision: i32) -> i32 { let mut doc = doc! {}; for id in server.roles.keys() { - doc.insert( - format!("roles.{id}._id"), - id, - ); + doc.insert(format!("roles.{id}._id"), id); } db.db() @@ -1306,6 +1475,21 @@ pub async fn run_migrations(db: &MongoDb, revision: i32) -> i32 { } }; + if revision <= 50 { + info!("Running migration [revision 50 / 13-04-2026]: Rename invites collection to account_invites"); + + db.db() + .client() + .database("admin") + .run_command(doc! { + "renameCollection": "revolt.invites", + "to": "revolt.account_invites", + "dropTarget": true + }) + .await + .unwrap(); + } + // Reminder to update LATEST_REVISION when adding new migrations. LATEST_REVISION.max(revision) } diff --git a/crates/core/database/src/models/channels/model.rs b/crates/core/database/src/models/channels/model.rs index 74b56e110..b11b3f5d7 100644 --- a/crates/core/database/src/models/channels/model.rs +++ b/crates/core/database/src/models/channels/model.rs @@ -408,7 +408,10 @@ impl Channel { /// Check whether has a user as a recipient pub fn contains_user(&self, user_id: &str) -> bool { match self { - Channel::Group { recipients, .. } => recipients.contains(&String::from(user_id)), + Channel::Group { recipients, .. } | Channel::DirectMessage { recipients, .. } => { + recipients.iter().any(|recipient| recipient == user_id) + } + Channel::SavedMessages { user, .. } => user == user_id, _ => false, } } @@ -416,7 +419,9 @@ impl Channel { /// Get list of recipients pub fn users(&self) -> Result> { match self { - Channel::Group { recipients, .. } => Ok(recipients.to_owned()), + Channel::Group { recipients, .. } | Channel::DirectMessage { recipients, .. } => { + Ok(recipients.to_owned()) + } _ => Err(create_error!(NotFound)), } } diff --git a/crates/core/database/src/models/channels/ops.rs b/crates/core/database/src/models/channels/ops.rs index 3ee90d543..ddd29b869 100644 --- a/crates/core/database/src/models/channels/ops.rs +++ b/crates/core/database/src/models/channels/ops.rs @@ -1,4 +1,4 @@ -use crate::{revolt_result::Result, Channel, FieldsChannel, PartialChannel}; +use crate::{Channel, FieldsChannel, PartialChannel, revolt_result::Result, util::ChunkedDatabaseGenerator}; use revolt_permissions::OverrideField; #[cfg(feature = "mongodb")] @@ -19,6 +19,9 @@ pub trait AbstractChannels: Sync + Send { /// Fetch all direct messages for a user async fn find_direct_messages(&self, user_id: &str) -> Result>; + // Fetch all group dms for a user + async fn find_group_message_channels(&self, user_id: &str) -> Result>; + // Fetch saved messages channel async fn find_saved_messages_channel(&self, user_id: &str) -> Result; @@ -47,6 +50,9 @@ pub trait AbstractChannels: Sync + Send { // Remove a user from a group async fn remove_user_from_group(&self, channel_id: &str, user_id: &str) -> Result<()>; + // Remove a user from all specified groups + async fn remove_user_from_groups(&self, channel_ids: Vec, user_id: &str) -> Result<()>; + // Delete a channel async fn delete_channel(&self, channel_id: &Channel) -> Result<()>; } diff --git a/crates/core/database/src/models/channels/ops/mongodb.rs b/crates/core/database/src/models/channels/ops/mongodb.rs index 79612f8d7..8986e58aa 100644 --- a/crates/core/database/src/models/channels/ops/mongodb.rs +++ b/crates/core/database/src/models/channels/ops/mongodb.rs @@ -1,7 +1,8 @@ use super::AbstractChannels; -use crate::{AbstractServers, Channel, FieldsChannel, IntoDocumentPath, MongoDb, PartialChannel}; +use crate::{AbstractServers, Channel, FieldsChannel, IntoDocumentPath, MongoDb, PartialChannel, util::ChunkedDatabaseGenerator}; use bson::{Bson, Document}; use futures::StreamExt; +use mongodb::options::ReadConcern; use revolt_permissions::OverrideField; use revolt_result::Result; @@ -69,6 +70,32 @@ impl AbstractChannels for MongoDb { ) } + // Fetch all group dms for a user + async fn find_group_message_channels(&self, user_id: &str) -> Result> { + let mut session = self + .start_session() + .await + .map_err(|_| create_database_error!("start_session", COL))?; + + session + .start_transaction() + .read_concern(ReadConcern::snapshot()) + .await + .map_err(|_| create_database_error!("start_transaction", COL))?; + + let cursor = self.col(COL) + .find(doc! { + "channel_type": "Group", + "recipients": user_id + }) + .session(&mut session) + .batch_size(100) + .await + .map_err(|_| create_database_error!("find", COL))?; + + Ok(ChunkedDatabaseGenerator::new_mongo(session, cursor)) + } + // Fetch saved messages channel async fn find_saved_messages_channel(&self, user_id: &str) -> Result { query!( @@ -180,13 +207,29 @@ impl AbstractChannels for MongoDb { .map_err(|_| create_database_error!("update_one", "channels")) } + // Remove a user from all specified groups + async fn remove_user_from_groups(&self, channel_ids: Vec, user_id: &str) -> Result<()> { + self.col::(COL) + .update_many( + doc! { + "_id": { "$in": channel_ids }, + }, + doc! { + "$pull": { + "recipients": user_id + } + }, + ) + .await + .map(|_| ()) + .map_err(|_| create_database_error!("update_many", COL)) + } + // Delete a channel async fn delete_channel(&self, channel: &Channel) -> Result<()> { let id = channel.id().to_string(); let server_id = match channel { - Channel::TextChannel { server, .. } => { - Some(server) - } + Channel::TextChannel { server, .. } => Some(server), _ => None, }; diff --git a/crates/core/database/src/models/channels/ops/reference.rs b/crates/core/database/src/models/channels/ops/reference.rs index 518808bcc..3bbd858a0 100644 --- a/crates/core/database/src/models/channels/ops/reference.rs +++ b/crates/core/database/src/models/channels/ops/reference.rs @@ -2,6 +2,7 @@ use std::collections::hash_map::Entry; use super::AbstractChannels; use crate::ReferenceDb; +use crate::util::ChunkedDatabaseGenerator; use crate::{Channel, FieldsChannel, PartialChannel}; use revolt_permissions::OverrideField; use revolt_result::Result; @@ -51,6 +52,23 @@ impl AbstractChannels for ReferenceDb { .collect()) } + // Fetch all group dms for a user + async fn find_group_message_channels(&self, user_id: &str) -> Result> { + let channels = self.channels.lock().await; + let groups = channels + .values() + .filter(|channel| match channel { + Channel::Group { recipients, .. } => { + recipients.iter().any(|recipient| recipient == user_id) + } + _ => false, + }) + .cloned() + .collect(); + + Ok(ChunkedDatabaseGenerator::new_reference(groups)) + } + // Fetch saved messages channel async fn find_saved_messages_channel(&self, user_id: &str) -> Result { let channels = self.channels.lock().await; @@ -131,9 +149,9 @@ impl AbstractChannels for ReferenceDb { // Remove a user from a group async fn remove_user_from_group(&self, channel: &str, user: &str) -> Result<()> { let mut channels = self.channels.lock().await; - if let Some(channel_data) = channels.get_mut(channel) { - if channel_data.users()?.contains(&String::from(user)) { - channel_data.users()?.retain(|x| x != user); + if let Some(Channel::Group { recipients, .. }) = channels.get_mut(channel) { + if let Some(index) = recipients.iter().position(|recipient| recipient == user) { + recipients.remove(index); return Ok(()); } else { return Err(create_error!(NotFound)); @@ -142,6 +160,19 @@ impl AbstractChannels for ReferenceDb { Err(create_error!(NotFound)) } + // Remove a user from all specified groups + async fn remove_user_from_groups(&self, channel_ids: Vec, user_id: &str) -> Result<()> { + let mut channels = self.channels.lock().await; + + for channel_id in channel_ids { + if let Some(Channel::Group { recipients, .. }) = channels.get_mut(&channel_id) { + recipients.retain(|recipient| recipient != user_id); + } + }; + + Ok(()) + } + // Delete a channel async fn delete_channel(&self, channel: &Channel) -> Result<()> { let mut channels = self.channels.lock().await; diff --git a/crates/core/database/src/models/messages/ops.rs b/crates/core/database/src/models/messages/ops.rs index 6ebdf4c3b..8bb538886 100644 --- a/crates/core/database/src/models/messages/ops.rs +++ b/crates/core/database/src/models/messages/ops.rs @@ -50,4 +50,6 @@ pub trait AbstractMessages: Sync + Send { author: &str, since: SystemTime ) -> Result>>; + + async fn delete_messages_by_user(&self, user_id: &str) -> Result<()>; } diff --git a/crates/core/database/src/models/messages/ops/mongodb.rs b/crates/core/database/src/models/messages/ops/mongodb.rs index 2a79ed5b4..03a2d84a4 100644 --- a/crates/core/database/src/models/messages/ops/mongodb.rs +++ b/crates/core/database/src/models/messages/ops/mongodb.rs @@ -416,6 +416,12 @@ impl AbstractMessages for MongoDb { Ok(deleted_messages) } + + async fn delete_messages_by_user(&self, user_id: &str) -> Result<()> { + self.delete_bulk_messages(doc! { + "author": user_id, + }).await + } } impl IntoDocumentPath for FieldsMessage { diff --git a/crates/core/database/src/models/messages/ops/reference.rs b/crates/core/database/src/models/messages/ops/reference.rs index 56bf1da9c..e1eab8434 100644 --- a/crates/core/database/src/models/messages/ops/reference.rs +++ b/crates/core/database/src/models/messages/ops/reference.rs @@ -1,10 +1,13 @@ -use std::collections::HashMap; +use crate::{ + AppendMessage, FieldsMessage, Message, MessageQuery, + PartialMessage, ReferenceDb, +}; use futures::future::try_join_all; use indexmap::IndexSet; use revolt_result::Result; +use std::collections::HashMap; use std::time::SystemTime; use ulid::Ulid; -use crate::{AppendMessage, FieldsMessage, Message, MessageQuery, PartialMessage, ReferenceDb}; use super::AbstractMessages; @@ -60,7 +63,7 @@ impl AbstractMessages for ReferenceDb { if let Some(pinned) = query.filter.pinned { if message.pinned.unwrap_or_default() == pinned { - return false + return false; } } @@ -191,7 +194,12 @@ impl AbstractMessages for ReferenceDb { } /// Update a given message with new information - async fn update_message(&self, id: &str, message: &PartialMessage, remove: Vec) -> Result<()> { + async fn update_message( + &self, + id: &str, + message: &PartialMessage, + remove: Vec, + ) -> Result<()> { let mut messages = self.messages.lock().await; if let Some(message_data) = messages.get_mut(id) { message_data.apply_options(message.to_owned()); @@ -294,7 +302,7 @@ impl AbstractMessages for ReferenceDb { &self, channels: &[String], author: &str, - since: SystemTime + since: SystemTime, ) -> Result>> { let threshold_ulid = Ulid::from_datetime(since).to_string(); let mut deleted_messages: HashMap> = HashMap::new(); @@ -335,16 +343,23 @@ impl AbstractMessages for ReferenceDb { } // Delete the messages - self.messages - .lock() - .await - .retain(|id, message| { - let should_keep = !(message.author == author - && channels.contains(&message.channel) - && id.as_str() >= threshold_ulid.as_str()); - should_keep - }); + self.messages.lock().await.retain(|id, message| { + let should_keep = !(message.author == author + && channels.contains(&message.channel) + && id.as_str() >= threshold_ulid.as_str()); + should_keep + }); Ok(deleted_messages) } + + async fn delete_messages_by_user(&self, user_id: &str) -> Result<()> { + let mut messages = self.messages.lock().await; + + messages.retain(|_, message| message.author != user_id); + + // TODO: remove attachments as well + + Ok(()) + } } diff --git a/crates/core/database/src/models/mfa_tickets/axum.rs b/crates/core/database/src/models/mfa_tickets/axum.rs new file mode 100644 index 000000000..4eaf3be0e --- /dev/null +++ b/crates/core/database/src/models/mfa_tickets/axum.rs @@ -0,0 +1,67 @@ +use axum::{ + extract::{FromRef, FromRequestParts}, + http::request::Parts, +}; + +use revolt_result::{Error, Result}; + +use crate::{Database, MFATicket, UnvalidatedTicket, ValidatedTicket}; + +#[async_trait] +impl FromRequestParts for MFATicket +where + Database: FromRef, + S: Send + Sync, +{ + type Rejection = Error; + + async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { + let db = Database::from_ref(state); + + if let Some(Ok(token)) = parts.headers.get("x-mfa-ticket").map(|v| v.to_str()) { + db.fetch_ticket_by_token(token).await + } else { + Err(create_error!(MissingHeaders)) + } + } +} + +#[async_trait] +impl FromRequestParts for ValidatedTicket +where + Database: FromRef, + S: Send + Sync, +{ + type Rejection = Error; + + async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { + let db = Database::from_ref(state); + + let ticket = MFATicket::from_request_parts(parts, state).await?; + + if ticket.validated && ticket.claim(&db).await.is_ok() { + Ok(ValidatedTicket(ticket)) + } else { + Err(create_error!(InvalidToken)) + } + } +} + +#[async_trait] +impl FromRequestParts for UnvalidatedTicket +where + Database: FromRef, + S: Send + Sync, +{ + type Rejection = Error; + + async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { + let ticket = MFATicket::from_request_parts(parts, state).await?; + + if !ticket.validated { + Ok(UnvalidatedTicket(ticket)) + } else { + Err(create_error!(InvalidToken)) + } + } +} diff --git a/crates/core/database/src/models/mfa_tickets/mod.rs b/crates/core/database/src/models/mfa_tickets/mod.rs new file mode 100644 index 000000000..4e58da725 --- /dev/null +++ b/crates/core/database/src/models/mfa_tickets/mod.rs @@ -0,0 +1,11 @@ +#[cfg(feature = "axum-impl")] +mod axum; +mod model; +mod ops; +#[cfg(feature = "rocket-impl")] +mod rocket; +#[cfg(feature = "rocket-impl")] +mod schema; + +pub use model::*; +pub use ops::*; diff --git a/crates/core/database/src/models/mfa_tickets/model.rs b/crates/core/database/src/models/mfa_tickets/model.rs new file mode 100644 index 000000000..c9063efdd --- /dev/null +++ b/crates/core/database/src/models/mfa_tickets/model.rs @@ -0,0 +1,105 @@ +use iso8601_timestamp::{Duration, Timestamp}; +use std::ops::Deref; + +use nanoid::nanoid; +use revolt_result::Result; + +use crate::{Database, MultiFactorAuthentication}; + +auto_derived_partial!( + /// Multi-factor auth ticket + pub struct MFATicket { + /// Unique Id + #[serde(rename = "_id")] + pub id: String, + + /// Account Id + pub account_id: String, + + /// Unique Token + pub token: String, + + /// Whether this ticket has been validated + /// (can be used for account actions) + pub validated: bool, + + /// Whether this ticket is authorised + /// (can be used to log a user in) + pub authorised: bool, + + /// TOTP code at time of ticket creation + pub last_totp_code: Option, + }, + "PartialMFATicket" +); + +/// Ticket which is guaranteed to be valid for use +/// +/// If used in a Rocket guard, it will be consumed on match +#[derive(Debug, Serialize, Deserialize)] +pub struct ValidatedTicket(pub MFATicket); + +/// Ticket which is guaranteed to not be valid for use +#[derive(Debug, Serialize, Deserialize)] +pub struct UnvalidatedTicket(pub MFATicket); + +impl MFATicket { + /// Create a new MFA ticket + pub fn new(account_id: String, validated: bool) -> MFATicket { + MFATicket { + id: ulid::Ulid::new().to_string(), + account_id, + token: nanoid!(64), + validated, + authorised: false, + last_totp_code: None, + } + } + + /// Populate an MFA ticket with valid MFA codes + pub async fn populate(&mut self, mfa: &MultiFactorAuthentication) { + self.last_totp_code = mfa.totp_token.generate_code().ok(); + } + + /// Save model + pub async fn save(&self, db: &Database) -> Result<()> { + db.save_ticket(self).await + } + + /// Check if this MFA ticket has expired + pub fn is_expired(&self) -> bool { + let now = Timestamp::now_utc(); + + let datetime: Timestamp = ulid::Ulid::from_string(&self.id) + .expect("Valid `ulid`") + .datetime() + .into(); + + now > (datetime.checked_add(Duration::minutes(5)).unwrap()) + } + + /// Claim and remove this MFA ticket + pub async fn claim(&self, db: &Database) -> Result<()> { + if self.is_expired() { + return Err(create_error!(InvalidToken)); + } + + db.delete_ticket(&self.id).await + } +} + +impl Deref for ValidatedTicket { + type Target = MFATicket; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Deref for UnvalidatedTicket { + type Target = MFATicket; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} diff --git a/crates/core/database/src/models/mfa_tickets/ops.rs b/crates/core/database/src/models/mfa_tickets/ops.rs new file mode 100644 index 000000000..0024400bf --- /dev/null +++ b/crates/core/database/src/models/mfa_tickets/ops.rs @@ -0,0 +1,22 @@ +use revolt_result::Result; + +use crate::MFATicket; + +#[cfg(feature = "mongodb")] +mod mongodb; +mod reference; + +#[async_trait] +pub trait AbstractMFATickets: Sync + Send { + /// Find ticket by token + async fn fetch_ticket_by_token(&self, token: &str) -> Result; + + /// Save ticket + async fn save_ticket(&self, ticket: &MFATicket) -> Result<()>; + + /// Delete ticket + async fn delete_ticket(&self, id: &str) -> Result<()>; + + /// Delete all expired tickets + async fn delete_expired_tickets(&self) -> Result; +} diff --git a/crates/core/database/src/models/mfa_tickets/ops/mongodb.rs b/crates/core/database/src/models/mfa_tickets/ops/mongodb.rs new file mode 100644 index 000000000..feb869f36 --- /dev/null +++ b/crates/core/database/src/models/mfa_tickets/ops/mongodb.rs @@ -0,0 +1,67 @@ +use std::time::{Duration, SystemTime}; + +use crate::{AbstractMFATickets, MFATicket, MongoDb}; +use bson::{to_document, Document}; +use iso8601_timestamp::Timestamp; +use mongodb::options::UpdateOptions; +use revolt_result::Result; +use ulid::Ulid; + +const COL: &str = "mfa_tickets"; + +#[async_trait] +impl AbstractMFATickets for MongoDb { + /// Find ticket by token + /// + /// Ticket is only valid for 5 minute + async fn fetch_ticket_by_token(&self, token: &str) -> Result { + let ticket: MFATicket = query!(self, find_one, COL, doc! { "token": token })? + .ok_or_else(|| create_error!(InvalidToken))?; + + if let Ok(ulid) = Ulid::from_string(&ticket.id) { + if Timestamp::from(ulid.datetime() + Duration::from_mins(5)) > Timestamp::now_utc() { + Ok(ticket) + } else { + Err(create_error!(InvalidToken)) + } + } else { + Err(create_error!(InvalidToken)) + } + } + + /// Save ticket + async fn save_ticket(&self, ticket: &MFATicket) -> Result<()> { + self.col::(COL) + .update_one( + doc! { + "_id": &ticket.id + }, + doc! { + "$set": to_document(ticket).map_err(|_| create_database_error!("to_document", COL))?, + }, + ) + .with_options(UpdateOptions::builder().upsert(true).build()) + .await + .map_err(|_| create_database_error!("upsert_one", COL)) + .map(|_| ()) + } + + /// Delete ticket + async fn delete_ticket(&self, id: &str) -> Result<()> { + query!(self, delete_one_by_id, COL, id).map(|_| ()) + } + + /// Delete all expired tickets + async fn delete_expired_tickets(&self) -> Result { + let threshhold = + Ulid::from_datetime(SystemTime::now() - Duration::from_mins(5)).to_string(); + + self.col::(COL) + .delete_many(doc! { + "_id": { "$lt": threshhold } + }) + .await + .map_err(|_| create_database_error!("delete_many", COL)) + .map(|result| result.deleted_count as usize) + } +} diff --git a/crates/core/database/src/models/mfa_tickets/ops/reference.rs b/crates/core/database/src/models/mfa_tickets/ops/reference.rs new file mode 100644 index 000000000..a5e2ce5ea --- /dev/null +++ b/crates/core/database/src/models/mfa_tickets/ops/reference.rs @@ -0,0 +1,57 @@ +use std::time::{Duration, SystemTime}; + +use crate::{AbstractMFATickets, MFATicket, ReferenceDb}; +use iso8601_timestamp::Timestamp; +use revolt_result::Result; +use ulid::Ulid; + +#[async_trait] +impl AbstractMFATickets for ReferenceDb { + /// Find ticket by token + async fn fetch_ticket_by_token(&self, token: &str) -> Result { + let tickets = self.tickets.lock().await; + let ticket = tickets + .values() + .find(|ticket| ticket.token == token) + .ok_or_else(|| create_error!(InvalidToken))?; + + if let Ok(ulid) = Ulid::from_string(&ticket.id) { + if Timestamp::from(ulid.datetime() + Duration::from_mins(5)) > Timestamp::now_utc() { + Ok(ticket.clone()) + } else { + Err(create_error!(InvalidToken)) + } + } else { + Err(create_error!(InvalidToken)) + } + } + + /// Save ticket + async fn save_ticket(&self, ticket: &MFATicket) -> Result<()> { + let mut tickets = self.tickets.lock().await; + tickets.insert(ticket.id.to_string(), ticket.clone()); + Ok(()) + } + + /// Delete ticket + async fn delete_ticket(&self, id: &str) -> Result<()> { + let mut tickets = self.tickets.lock().await; + if tickets.remove(id).is_some() { + Ok(()) + } else { + Err(create_error!(InvalidToken)) + } + } + + /// Delete all expired tickets + async fn delete_expired_tickets(&self) -> Result { + let threshhold = + Ulid::from_datetime(SystemTime::now() - Duration::from_mins(5)).to_string(); + let mut tickets = self.tickets.lock().await; + + let before = tickets.len(); + tickets.retain(|_, ticket| ticket.id >= threshhold); + + Ok(before - tickets.len()) + } +} diff --git a/crates/core/database/src/models/mfa_tickets/rocket.rs b/crates/core/database/src/models/mfa_tickets/rocket.rs new file mode 100644 index 000000000..f8b714638 --- /dev/null +++ b/crates/core/database/src/models/mfa_tickets/rocket.rs @@ -0,0 +1,81 @@ +use crate::{Database, MFATicket, UnvalidatedTicket, ValidatedTicket}; +use revolt_result::Error; +use rocket::{ + http::Status, + outcome::Outcome, + request::{self, FromRequest}, + Request, +}; + +#[rocket::async_trait] +impl<'r> FromRequest<'r> for MFATicket { + type Error = Error; + + #[allow(clippy::collapsible_match)] + async fn from_request(request: &'r Request<'_>) -> request::Outcome { + if let Some(header_mfa_ticket) = request.headers().get("x-mfa-ticket").next() { + if let Ok(ticket) = request + .rocket() + .state::() + .expect("`Database`") + .fetch_ticket_by_token(header_mfa_ticket) + .await + { + Outcome::Success(ticket) + } else { + Outcome::Error((Status::Unauthorized, create_error!(InvalidToken))) + } + } else { + Outcome::Error((Status::Unauthorized, create_error!(MissingHeaders))) + } + } +} + +#[rocket::async_trait] +impl<'r> FromRequest<'r> for ValidatedTicket { + type Error = Error; + + #[allow(clippy::collapsible_match)] + async fn from_request(request: &'r Request<'_>) -> request::Outcome { + match request.guard::().await { + Outcome::Success(ticket) => { + if ticket.validated { + let db = request + .rocket() + .state::() + .expect("`Database`"); + + if ticket.claim(db).await.is_ok() { + Outcome::Success(ValidatedTicket(ticket)) + } else { + Outcome::Error((Status::Forbidden, create_error!(InvalidToken))) + } + } else { + Outcome::Error((Status::Forbidden, create_error!(InvalidToken))) + } + } + Outcome::Forward(f) => Outcome::Forward(f), + Outcome::Error(err) => Outcome::Error(err), + } + } +} + +#[rocket::async_trait] +impl<'r> FromRequest<'r> for UnvalidatedTicket { + type Error = Error; + + #[allow(clippy::collapsible_match)] + async fn from_request(request: &'r Request<'_>) -> request::Outcome { + match request.guard::().await { + Outcome::Success(ticket) => { + if !ticket.validated { + Outcome::Success(UnvalidatedTicket(ticket)) + } else { + Outcome::Error((Status::Forbidden, create_error!(InvalidToken))) + } + } + Outcome::Forward(f) => Outcome::Forward(f), + Outcome::Error(err) => Outcome::Error(err), + } + } +} diff --git a/crates/core/database/src/models/mfa_tickets/schema.rs b/crates/core/database/src/models/mfa_tickets/schema.rs new file mode 100644 index 000000000..b85841292 --- /dev/null +++ b/crates/core/database/src/models/mfa_tickets/schema.rs @@ -0,0 +1,80 @@ +use revolt_okapi::openapi3::{SecurityScheme, SecuritySchemeData}; +use revolt_rocket_okapi::{ + gen::OpenApiGenerator, + request::{OpenApiFromRequest, RequestHeaderInput}, +}; + +use crate::{MFATicket, ValidatedTicket, UnvalidatedTicket}; + + +impl<'r> OpenApiFromRequest<'r> for MFATicket { + fn from_request_input( + _gen: &mut OpenApiGenerator, + _name: String, + _required: bool, + ) -> revolt_rocket_okapi::Result { + let mut requirements = schemars::Map::new(); + requirements.insert("MFA Ticket".to_owned(), vec![]); + + Ok(RequestHeaderInput::Security( + "MFA Ticket".to_owned(), + SecurityScheme { + data: SecuritySchemeData::ApiKey { + name: "x-mfa-ticket".to_owned(), + location: "header".to_owned(), + }, + description: Some("Used to authorise a request.".to_owned()), + extensions: schemars::Map::new(), + }, + requirements, + )) + } +} + +impl<'r> OpenApiFromRequest<'r> for ValidatedTicket { + fn from_request_input( + _gen: &mut OpenApiGenerator, + _name: String, + _required: bool, + ) -> revolt_rocket_okapi::Result { + let mut requirements = schemars::Map::new(); + requirements.insert("Valid MFA Ticket".to_owned(), vec![]); + + Ok(RequestHeaderInput::Security( + "Valid MFA Ticket".to_owned(), + SecurityScheme { + data: SecuritySchemeData::ApiKey { + name: "x-mfa-ticket".to_owned(), + location: "header".to_owned(), + }, + description: Some("Used to authorise a request.".to_owned()), + extensions: schemars::Map::new(), + }, + requirements, + )) + } +} + +impl<'r> OpenApiFromRequest<'r> for UnvalidatedTicket { + fn from_request_input( + _gen: &mut OpenApiGenerator, + _name: String, + _required: bool, + ) -> revolt_rocket_okapi::Result { + let mut requirements = schemars::Map::new(); + requirements.insert("Unvalidated MFA Ticket".to_owned(), vec![]); + + Ok(RequestHeaderInput::Security( + "Unvalidated MFA Ticket".to_owned(), + SecurityScheme { + data: SecuritySchemeData::ApiKey { + name: "x-mfa-ticket".to_owned(), + location: "header".to_owned(), + }, + description: Some("Used to authorise a request.".to_owned()), + extensions: schemars::Map::new(), + }, + requirements, + )) + } +} \ No newline at end of file diff --git a/crates/core/database/src/models/mod.rs b/crates/core/database/src/models/mod.rs index 93bd556c8..0852adfc4 100644 --- a/crates/core/database/src/models/mod.rs +++ b/crates/core/database/src/models/mod.rs @@ -17,6 +17,10 @@ mod server_members; mod servers; mod user_settings; mod users; +mod accounts; +mod account_invites; +mod sessions; +mod mfa_tickets; pub use admin_migrations::*; pub use bots::*; @@ -37,6 +41,10 @@ pub use server_members::*; pub use servers::*; pub use user_settings::*; pub use users::*; +pub use accounts::*; +pub use account_invites::*; +pub use sessions::*; +pub use mfa_tickets::*; use crate::{Database, ReferenceDb}; @@ -65,6 +73,10 @@ pub trait AbstractDatabase: + servers::AbstractServers + user_settings::AbstractUserSettings + users::AbstractUsers + + accounts::AbstractAccounts + + account_invites::AbstractAccountInvites + + sessions::AbstractSessions + + mfa_tickets::AbstractMFATickets { } diff --git a/crates/core/database/src/models/server_members/ops.rs b/crates/core/database/src/models/server_members/ops.rs index 1c59bf0fc..73918b0b4 100644 --- a/crates/core/database/src/models/server_members/ops.rs +++ b/crates/core/database/src/models/server_members/ops.rs @@ -129,4 +129,7 @@ pub trait AbstractServerMembers: Sync + Send { /// Fetch all members who have been marked for deletion. async fn remove_dangling_members(&self) -> Result<()>; + + /// Removes a user from every server they are in + async fn clear_memberships(&self, user_id: &str) -> Result<()>; } diff --git a/crates/core/database/src/models/server_members/ops/mongodb.rs b/crates/core/database/src/models/server_members/ops/mongodb.rs index 377e5877a..99cce7c9d 100644 --- a/crates/core/database/src/models/server_members/ops/mongodb.rs +++ b/crates/core/database/src/models/server_members/ops/mongodb.rs @@ -326,6 +326,17 @@ impl AbstractServerMembers for MongoDb { .map(|_| ()) .map_err(|_| create_database_error!("count_documents", COL)) } + + /// Removes a user from every server they are in + /// + /// **This should only be used for account deletion.** + async fn clear_memberships(&self, user_id: &str) -> Result<()> { + self.col::(COL) + .delete_many(doc! { "_id.user": user_id }) + .await + .map(|_| ()) + .map_err(|_| create_database_error!("delete_many", COL)) + } } impl IntoDocumentPath for FieldsMember { diff --git a/crates/core/database/src/models/server_members/ops/reference.rs b/crates/core/database/src/models/server_members/ops/reference.rs index 3238edbb1..32d8f64ea 100644 --- a/crates/core/database/src/models/server_members/ops/reference.rs +++ b/crates/core/database/src/models/server_members/ops/reference.rs @@ -200,4 +200,13 @@ impl AbstractServerMembers for ReferenceDb { async fn remove_dangling_members(&self) -> Result<()> { todo!() } + + /// Removes a user from every server they are in + async fn clear_memberships(&self, user_id: &str) -> Result<()> { + let mut server_members = self.server_members.lock().await; + + server_members.retain(|_, v| v.id.user != user_id); + + Ok(()) + } } diff --git a/crates/core/database/src/models/servers/ops.rs b/crates/core/database/src/models/servers/ops.rs index c7ae6228d..89d12beaf 100644 --- a/crates/core/database/src/models/servers/ops.rs +++ b/crates/core/database/src/models/servers/ops.rs @@ -17,6 +17,8 @@ pub trait AbstractServers: Sync + Send { /// Fetch a servers by their ids async fn fetch_servers<'a>(&self, ids: &'a [String]) -> Result>; + async fn fetch_owned_servers(&self, user_id: &str) -> Result>; + /// Update a server with new information async fn update_server( &self, diff --git a/crates/core/database/src/models/servers/ops/mongodb.rs b/crates/core/database/src/models/servers/ops/mongodb.rs index 964de4103..21183d3f4 100644 --- a/crates/core/database/src/models/servers/ops/mongodb.rs +++ b/crates/core/database/src/models/servers/ops/mongodb.rs @@ -43,6 +43,17 @@ impl AbstractServers for MongoDb { .await) } + async fn fetch_owned_servers(&self, user_id: &str) -> Result> { + query!( + self, + find, + COL, + doc! { + "owner": user_id + } + ) + } + /// Update a server with new information async fn update_server( &self, diff --git a/crates/core/database/src/models/servers/ops/reference.rs b/crates/core/database/src/models/servers/ops/reference.rs index 572311bde..0af6ad26c 100644 --- a/crates/core/database/src/models/servers/ops/reference.rs +++ b/crates/core/database/src/models/servers/ops/reference.rs @@ -40,6 +40,16 @@ impl AbstractServers for ReferenceDb { .collect() } + async fn fetch_owned_servers(&self, user_id: &str) -> Result> { + let servers = self.servers.lock().await; + + Ok(servers + .values() + .filter(|server| server.owner == user_id) + .cloned() + .collect()) + } + /// Update a server with new information async fn update_server( &self, diff --git a/crates/core/database/src/models/sessions/axum.rs b/crates/core/database/src/models/sessions/axum.rs new file mode 100644 index 000000000..57357aa92 --- /dev/null +++ b/crates/core/database/src/models/sessions/axum.rs @@ -0,0 +1,24 @@ +use axum::{extract::{FromRef, FromRequestParts}, http::request::Parts}; + +use revolt_result::{create_error, Error, Result}; + +use crate::{Database, Session}; + +#[async_trait] +impl FromRequestParts for Session +where + Database: FromRef, + S: Send + Sync +{ + type Rejection = Error; + + async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { + let db = Database::from_ref(state); + + if let Some(Ok(token)) = parts.headers.get("x-session-token").map(|v| v.to_str()) { + db.fetch_session_by_token(token).await + } else { + Err(create_error!(MissingHeaders)) + } + } +} diff --git a/crates/core/database/src/models/sessions/mod.rs b/crates/core/database/src/models/sessions/mod.rs new file mode 100644 index 000000000..4e58da725 --- /dev/null +++ b/crates/core/database/src/models/sessions/mod.rs @@ -0,0 +1,11 @@ +#[cfg(feature = "axum-impl")] +mod axum; +mod model; +mod ops; +#[cfg(feature = "rocket-impl")] +mod rocket; +#[cfg(feature = "rocket-impl")] +mod schema; + +pub use model::*; +pub use ops::*; diff --git a/crates/core/database/src/models/sessions/model.rs b/crates/core/database/src/models/sessions/model.rs new file mode 100644 index 000000000..0be0246b3 --- /dev/null +++ b/crates/core/database/src/models/sessions/model.rs @@ -0,0 +1,68 @@ +use iso8601_timestamp::Timestamp; + +use crate::{events::client::EventV1, Database}; +use revolt_result::Result; + +auto_derived_partial!( + /// Session information + pub struct Session { + /// Unique Id + #[serde(rename = "_id")] + pub id: String, + + /// User Id + pub user_id: String, + + /// Session token + pub token: String, + + /// Display name + pub name: String, + + /// When the session was last logged in + pub last_seen: Timestamp, + + /// Where the session originated from + /// + /// This could be used to differentiate sessions that come from staging/test vs prod, etc. + #[serde(skip_serializing_if = "Option::is_none")] + pub origin: Option, + + /// Web Push subscription + #[serde(skip_serializing_if = "Option::is_none")] + pub subscription: Option, + }, + "PartialSession" +); + +auto_derived!( + /// Web Push subscription + pub struct WebPushSubscription { + pub endpoint: String, + pub p256dh: String, + pub auth: String, + } +); + +impl Session { + /// Save model + pub async fn save(&self, db: &Database) -> Result<()> { + db.save_session(self).await + } + + /// Delete session + pub async fn delete(self, db: &Database) -> Result<()> { + // Delete from database + db.delete_session(&self.id).await?; + + // Create and push event + EventV1::DeleteSession { + user_id: self.user_id.clone(), + session_id: self.id, + } + .private(self.user_id) + .await; + + Ok(()) + } +} diff --git a/crates/core/database/src/models/sessions/ops.rs b/crates/core/database/src/models/sessions/ops.rs new file mode 100644 index 000000000..17993411c --- /dev/null +++ b/crates/core/database/src/models/sessions/ops.rs @@ -0,0 +1,37 @@ +use iso8601_timestamp::Timestamp; +use revolt_result::Result; + +use crate::Session; + +#[cfg(feature = "mongodb")] +mod mongodb; +mod reference; + +#[async_trait] +pub trait AbstractSessions: Sync + Send { + /// Find session by id + async fn fetch_session(&self, id: &str) -> Result; + + /// Find sessions by user id + async fn fetch_sessions(&self, user_id: &str) -> Result>; + + /// Find sessions by user ids + async fn fetch_sessions_with_subscription(&self, user_ids: &[String]) -> Result>; + + /// Find session by token + async fn fetch_session_by_token(&self, token: &str) -> Result; + + /// Save session + async fn save_session(&self, session: &Session) -> Result<()>; + + /// Delete session + async fn delete_session(&self, id: &str) -> Result<()>; + + /// Delete session + async fn delete_all_sessions(&self, user_id: &str, ignore: Option) -> Result<()>; + + /// Remove push subscription for a session by session id + async fn remove_push_subscription_by_session_id(&self, session_id: &str) -> Result<()>; + + async fn update_session_last_seen(&self, session_id: &str, when: Timestamp) -> Result<()>; +} diff --git a/crates/core/database/src/models/sessions/ops/mongodb.rs b/crates/core/database/src/models/sessions/ops/mongodb.rs new file mode 100644 index 000000000..33ba933b4 --- /dev/null +++ b/crates/core/database/src/models/sessions/ops/mongodb.rs @@ -0,0 +1,142 @@ +use crate::{AbstractSessions, MongoDb, Session}; +use bson::{to_bson, to_document}; +use iso8601_timestamp::Timestamp; +use mongodb::options::UpdateOptions; +use revolt_result::Result; + +const COL: &str = "sessions"; + +#[async_trait] +impl AbstractSessions for MongoDb { + /// Find session by id + async fn fetch_session(&self, id: &str) -> Result { + query!(self, find_one_by_id, COL, id)?.ok_or_else(|| create_error!(UnknownUser)) + } + + /// Find sessions by user id + async fn fetch_sessions(&self, user_id: &str) -> Result> { + query!( + self, + find, + COL, + doc! { + "user_id": user_id + } + ) + } + + /// Find sessions by user ids + async fn fetch_sessions_with_subscription(&self, user_ids: &[String]) -> Result> { + query!( + self, + find, + COL, + doc! { + "user_id": { + "$in": user_ids + }, + "subscription": { + "$exists": true + } + } + ) + } + + /// Fetch a session from the database by token + async fn fetch_session_by_token(&self, token: &str) -> Result { + query!( + self, + find_one, + COL, + doc! { + "token": token + } + )? + .ok_or_else(|| create_error!(InvalidSession)) + } + + /// Save session + async fn save_session(&self, session: &Session) -> Result<()> { + self.col::(COL) + .update_one( + doc! { + "_id": &session.id + }, + doc! { + "$set": to_document(session).map_err(|_| create_database_error!("to_document", COL))?, + }, + ) + .with_options(UpdateOptions::builder().upsert(true).build()) + .await + .map_err(|_| create_database_error!("upsert_one", COL)) + .map(|_| ()) + } + + /// Delete session + async fn delete_session(&self, id: &str) -> Result<()> { + self.col::(COL) + .delete_one(doc! { + "_id": id + }) + .await + .map_err(|_| create_database_error!("delete_one", COL)) + .map(|_| ()) + } + + /// Delete session + async fn delete_all_sessions(&self, user_id: &str, ignore: Option) -> Result<()> { + let mut query = doc! { + "user_id": user_id + }; + + if let Some(id) = ignore { + query.insert( + "_id", + doc! { + "$ne": id + }, + ); + } + + self.col::(COL) + .delete_many(query) + .await + .map_err(|_| create_database_error!("delete_one", COL)) + .map(|_| ()) + } + + /// Remove push subscription for a session by session id + async fn remove_push_subscription_by_session_id(&self, session_id: &str) -> Result<()> { + self.col::(COL) + .update_one( + doc! { + "_id": session_id + }, + doc! { + "$unset": { + "subscription": 1 + } + }, + ) + .await + .map(|_| ()) + .map_err(|_| create_database_error!("update_one", COL)) + } + + async fn update_session_last_seen(&self, session_id: &str, when: Timestamp) -> Result<()> { + self.col::(COL) + .update_one( + doc! { + "_id": session_id + }, + doc! { + "$set": { + "last_seen": to_bson(&when).unwrap() + } + }, + ) + .await + .map(|_| ()) + .map_err(|_| create_database_error!("update_one", COL)) + } +} diff --git a/crates/core/database/src/models/sessions/ops/reference.rs b/crates/core/database/src/models/sessions/ops/reference.rs new file mode 100644 index 000000000..4b7ffab8c --- /dev/null +++ b/crates/core/database/src/models/sessions/ops/reference.rs @@ -0,0 +1,101 @@ +use crate::{AbstractSessions, ReferenceDb, Session}; +use iso8601_timestamp::Timestamp; +use revolt_result::Result; + +#[async_trait] +impl AbstractSessions for ReferenceDb { + /// Find session by id + async fn fetch_session(&self, id: &str) -> Result { + let sessions = self.sessions.lock().await; + sessions + .get(id) + .cloned() + .ok_or_else(|| create_error!(UnknownUser)) + } + + /// Find sessions by user id + async fn fetch_sessions(&self, user_id: &str) -> Result> { + let sessions = self.sessions.lock().await; + Ok(sessions + .values() + .filter(|session| session.user_id == user_id) + .cloned() + .collect()) + } + + /// Find sessions by user ids + async fn fetch_sessions_with_subscription(&self, user_ids: &[String]) -> Result> { + let sessions = self.sessions.lock().await; + Ok(sessions + .values() + .filter(|session| session.subscription.is_some() && user_ids.contains(&session.user_id)) + .cloned() + .collect()) + } + + /// Find session by token + async fn fetch_session_by_token(&self, token: &str) -> Result { + let sessions = self.sessions.lock().await; + sessions + .values() + .find(|session| session.token == token) + .cloned() + .ok_or_else(|| create_error!(InvalidSession)) + } + + /// Save session + async fn save_session(&self, session: &Session) -> Result<()> { + let mut sessions = self.sessions.lock().await; + sessions.insert(session.id.to_string(), session.clone()); + Ok(()) + } + + /// Delete session + async fn delete_session(&self, id: &str) -> Result<()> { + let mut sessions = self.sessions.lock().await; + if sessions.remove(id).is_some() { + Ok(()) + } else { + Err(create_error!(InvalidSession)) + } + } + + /// Delete session + async fn delete_all_sessions(&self, user_id: &str, ignore: Option) -> Result<()> { + let mut sessions = self.sessions.lock().await; + sessions.retain(|_, session| { + if session.user_id == user_id { + if let Some(ignore) = &ignore { + ignore == &session.id + } else { + false + } + } else { + true + } + }); + + Ok(()) + } + + /// Remove push subscription for a session by session id + async fn remove_push_subscription_by_session_id(&self, session_id: &str) -> Result<()> { + let mut sessions = self.sessions.lock().await; + + if let Some(session) = sessions.get_mut(session_id) { + session.subscription = None; + }; + + Ok(()) + } + + async fn update_session_last_seen(&self, session_id: &str, when: Timestamp) -> Result<()> { + let mut sessions = self.sessions.lock().await; + + if let Some(session) = sessions.get_mut(session_id) { + session.last_seen = when; + }; + + Ok(()) + } +} diff --git a/crates/core/database/src/models/sessions/rocket.rs b/crates/core/database/src/models/sessions/rocket.rs new file mode 100644 index 000000000..6b1f5421d --- /dev/null +++ b/crates/core/database/src/models/sessions/rocket.rs @@ -0,0 +1,30 @@ +use crate::{Database, Session}; +use revolt_result::Error; +use rocket::{ + http::Status, + request::{FromRequest, Outcome}, + Request, +}; + +#[rocket::async_trait] +impl<'r> FromRequest<'r> for Session { + type Error = Error; + + async fn from_request(request: &'r Request<'_>) -> Outcome { + if let Some(token) = request.headers().get("x-session-token").next() { + if let Ok(session) = request + .rocket() + .state::() + .expect("`Database`") + .fetch_session_by_token(token) + .await + { + Outcome::Success(session) + } else { + Outcome::Error((Status::Unauthorized, create_error!(InvalidSession))) + } + } else { + Outcome::Error((Status::Unauthorized, create_error!(MissingHeaders))) + } + } +} diff --git a/crates/core/database/src/models/sessions/schema.rs b/crates/core/database/src/models/sessions/schema.rs new file mode 100644 index 000000000..ec428f23a --- /dev/null +++ b/crates/core/database/src/models/sessions/schema.rs @@ -0,0 +1,32 @@ +use revolt_okapi::openapi3::{SecurityScheme, SecuritySchemeData}; +use revolt_rocket_okapi::{ + gen::OpenApiGenerator, + request::{OpenApiFromRequest, RequestHeaderInput}, +}; + +use crate::Session; + + +impl<'r> OpenApiFromRequest<'r> for Session { + fn from_request_input( + _gen: &mut OpenApiGenerator, + _name: String, + _required: bool, + ) -> revolt_rocket_okapi::Result { + let mut requirements = schemars::Map::new(); + requirements.insert("Session Token".to_owned(), vec![]); + + Ok(RequestHeaderInput::Security( + "Session Token".to_owned(), + SecurityScheme { + data: SecuritySchemeData::ApiKey { + name: "x-session-token".to_owned(), + location: "header".to_owned(), + }, + description: Some("Used to authenticate as a user.".to_owned()), + extensions: schemars::Map::new(), + }, + requirements, + )) + } +} \ No newline at end of file diff --git a/crates/core/database/src/models/users/model.rs b/crates/core/database/src/models/users/model.rs index bea37fac0..834485191 100644 --- a/crates/core/database/src/models/users/model.rs +++ b/crates/core/database/src/models/users/model.rs @@ -1,8 +1,11 @@ use std::{collections::HashSet, str::FromStr, time::Duration}; -use crate::{events::client::EventV1, Database, File, RatelimitEvent, AMQP}; +use crate::{ + events::client::EventV1, + util::email::{email_templates, send_email}, + Database, File, RatelimitEvent, AMQP, +}; -use authifier::config::{EmailVerificationConfig, Template}; use futures::future::join_all; use iso8601_timestamp::Timestamp; use once_cell::sync::Lazy; @@ -718,22 +721,11 @@ impl User { duration_days: Option, reason: Option>, ) -> Result<()> { - let authifier = db.clone().to_authifier().await; - let mut account = authifier - .database - .find_account(&self.id) - .await - .map_err(|_| create_error!(InternalError))?; + let mut account = db.fetch_account(&self.id).await?; - account - .disable(&authifier) - .await - .map_err(|_| create_error!(InternalError))?; + account.disable(db).await?; - account - .delete_all_sessions(&authifier, None) - .await - .map_err(|_| create_error!(InternalError))?; + account.delete_all_sessions(db, None).await?; self.update( db, @@ -749,18 +741,15 @@ impl User { .await?; if let Some(reason) = reason { - if let EmailVerificationConfig::Enabled { smtp, .. } = - authifier.config.email_verification - { - smtp.send_email( + let config = config().await; + + if !config.api.smtp.host.is_empty() { + let templates = email_templates().await; + + send_email( + &config.api.smtp, account.email.clone(), - // maybe move this to common area? - &Template { - title: "Account Suspension".to_string(), - html: Some(include_str!("../../../templates/suspension.html").to_owned()), - text: include_str!("../../../templates/suspension.txt").to_owned(), - url: Default::default(), - }, + &templates.suspension, json!({ "email": account.email, "list": reason.join(", "), @@ -809,7 +798,9 @@ impl User { db, PartialUser { username: Some(format!("Deleted User {}", self.id)), + discriminator: Some("0000".to_string()), flags: Some(2), + relations: Some(Vec::new()), ..Default::default() }, vec![ @@ -837,6 +828,56 @@ impl User { badges } + + /// Removes all relationships which include the user + pub async fn clear_relationships(&self, db: &Database) -> Result<()> { + let user_ids = self + .relations + .iter() + .flatten() + .map(|relation| relation.id.clone()) + .collect(); + + db.clear_user_relationships(&self.id, user_ids).await + } + + /// Removes user from all joined groups + pub async fn remove_from_all_groups(&self, db: &Database) -> Result<()> { + let mut generator = db.find_group_message_channels(&self.id).await?; + + while let Some(groups) = generator.next_n(100).await? { + let ids = groups + .into_iter() + .map(|channel| channel.id().to_string()) + .collect(); + + db.remove_user_from_groups(ids, &self.id).await?; + } + + Ok(()) + } + + /// Deletes the user along with: + /// - deletes owned bots, servers and messages + /// - removes user from all groups + /// - clears relationships + pub async fn delete(&mut self, db: &Database) -> Result<()> { + for bot in db.fetch_bots_by_user(&self.id).await? { + bot.delete(db).await?; + } + + for server in db.fetch_owned_servers(&self.id).await? { + server.delete(db).await?; + } + + self.remove_from_all_groups(db).await?; + db.clear_memberships(&self.id).await?; + self.clear_relationships(db).await?; + db.delete_messages_by_user(&self.id).await?; + self.mark_deleted(db).await?; + + Ok(()) + } } #[cfg(test)] diff --git a/crates/core/database/src/models/users/ops.rs b/crates/core/database/src/models/users/ops.rs index d7586641c..185846d89 100644 --- a/crates/core/database/src/models/users/ops.rs +++ b/crates/core/database/src/models/users/ops.rs @@ -1,5 +1,3 @@ -use authifier::models::Session; -use iso8601_timestamp::Timestamp; use revolt_result::Result; use crate::{FieldsUser, PartialUser, RelationshipStatus, User}; @@ -19,9 +17,6 @@ pub trait AbstractUsers: Sync + Send { /// Fetch a user from the database by their username async fn fetch_user_by_username(&self, username: &str, discriminator: &str) -> Result; - /// Fetch a session from the database by token - async fn fetch_session_by_token(&self, token: &str) -> Result; - /// Fetch multiple users by their ids async fn fetch_users<'a>(&self, ids: &'a [String]) -> Result>; @@ -61,8 +56,6 @@ pub trait AbstractUsers: Sync + Send { /// Delete a user by their id async fn delete_user(&self, id: &str) -> Result<()>; - /// Remove push subscription for a session by session id (TODO: remove) - async fn remove_push_subscription_by_session_id(&self, session_id: &str) -> Result<()>; - - async fn update_session_last_seen(&self, session_id: &str, when: Timestamp) -> Result<()>; + /// Removes all relationships with the user from the list of users + async fn clear_user_relationships(&self, target_id: &str, user_ids: Vec) -> Result<()>; } diff --git a/crates/core/database/src/models/users/ops/mongodb.rs b/crates/core/database/src/models/users/ops/mongodb.rs index 66de248ec..0a6f641f7 100644 --- a/crates/core/database/src/models/users/ops/mongodb.rs +++ b/crates/core/database/src/models/users/ops/mongodb.rs @@ -1,7 +1,5 @@ use ::mongodb::options::{Collation, CollationStrength, FindOneOptions, FindOptions}; -use authifier::models::Session; use futures::StreamExt; -use iso8601_timestamp::Timestamp; use revolt_result::Result; use crate::DocumentId; @@ -47,17 +45,6 @@ impl AbstractUsers for MongoDb { .ok_or_else(|| create_error!(NotFound)) } - /// Fetch a session from the database by token - async fn fetch_session_by_token(&self, token: &str) -> Result { - self.col::("sessions") - .find_one(doc! { - "token": token - }) - .await - .map_err(|_| create_database_error!("find_one", "sessions"))? - .ok_or_else(|| create_error!(InvalidSession)) - } - /// Fetch multiple users by their ids async fn fetch_users<'a>(&self, ids: &'a [String]) -> Result> { Ok(self @@ -321,41 +308,22 @@ impl AbstractUsers for MongoDb { query!(self, delete_one_by_id, COL, id).map(|_| ()) } - /// Remove push subscription for a session by session id (TODO: remove) - async fn remove_push_subscription_by_session_id(&self, session_id: &str) -> Result<()> { - self.col::("sessions") - .update_one( - doc! { - "_id": session_id - }, - doc! { - "$unset": { - "subscription": 1 - } - }, - ) - .await - .map(|_| ()) - .map_err(|_| create_database_error!("update_one", "sessions")) - } - - async fn update_session_last_seen(&self, session_id: &str, when: Timestamp) -> Result<()> { - let formatted: &str = &when.format(); - - self.col::("sessions") - .update_one( - doc! { - "_id": session_id - }, + /// Removes all relationships with the user from the list of users + async fn clear_user_relationships(&self, target_id: &str, user_ids: Vec) -> Result<()> { + self.col::(COL) + .update_many( + doc! { "_id": { "$in": user_ids } }, doc! { - "$set": { - "last_seen": formatted + "$pull": { + "relations": { + "_id": target_id.to_string() + } } }, ) .await .map(|_| ()) - .map_err(|_| create_database_error!("update_one", "sessions")) + .map_err(|_| create_database_error!("bulk_write", COL)) } } diff --git a/crates/core/database/src/models/users/ops/reference.rs b/crates/core/database/src/models/users/ops/reference.rs index 4817f97e4..e9c18b672 100644 --- a/crates/core/database/src/models/users/ops/reference.rs +++ b/crates/core/database/src/models/users/ops/reference.rs @@ -1,5 +1,3 @@ -use authifier::models::Session; -use iso8601_timestamp::Timestamp; use revolt_result::Result; use crate::{FieldsUser, PartialUser, RelationshipStatus, User}; @@ -42,11 +40,6 @@ impl AbstractUsers for ReferenceDb { .ok_or_else(|| create_error!(NotFound)) } - /// Fetch a session from the database by token - async fn fetch_session_by_token(&self, _token: &str) -> Result { - todo!() - } - /// Fetch multiple users by their ids async fn fetch_users<'a>(&self, ids: &'a [String]) -> Result> { let users = self.users.lock().await; @@ -165,12 +158,22 @@ impl AbstractUsers for ReferenceDb { } } - /// Remove push subscription for a session by session id (TODO: remove) - async fn remove_push_subscription_by_session_id(&self, _session_id: &str) -> Result<()> { - todo!() - } + /// Removes all relationships with the user from the list of users + async fn clear_user_relationships( + &self, + target_id: &str, + user_ids: Vec, + ) -> Result<()> { + let mut users = self.users.lock().await; - async fn update_session_last_seen(&self, _session_id: &str, _when: Timestamp) -> Result<()> { - todo!() + for user_id in user_ids { + if let Some(user) = users.get_mut(&user_id) { + if let Some(relations) = &mut user.relations { + relations.retain(|relation| relation.id != target_id); + } + } + } + + Ok(()) } } diff --git a/crates/core/database/src/models/users/rocket.rs b/crates/core/database/src/models/users/rocket.rs index 57b634b15..8729bf748 100644 --- a/crates/core/database/src/models/users/rocket.rs +++ b/crates/core/database/src/models/users/rocket.rs @@ -1,12 +1,12 @@ -use authifier::models::Session; use rocket::http::Status; use rocket::request::{self, FromRequest, Outcome, Request}; +use revolt_result::Error; -use crate::{Database, User}; +use crate::{Database, Session, User}; #[rocket::async_trait] impl<'r> FromRequest<'r> for User { - type Error = authifier::Error; + type Error = Error; async fn from_request(request: &'r Request<'_>) -> request::Outcome { let user: &Option = request @@ -38,7 +38,7 @@ impl<'r> FromRequest<'r> for User { if let Some(user) = user { Outcome::Success(user.clone()) } else { - Outcome::Error((Status::Unauthorized, authifier::Error::InvalidSession)) + Outcome::Error((Status::Unauthorized, create_error!(InvalidSession))) } } } diff --git a/crates/core/database/src/tasks/authifier_relay.rs b/crates/core/database/src/tasks/authifier_relay.rs deleted file mode 100644 index 14bcb692d..000000000 --- a/crates/core/database/src/tasks/authifier_relay.rs +++ /dev/null @@ -1,29 +0,0 @@ -use async_std::channel::{unbounded, Receiver, Sender}; -use authifier::AuthifierEvent; -use once_cell::sync::Lazy; - -use crate::events::client::EventV1; - -static Q: Lazy<(Sender, Receiver)> = Lazy::new(unbounded); - -/// Get sender -pub fn sender() -> Sender { - Q.0.clone() -} - -/// Start a new worker -pub async fn worker() { - loop { - let event = Q.1.recv().await.unwrap(); - match &event { - AuthifierEvent::CreateSession { .. } | AuthifierEvent::CreateAccount { .. } => { - EventV1::Auth(event).global().await - } - AuthifierEvent::DeleteSession { user_id, .. } - | AuthifierEvent::DeleteAllSessions { user_id, .. } => { - let id = user_id.to_string(); - EventV1::Auth(event).private(id).await - } - } - } -} diff --git a/crates/core/database/src/tasks/mod.rs b/crates/core/database/src/tasks/mod.rs index 111d51068..d7e3df61d 100644 --- a/crates/core/database/src/tasks/mod.rs +++ b/crates/core/database/src/tasks/mod.rs @@ -8,14 +8,11 @@ use std::time::Instant; const WORKER_COUNT: usize = 5; pub mod ack; -pub mod authifier_relay; pub mod last_message_id; pub mod process_embeds; /// Spawn background workers pub fn start_workers(db: Database, amqp: AMQP) { - task::spawn(authifier_relay::worker()); - for _ in 0..WORKER_COUNT { task::spawn(ack::worker(db.clone(), amqp.clone())); task::spawn(last_message_id::worker(db.clone())); diff --git a/crates/core/database/src/util/bridge/v0.rs b/crates/core/database/src/util/bridge/v0.rs index 45b80e55f..911bc3717 100644 --- a/crates/core/database/src/util/bridge/v0.rs +++ b/crates/core/database/src/util/bridge/v0.rs @@ -1422,3 +1422,92 @@ impl From for VoiceInformation { } } } + +impl From for AccountInfo { + fn from(item: crate::Account) -> Self { + AccountInfo { + id: item.id, + email: item.email, + } + } +} + +impl From for MFATicket { + fn from(value: crate::MFATicket) -> Self { + MFATicket { + id: value.id, + account_id: value.account_id, + token: value.token, + validated: value.validated, + authorised: value.authorised, + last_totp_code: value.last_totp_code, + } + } +} + +impl From for MultiFactorStatus { + fn from(item: crate::MultiFactorAuthentication) -> Self { + MultiFactorStatus { + // email_otp: item.enable_email_otp, + // trusted_handover: item.enable_trusted_handover, + // email_mfa: item.enable_email_mfa, + totp_mfa: !item.totp_token.is_disabled(), + // security_key_mfa: item.security_key_token.is_some(), + recovery_active: !item.recovery_codes.is_empty(), + ..Default::default() + } + } +} + +impl From for MFAMethod { + fn from(value: crate::MFAMethod) -> Self { + match value { + crate::MFAMethod::Password => MFAMethod::Password, + crate::MFAMethod::Recovery => MFAMethod::Recovery, + crate::MFAMethod::Totp => MFAMethod::Totp, + } + } +} + +impl From for SessionInfo { + fn from(item: crate::Session) -> Self { + SessionInfo { + id: item.id, + name: item.name, + } + } +} + +impl From for Session { + fn from(value: crate::Session) -> Self { + Session { + id: value.id, + user_id: value.user_id, + token: value.token, + name: value.name, + last_seen: value.last_seen, + origin: value.origin, + subscription: value.subscription.map(Into::into), + } + } +} + +impl From for WebPushSubscription { + fn from(value: crate::WebPushSubscription) -> Self { + WebPushSubscription { + endpoint: value.endpoint, + p256dh: value.p256dh, + auth: value.auth, + } + } +} + +impl From for crate::WebPushSubscription { + fn from(value: WebPushSubscription) -> Self { + crate::WebPushSubscription { + endpoint: value.endpoint, + p256dh: value.p256dh, + auth: value.auth, + } + } +} diff --git a/crates/core/database/src/util/captcha.rs b/crates/core/database/src/util/captcha.rs new file mode 100644 index 000000000..73e7d87d9 --- /dev/null +++ b/crates/core/database/src/util/captcha.rs @@ -0,0 +1,42 @@ +use reqwest::Client; +use revolt_config::config; +use revolt_result::Result; +use std::sync::LazyLock; + +static CLIENT: LazyLock = LazyLock::new(Client::new); + +#[derive(Serialize, Deserialize)] +struct CaptchaResponse { + success: bool, +} + +pub async fn check_captcha(token: Option<&str>) -> Result<()> { + let config = config().await; + + if !config.api.security.captcha.hcaptcha_key.is_empty() { + let Some(token) = token else { + return Err(create_error!(CaptchaFailed)); + }; + + let response = CLIENT + .post("https://hcaptcha.com/siteverify") + .form(&[ + ("secret", config.api.security.captcha.hcaptcha_key.as_str()), + ("response", token), + ]) + .send() + .await + .map_err(|_| create_error!(CaptchaFailed))? + .json::() + .await + .map_err(|_| create_error!(CaptchaFailed))?; + + if response.success { + Ok(()) + } else { + Err(create_error!(CaptchaFailed)) + } + } else { + Ok(()) + } +} diff --git a/crates/core/database/src/util/chunked.rs b/crates/core/database/src/util/chunked.rs new file mode 100644 index 000000000..16ac15825 --- /dev/null +++ b/crates/core/database/src/util/chunked.rs @@ -0,0 +1,63 @@ +#[cfg(feature = "mongodb")] +use ::mongodb::{ClientSession, SessionCursor}; +use revolt_result::{Result, ToRevoltError}; +use serde::Deserialize; + +#[derive(Debug)] +#[allow(clippy::large_enum_variant)] +pub enum ChunkedDatabaseGenerator { + #[cfg(feature = "mongodb")] + MongoDb { + session: ClientSession, + cursor: SessionCursor, + }, + + Reference { + offset: usize, + data: Vec, + }, +} + +impl Deserialize<'d> + Clone> ChunkedDatabaseGenerator { + #[cfg(feature = "mongodb")] + pub fn new_mongo(session: ClientSession, cursor: SessionCursor) -> Self { + Self::MongoDb { session, cursor } + } + + pub fn new_reference(data: Vec) -> Self { + Self::Reference { offset: 0, data } + } + + pub async fn next(&mut self) -> Result> { + match self { + #[cfg(feature = "mongodb")] + Self::MongoDb { session, cursor } => { + cursor.next(session).await.transpose().to_internal_error() + } + Self::Reference { offset, data } => { + if let Some(value) = data.get(*offset) { + *offset += 1; + Ok(Some(value.clone())) + } else { + Ok(None) + } + } + } + } + + pub async fn next_n(&mut self, n: usize) -> Result>> { + let mut docs = Vec::new(); + + while docs.len() < n { + if let Some(doc) = self.next().await? { + docs.push(doc); + } else if docs.is_empty() { + return Ok(None); + } else { + break; + } + } + + Ok(Some(docs)) + } +} diff --git a/crates/core/database/src/util/email.rs b/crates/core/database/src/util/email.rs new file mode 100644 index 000000000..8a993a0a4 --- /dev/null +++ b/crates/core/database/src/util/email.rs @@ -0,0 +1,271 @@ +use std::{collections::HashSet, sync::LazyLock}; + +use lettre::{ + transport::smtp::{authentication::Credentials, client::Tls}, + SmtpTransport, +}; +use regex::Regex; +use revolt_config::{config, ApiSmtp}; +use revolt_result::Result; + +static SPLIT: LazyLock = LazyLock::new(|| Regex::new("([^@]+)(@.+)").unwrap()); +static SYMBOL_RE: LazyLock = LazyLock::new(|| Regex::new("\\+.+|\\.").unwrap()); +static HANDLEBARS: LazyLock> = + LazyLock::new(handlebars::Handlebars::new); +static REVOLT_SOURCE_LIST: LazyLock> = LazyLock::new(|| { + include_str!("../../assets/revolt_source_list.txt") + .split('\n') + .map(|x| x.into()) + .collect() +}); + +/// Strip special characters and aliases from emails +pub fn normalise_email(original: String) -> String { + let split = SPLIT.captures(&original).unwrap(); + let mut clean = SYMBOL_RE + .replace_all(split.get(1).unwrap().as_str(), "") + .to_string(); + + clean.push_str(split.get(2).unwrap().as_str()); + clean.to_lowercase() +} + +/// Email template +#[derive(Clone)] +pub struct Template { + /// Title of the email + pub title: String, + /// Plain text version of this email + pub text: String, + /// HTML version of this email + pub html: Option, + /// URL to redirect people to from the email + /// + /// Use `{{url}}` to fill this field. + /// + /// Any given URL will be suffixed with a unique token if applicable. + /// + /// e.g. `https://example.com?t=` becomes `https://example.com?t=UNIQUE_CODE` + pub url: String, +} + +/// Email templates +#[derive(Clone)] +pub struct Templates { + /// Template for email verification + pub verify: Template, + /// Template for password reset + pub reset: Template, + /// Template for password reset when the account already exists on creation + pub reset_existing: Template, + /// Template for account deletion + pub deletion: Template, + /// Template for suspention + pub suspension: Template, +} + +pub async fn email_templates() -> Templates { + let config = config().await; + + if std::env::var("TEST_DB").is_ok() { + Templates { + verify: Template { + title: "verify".into(), + text: "[[{{url}}]]".into(), + url: "".into(), + html: None, + }, + reset: Template { + title: "reset".into(), + text: "[[{{url}}]]".into(), + url: "".into(), + html: None, + }, + reset_existing: Template { + title: "reset_existing".into(), + text: "[[{{url}}]]".into(), + url: "".into(), + html: None, + }, + deletion: Template { + title: "deletion".into(), + text: "[[{{url}}]]".into(), + url: "".into(), + html: None, + }, + suspension: Template { + title: "suspension".into(), + text: "[[dummy]]".into(), + url: "".into(), + html: None, + }, + } + } else if config.production { + Templates { + verify: Template { + title: "Verify your Stoat account.".into(), + text: include_str!("../../templates/verify.txt").into(), + url: format!("{}/login/verify/", config.hosts.app), + html: Some(include_str!("../../templates/verify.html").into()), + }, + reset: Template { + title: "Reset your Stoat password.".into(), + text: include_str!("../../templates/reset.txt").into(), + url: format!("{}/login/reset/", config.hosts.app), + html: Some(include_str!("../../templates/reset.html").into()), + }, + reset_existing: Template { + title: "You already have a Stoat account, reset your password.".into(), + text: include_str!("../../templates/reset-existing.txt").into(), + url: format!("{}/login/reset/", config.hosts.app), + html: Some(include_str!("../../templates/reset-existing.html").into()), + }, + deletion: Template { + title: "Confirm account deletion.".into(), + text: include_str!("../../templates/deletion.txt").into(), + url: format!("{}/delete/", config.hosts.app), + html: Some(include_str!("../../templates/deletion.html").into()), + }, + suspension: Template { + title: "Account Suspension".to_string(), + html: Some(include_str!("../../templates/suspension.html").to_owned()), + text: include_str!("../../templates/suspension.txt").to_owned(), + url: Default::default(), + }, + } + } else { + Templates { + verify: Template { + title: "Verify your account.".into(), + text: include_str!("../../templates/verify.whitelabel.txt").into(), + url: format!("{}/login/verify/", config.hosts.app), + html: None, + }, + reset: Template { + title: "Reset your password.".into(), + text: include_str!("../../templates/reset.whitelabel.txt").into(), + url: format!("{}/login/reset/", config.hosts.app), + html: None, + }, + reset_existing: Template { + title: "Reset your password.".into(), + text: include_str!("../../templates/reset.whitelabel.txt").into(), + url: format!("{}/login/reset/", config.hosts.app), + html: None, + }, + deletion: Template { + title: "Confirm account deletion.".into(), + text: include_str!("../../templates/deletion.whitelabel.txt").into(), + url: format!("{}/delete/", config.hosts.app), + html: None, + }, + suspension: Template { + title: "Account Suspension".to_string(), + text: include_str!("../../templates/suspension.whitelabel.txt").to_owned(), + url: Default::default(), + html: None, + }, + } + } +} + +/// Create SMTP transport +pub fn create_transport(smtp: &ApiSmtp) -> SmtpTransport { + let relay = if smtp.use_starttls == Some(true) { + SmtpTransport::starttls_relay(&smtp.host).unwrap() + } else { + SmtpTransport::relay(&smtp.host).unwrap() + }; + + let relay = if let Some(port) = smtp.port { + relay.port(port.try_into().unwrap()) + } else { + relay + }; + + let relay = if smtp.use_tls == Some(false) { + relay.tls(Tls::None) + } else { + relay + }; + + relay + .credentials(Credentials::new( + smtp.username.clone(), + smtp.password.clone(), + )) + .build() +} + +/// Render an email template +fn render_template(text: &str, variables: &handlebars::JsonValue) -> Result { + HANDLEBARS + .render_template(text, variables) + .map_err(|_| create_error!(RenderFail)) +} + +/// Send an email +pub fn send_email( + smtp: &ApiSmtp, + address: String, + template: &Template, + variables: handlebars::JsonValue, +) -> Result<()> { + let m = lettre::Message::builder() + .from(smtp.from_address.parse().expect("valid `smtp_from`")) + .to(address.parse().expect("valid `smtp_to`")) + .subject(template.title.clone()); + + let m = if let Some(reply_to) = &smtp.reply_to { + m.reply_to(reply_to.parse().expect("valid `smtp_reply_to`")) + } else { + m + }; + + let text = render_template(&template.text, &variables).expect("valid `template`"); + + let m = if let Some(html) = &template.html { + m.multipart(lettre::message::MultiPart::alternative_plain_html( + text, + render_template(html, &variables).expect("valid `template`"), + )) + } else { + m.body(text) + } + .expect("valid `message`"); + + use lettre::Transport; + let sender = create_transport(smtp); + + match sender.send(&m) { + Ok(_) => Ok(()), + Err(error) => { + error!( + "Failed to send email to {}!\nlettre error: {}", + address, error + ); + + revolt_config::capture_error(&error); + + Err(create_error!(EmailFailed)) + } + } +} + +pub fn validate_email(email: &str) -> Result<()> { + // Make sure this is an actual email + if !validator::validate_email(email) { + return Err(create_error!(IncorrectData { + with: "email".to_string() + })); + } + + // Check if the email is blacklisted + if let Some(domain) = email.split('@').next_back() { + if REVOLT_SOURCE_LIST.contains(&domain.to_string()) { + return Err(create_error!(Blacklisted)); + } + } + + Ok(()) +} diff --git a/crates/core/database/src/util/ip.rs b/crates/core/database/src/util/ip.rs new file mode 100644 index 000000000..e357b76a1 --- /dev/null +++ b/crates/core/database/src/util/ip.rs @@ -0,0 +1,56 @@ +#[cfg(feature = "rocket-impl")] +pub mod rocket { + use revolt_config::config; + use rocket::Request; + + pub fn to_ip(request: &'_ Request<'_>) -> String { + request + .client_ip() + .map(|x| x.to_string()) + .unwrap_or_default() + } + + /// Find the actual IP of the client + pub async fn to_real_ip(request: &'_ Request<'_>) -> String { + if config().await.api.security.trust_cloudflare { + request + .headers() + .get_one("CF-Connecting-IP") + .map(|x| x.to_string()) + .unwrap_or_else(|| to_ip(request)) + } else { + to_ip(request) + } + } +} + +#[cfg(feature = "axum-impl")] +pub mod axum { + use axum::{ + extract::ConnectInfo, + http::request::Parts, + }; + use revolt_config::config; + use std::net::SocketAddr; + + pub fn to_ip(parts: &Parts) -> String { + parts + .extensions + .get::>() + .map(|info| info.ip().to_string()) + .unwrap_or_default() + } + + /// Find the actual IP of the client + pub async fn to_real_ip(parts: &Parts) -> String { + if config().await.api.security.trust_cloudflare { + parts + .headers + .get("CF-Connecting-IP") + .map(|x| x.to_str().unwrap().to_string()) + .unwrap_or_else(|| to_ip(parts)) + } else { + to_ip(parts) + } + } +} diff --git a/crates/core/database/src/util/mod.rs b/crates/core/database/src/util/mod.rs index ae2817ac0..54cc4300f 100644 --- a/crates/core/database/src/util/mod.rs +++ b/crates/core/database/src/util/mod.rs @@ -1,10 +1,17 @@ pub mod acker; pub mod bridge; pub mod bulk_permissions; +pub mod captcha; +pub mod chunked; +pub mod email; mod funcs; pub mod idempotency; +pub mod ip; +pub mod password; pub mod permissions; pub mod reference; +pub mod shield; pub mod test_fixtures; pub use funcs::*; +pub use chunked::ChunkedDatabaseGenerator; \ No newline at end of file diff --git a/crates/core/database/src/util/password.rs b/crates/core/database/src/util/password.rs new file mode 100644 index 000000000..4f8297cb6 --- /dev/null +++ b/crates/core/database/src/util/password.rs @@ -0,0 +1,72 @@ +use reqwest::Client; +use sha1::Digest; +use std::{collections::HashSet, sync::LazyLock}; + +use revolt_config::config; +use revolt_result::{Result, ToRevoltError}; + +static CLIENT: LazyLock = LazyLock::new(Client::new); +static ARGON_CONFIG: LazyLock> = LazyLock::new(argon2::Config::default); +static TOP_100K_COMPROMISED: LazyLock> = LazyLock::new(|| { + include_str!("../../assets/pwned100k.txt") + .split('\n') + .map(|x| x.into()) + .collect() +}); + +#[derive(Deserialize)] +struct EasyPwnedResult { + secure: bool, +} + +/// Hash a password using argon2 +pub fn hash_password(plaintext_password: String) -> Result { + argon2::hash_encoded( + plaintext_password.as_bytes(), + nanoid::nanoid!(24).as_bytes(), + &ARGON_CONFIG, + ) + .to_internal_error() +} + +pub async fn assert_safe(password: &str) -> Result<()> { + // Make sure the password is long enough. + if password.len() < 8 { + return Err(create_error!(ShortPassword)); + } + + let config = config().await; + + if !config.api.security.easypwned.is_empty() { + let mut hasher = sha1::Sha1::new(); + hasher.update(password); + let pwd_hash = hasher.finalize(); + + let result = match CLIENT + .get(format!( + "{}/hash/{pwd_hash:#02x}", + &config.api.security.easypwned + )) + .send() + .await + { + Ok(response) => match response.json::().await { + Ok(result) => Ok(result.secure), + Err(e) => Err(e), + }, + Err(e) => Err(e), + }; + + if let Err(e) = &result { + revolt_config::capture_error(e); + } else if result.is_ok_and(|b| b) { + return Ok(()); + } + }; + + if TOP_100K_COMPROMISED.contains(password) { + return Err(create_error!(CompromisedPassword)); + }; + + Ok(()) +} diff --git a/crates/core/database/src/util/shield.rs b/crates/core/database/src/util/shield.rs new file mode 100644 index 000000000..4c6a79eba --- /dev/null +++ b/crates/core/database/src/util/shield.rs @@ -0,0 +1,118 @@ +use reqwest::Client; +use revolt_config::config; +use revolt_result::Result; +use serde::{Deserialize, Serialize}; +use std::{collections::HashMap, sync::LazyLock}; +use crate::util::ip; + +static CLIENT: LazyLock = LazyLock::new(Client::new); + +#[derive(Serialize, Deserialize, Default, Debug)] +pub struct ShieldValidationInput { + /// Remote user IP + pub ip: Option, + + /// User provided email + pub email: Option, + + /// Request headers + pub headers: Option>, + + /// Skip alerts and monitoring for this request + pub dry_run: bool, +} + +#[derive(Serialize, Deserialize)] +pub struct ValidationResult { + /// Whether this request was blocked + blocked: bool, + + /// Reasons for the request being blocked + reasons: Vec, +} + +pub async fn validate_shield(input: ShieldValidationInput) -> Result<()> { + let shield = config().await.api.security.shield; + + if !shield.host.is_empty() { + if let Ok(response) = CLIENT + .post(format!("{}/validate", &shield.host)) + .json(&input) + .header("Authorization", &shield.key) + .send() + .await + { + let result = response + .json::() + .await + .map_err(|_| create_error!(InternalError))?; + + if result.blocked { + return Err(create_error!(BlockedByShield)); + } + } + } + + Ok(()) +} + +#[cfg(feature = "rocket-impl")] +#[async_trait] +impl<'r> rocket::request::FromRequest<'r> for ShieldValidationInput { + type Error = revolt_result::Error; + + #[allow(clippy::collapsible_match)] + async fn from_request( + request: &'r rocket::Request<'_>, + ) -> rocket::request::Outcome { + rocket::request::Outcome::Success(ShieldValidationInput { + ip: Some(ip::rocket::to_real_ip(request).await), + headers: Some( + request + .headers() + .iter() + .map(|entry| (entry.name.to_string(), entry.value.to_string())) + .collect(), + ), + ..Default::default() + }) + } +} + +#[cfg(feature = "rocket-impl")] +impl<'r> revolt_rocket_okapi::request::OpenApiFromRequest<'r> for ShieldValidationInput { + fn from_request_input( + _gen: &mut revolt_rocket_okapi::r#gen::OpenApiGenerator, + _name: String, + _required: bool, + ) -> revolt_rocket_okapi::Result { + Ok(revolt_rocket_okapi::request::RequestHeaderInput::None) + } +} +#[cfg(feature = "axum-impl")] +#[async_trait] +impl axum::extract::FromRequestParts for ShieldValidationInput { + type Rejection = axum::Json ; + + async fn from_request_parts( + parts: &mut axum::http::request::Parts, + _state: &S, + ) -> Result { + Ok(ShieldValidationInput { + ip: Some(ip::axum::to_real_ip(parts).await), + headers: Some( + parts + .headers + .iter() + .map(|(name, value)| { + ( + name.to_string(), + value.to_str().map(|s| s.to_string()).unwrap_or_default(), + ) + }) + .collect(), + ), + ..Default::default() + }) + } +} diff --git a/crates/core/models/Cargo.toml b/crates/core/models/Cargo.toml index c92f3f8a2..cf453ece8 100644 --- a/crates/core/models/Cargo.toml +++ b/crates/core/models/Cargo.toml @@ -41,6 +41,7 @@ iso8601-timestamp = { workspace = true, features = ["schema", "bson"] } # Spec Generation schemars = { workspace = true, features = ["indexmap2"], optional = true } utoipa = { workspace = true, optional = true } +serde_json = { workspace = true } # Validation validator = { workspace = true, features = ["derive"], optional = true } diff --git a/crates/core/models/src/v0/accounts.rs b/crates/core/models/src/v0/accounts.rs new file mode 100644 index 000000000..ddf058650 --- /dev/null +++ b/crates/core/models/src/v0/accounts.rs @@ -0,0 +1,70 @@ +auto_derived!( + /// # Change Email Data + pub struct DataChangeEmail { + /// Valid email address + pub email: String, + /// Current password + pub current_password: String, + } + + /// # Change Data + pub struct DataChangePassword { + /// New password + pub password: String, + /// Current password + pub current_password: String, + } + + /// # Account Deletion Token + pub struct DataAccountDeletion { + /// Deletion token + pub token: String, + } + + /// # Account Data + pub struct DataCreateAccount { + /// Valid email address + pub email: String, + /// Password + pub password: String, + /// Invite code + pub invite: Option, + /// Captcha verification code + pub captcha: Option, + } + + pub struct AccountInfo { + #[serde(rename = "_id")] + pub id: String, + pub email: String, + } + + /// # Password Reset + pub struct DataPasswordReset { + /// Reset token + pub token: String, + + /// New password + pub password: String, + + /// Whether to logout all sessions + #[serde(default)] + pub remove_sessions: bool, + } + + /// # Resend Information + pub struct DataResendVerification { + /// Email associated with the account + pub email: String, + /// Captcha verification code + pub captcha: Option, + } + + /// # Reset Information + pub struct DataSendPasswordReset { + /// Email associated with the account + pub email: String, + /// Captcha verification code + pub captcha: Option, + } +); \ No newline at end of file diff --git a/crates/core/models/src/v0/mfa_tickets.rs b/crates/core/models/src/v0/mfa_tickets.rs new file mode 100644 index 000000000..f11cf08f4 --- /dev/null +++ b/crates/core/models/src/v0/mfa_tickets.rs @@ -0,0 +1,68 @@ +auto_derived!( + pub struct MFATicket { + /// Unique Id + #[serde(rename = "_id")] + pub id: String, + + /// Account Id + pub account_id: String, + + /// Unique Token + pub token: String, + + /// Whether this ticket has been validated + /// (can be used for account actions) + pub validated: bool, + + /// Whether this ticket is authorised + /// (can be used to log a user in) + pub authorised: bool, + + /// TOTP code at time of ticket creation + pub last_totp_code: Option, + } + + #[serde(untagged)] + pub enum ResponseVerify { + NoTicket, + WithTicket { + /// Authorised MFA ticket, can be used to log in + ticket: MFATicket, + }, + } + + /// MFA response + #[serde(untagged)] + pub enum MFAResponse { + Password { password: String }, + Recovery { recovery_code: String }, + Totp { totp_code: String }, + } + + #[derive(Default)] + pub struct MultiFactorStatus { + #[serde(skip_serializing_if = "crate::if_false", default)] + pub email_otp: bool, + #[serde(skip_serializing_if = "crate::if_false", default)] + pub trusted_handover: bool, + #[serde(skip_serializing_if = "crate::if_false", default)] + pub email_mfa: bool, + #[serde(skip_serializing_if = "crate::if_false", default)] + pub totp_mfa: bool, + #[serde(skip_serializing_if = "crate::if_false", default)] + pub security_key_mfa: bool, + #[serde(skip_serializing_if = "crate::if_false", default)] + pub recovery_active: bool, + } + + pub enum MFAMethod { + Password, + Recovery, + Totp, + } + + /// # Totp Secret + pub struct ResponseTotpSecret { + pub secret: String, + } +); \ No newline at end of file diff --git a/crates/core/models/src/v0/mod.rs b/crates/core/models/src/v0/mod.rs index 0468493b8..47e705070 100644 --- a/crates/core/models/src/v0/mod.rs +++ b/crates/core/models/src/v0/mod.rs @@ -14,6 +14,9 @@ mod server_members; mod servers; mod user_settings; mod users; +mod accounts; +mod mfa_tickets; +mod sessions; pub use bots::*; pub use channel_invites::*; @@ -31,3 +34,6 @@ pub use server_members::*; pub use servers::*; pub use user_settings::*; pub use users::*; +pub use accounts::*; +pub use mfa_tickets::*; +pub use sessions::*; \ No newline at end of file diff --git a/crates/core/models/src/v0/sessions.rs b/crates/core/models/src/v0/sessions.rs new file mode 100644 index 000000000..84ffc33a9 --- /dev/null +++ b/crates/core/models/src/v0/sessions.rs @@ -0,0 +1,88 @@ +use iso8601_timestamp::Timestamp; + +use crate::v0::{MFAMethod, MFAResponse}; + +auto_derived!( + pub struct Session { + /// Unique Id + #[serde(rename = "_id")] + pub id: String, + + /// User Id + pub user_id: String, + + /// Session token + pub token: String, + + /// Display name + pub name: String, + + /// When the session was last logged in + pub last_seen: Timestamp, + + /// Where the session is originating from + #[serde(skip_serializing_if = "Option::is_none")] + pub origin: Option, + + /// Web Push subscription + #[serde(skip_serializing_if = "Option::is_none")] + pub subscription: Option, + } + + /// Web Push subscription + pub struct WebPushSubscription { + pub endpoint: String, + pub p256dh: String, + pub auth: String, + } + + /// # Edit Data + pub struct DataEditSession { + /// Session friendly name + pub friendly_name: String, + } + + pub struct SessionInfo { + #[serde(rename = "_id")] + pub id: String, + pub name: String, + } + + /// # Login Data + #[serde(untagged)] + pub enum DataLogin { + Email { + /// Email + email: String, + /// Password + password: String, + /// Friendly name used for the session + friendly_name: Option, + }, + MFA { + /// Unvalidated or authorised MFA ticket + /// + /// Used to resolve the correct account + mfa_ticket: String, + /// Valid MFA response + /// + /// This will take precedence over the `password` field where applicable + mfa_response: Option, + /// Friendly name used for the session + friendly_name: Option, + }, + } + + #[serde(tag = "result")] + pub enum ResponseLogin { + Success(Session), + MFA { + ticket: String, + allowed_methods: Vec, + }, + Disabled { + user_id: String, + }, + } + +); \ No newline at end of file diff --git a/crates/core/ratelimits/Cargo.toml b/crates/core/ratelimits/Cargo.toml index e606d151f..440c3b8a4 100644 --- a/crates/core/ratelimits/Cargo.toml +++ b/crates/core/ratelimits/Cargo.toml @@ -28,7 +28,6 @@ revolt_rocket_okapi = { workspace = true, optional = true } axum = { workspace = true, optional = true, features = ["macros"] } serde = { workspace = true } -authifier = { workspace = true } dashmap = { workspace = true } async-trait = { workspace = true } log = { workspace = true } diff --git a/crates/core/ratelimits/src/axum.rs b/crates/core/ratelimits/src/axum.rs index f50cf8671..74556f25b 100644 --- a/crates/core/ratelimits/src/axum.rs +++ b/crates/core/ratelimits/src/axum.rs @@ -1,17 +1,14 @@ -use std::net::SocketAddr; - use async_trait::async_trait; use axum::{ Json, RequestPartsExt, Router, body::Body, - extract::{ConnectInfo, FromRef, FromRequestParts, State}, + extract::{FromRef, FromRequestParts, State}, http::{HeaderValue, Request, StatusCode, request::Parts}, middleware::Next, response::{IntoResponse, Response}, routing::get, }; -use revolt_database::{Database, User}; -use revolt_config::config; +use revolt_database::{Database, User, util::ip::axum::to_real_ip}; use crate::ratelimiter::{RatelimitInformation, Ratelimiter, RequestKind}; @@ -24,26 +21,6 @@ impl RequestKind for AxumRequestKind { pub type RatelimitStorage = crate::ratelimiter::RatelimitStorage; -fn to_ip(parts: &Parts) -> String { - parts - .extensions - .get::>() - .map(|info| info.ip().to_string()) - .unwrap_or_default() -} - -async fn to_real_ip(parts: &Parts) -> String { - if config().await.api.security.trust_cloudflare { - parts - .headers - .get("CF-Connecting-IP") - .map(|x| x.to_str().unwrap().to_string()) - .unwrap_or_else(|| to_ip(parts)) - } else { - to_ip(parts) - } -} - #[async_trait] impl FromRequestParts for Ratelimiter where diff --git a/crates/core/ratelimits/src/rocket.rs b/crates/core/ratelimits/src/rocket.rs index f790abb9f..a006f3c20 100644 --- a/crates/core/ratelimits/src/rocket.rs +++ b/crates/core/ratelimits/src/rocket.rs @@ -1,6 +1,5 @@ use async_trait::async_trait; use log::info; -use revolt_config::config; use rocket::fairing::{Fairing, Info, Kind}; use rocket::http::uri::Origin; use rocket::http::{Method, Status}; @@ -10,8 +9,7 @@ use rocket::{Data, Request, Response, State}; use revolt_rocket_okapi::r#gen::OpenApiGenerator; use revolt_rocket_okapi::request::{OpenApiFromRequest, RequestHeaderInput}; - -use authifier::models::Session; +use revolt_database::{Session, util::ip::rocket::to_real_ip}; use crate::ratelimiter::RequestKind; use crate::ratelimiter::{RatelimitInformation, Ratelimiter}; @@ -25,27 +23,6 @@ impl RequestKind for RocketRequestKind { pub type RatelimitStorage = crate::ratelimiter::RatelimitStorage; -/// Find the remote IP of the client -fn to_ip(request: &'_ rocket::Request<'_>) -> String { - request - .client_ip() - .map(|r| r.to_string()) - .unwrap_or_default() -} - -/// Find the actual IP of the client -async fn to_real_ip(request: &'_ rocket::Request<'_>) -> String { - if config().await.api.security.trust_cloudflare { - request - .headers() - .get_one("CF-Connecting-IP") - .map(|x| x.to_string()) - .unwrap_or_else(|| to_ip(request)) - } else { - to_ip(request) - } -} - #[async_trait] impl<'r> FromRequest<'r> for Ratelimiter { type Error = Ratelimiter; diff --git a/crates/core/result/src/axum.rs b/crates/core/result/src/axum.rs index 440c4fc4b..50df61502 100644 --- a/crates/core/result/src/axum.rs +++ b/crates/core/result/src/axum.rs @@ -1,4 +1,8 @@ -use axum::{http::StatusCode, response::IntoResponse, Json}; +use axum::{ + http::{header, StatusCode}, + response::IntoResponse, + Json, +}; use crate::{Error, ErrorType}; @@ -93,6 +97,29 @@ impl IntoResponse for Error { ErrorType::FileTypeNotAllowed => StatusCode::BAD_REQUEST, ErrorType::ImageProcessingFailed => StatusCode::INTERNAL_SERVER_ERROR, ErrorType::NoEmbedData => StatusCode::BAD_REQUEST, + ErrorType::RenderFail => StatusCode::INTERNAL_SERVER_ERROR, + ErrorType::MissingHeaders => StatusCode::BAD_REQUEST, + ErrorType::CaptchaFailed => StatusCode::BAD_REQUEST, + ErrorType::BlockedByShield => StatusCode::BAD_REQUEST, + ErrorType::UnverifiedAccount => StatusCode::FORBIDDEN, + ErrorType::EmailFailed => StatusCode::INTERNAL_SERVER_ERROR, + ErrorType::InvalidToken => StatusCode::UNAUTHORIZED, + ErrorType::MissingInvite => StatusCode::BAD_REQUEST, + ErrorType::InvalidInvite => StatusCode::BAD_REQUEST, + ErrorType::CompromisedPassword => StatusCode::BAD_REQUEST, + ErrorType::ShortPassword => StatusCode::BAD_REQUEST, + ErrorType::Blacklisted => { + return ( + StatusCode::UNAUTHORIZED, + [(header::CONTENT_TYPE, "application/json")], + "{\"type\":\"DisallowedContactSupport\", \"note\":\"If you see this messages right here, you're probably doing something you shouldn't be.\"}" + ).into_response() + } + ErrorType::LockedOut => StatusCode::FORBIDDEN, + ErrorType::TotpAlreadyEnabled => StatusCode::BAD_REQUEST, + ErrorType::DisallowedMFAMethod => StatusCode::BAD_REQUEST, + ErrorType::OperationFailed => StatusCode::INTERNAL_SERVER_ERROR, + ErrorType::IncorrectData { .. } => StatusCode::BAD_REQUEST, }; (status, Json(&self)).into_response() diff --git a/crates/core/result/src/lib.rs b/crates/core/result/src/lib.rs index 4124a0476..abf829b28 100644 --- a/crates/core/result/src/lib.rs +++ b/crates/core/result/src/lib.rs @@ -164,6 +164,10 @@ pub enum ErrorType { FailedValidation { error: String, }, + OperationFailed, + IncorrectData { + with: String, + }, // ? Voice errors LiveKitUnavailable, @@ -188,6 +192,25 @@ pub enum ErrorType { FeatureDisabled { feature: String, }, + + // ? Authentication + RenderFail, + MissingHeaders, + CaptchaFailed, + BlockedByShield, + UnverifiedAccount, + EmailFailed, + InvalidToken, + MissingInvite, + InvalidInvite, + + CompromisedPassword, + ShortPassword, + Blacklisted, + LockedOut, + + TotpAlreadyEnabled, + DisallowedMFAMethod, } #[macro_export] diff --git a/crates/core/result/src/rocket.rs b/crates/core/result/src/rocket.rs index 76719149a..796ae89df 100644 --- a/crates/core/result/src/rocket.rs +++ b/crates/core/result/src/rocket.rs @@ -99,6 +99,32 @@ impl<'r> Responder<'r, 'static> for Error { ErrorType::ImageProcessingFailed => Status::InternalServerError, ErrorType::NoEmbedData => Status::BadRequest, ErrorType::VosoUnavailable => Status::BadRequest, + + ErrorType::RenderFail => Status::InternalServerError, + ErrorType::MissingHeaders => Status::BadRequest, + ErrorType::CaptchaFailed => Status::BadRequest, + ErrorType::BlockedByShield => Status::BadRequest, + ErrorType::UnverifiedAccount => Status::Forbidden, + ErrorType::EmailFailed => Status::InternalServerError, + ErrorType::InvalidToken => Status::Unauthorized, + ErrorType::MissingInvite => Status::BadRequest, + ErrorType::InvalidInvite => Status::BadRequest, + ErrorType::CompromisedPassword => Status::BadRequest, + ErrorType::ShortPassword => Status::BadRequest, + ErrorType::Blacklisted => { + // Fail blacklisted email addresses. + const RESP: &str = "{\"type\":\"DisallowedContactSupport\", \"note\":\"If you see this messages right here, you're probably doing something you shouldn't be.\"}"; + + return Response::build() + .status(Status::Unauthorized) + .sized_body(RESP.len(), std::io::Cursor::new(RESP)) + .ok(); + } + ErrorType::LockedOut => Status::Forbidden, + ErrorType::TotpAlreadyEnabled => Status::BadRequest, + ErrorType::DisallowedMFAMethod => Status::BadRequest, + ErrorType::OperationFailed => Status::InternalServerError, + ErrorType::IncorrectData { .. } => Status::BadRequest, }; // Serialize the error data structure into JSON. diff --git a/crates/daemons/crond/Cargo.toml b/crates/daemons/crond/Cargo.toml index bb2f6ced7..5d0879ec4 100644 --- a/crates/daemons/crond/Cargo.toml +++ b/crates/daemons/crond/Cargo.toml @@ -15,6 +15,7 @@ log = { workspace = true } # Async tokio = { workspace = true } +futures = { workspace = true } # Redis redis-kiss = { workspace = true } diff --git a/crates/daemons/crond/src/main.rs b/crates/daemons/crond/src/main.rs index 2b9a82f65..af1ed7f2a 100644 --- a/crates/daemons/crond/src/main.rs +++ b/crates/daemons/crond/src/main.rs @@ -1,23 +1,51 @@ -use revolt_config::configure; -use revolt_database::{DatabaseInfo, AMQP}; +use std::{future::Future, panic::AssertUnwindSafe, time::Duration}; + +use futures::FutureExt; +use revolt_config::{capture_error, configure}; +use revolt_database::{Database, DatabaseInfo, AMQP}; use revolt_result::Result; -use tasks::{acks, file_deletion, prune_dangling_files, prune_members}; -use tokio::try_join; +use tasks::*; +use tokio::{join, time::sleep}; pub mod tasks; +pub async fn cron_task_wrapper>>( + func: fn(Database, AMQP) -> Fut, + db: Database, + amqp: AMQP, +) { + loop { + let wrapper = AssertUnwindSafe(func(db.clone(), amqp.clone())); + + match wrapper.catch_unwind().await { + Ok(Ok(())) => { + log::error!("cron unexpectedly finshed, Retrying after 60s"); + } + Ok(Err(error)) => { + log::error!("cron task failed unexpectedly: {error:?}\nRetrying after 60s"); + capture_error(&error); + } + _ => { + log::error!("cron task failed unexpectedly\nRetrying after 60s"); + } + } + + sleep(Duration::from_secs(60)).await; + } +} + #[tokio::main] -async fn main() -> Result<()> { +async fn main() { configure!(crond); let db = DatabaseInfo::Auto.connect().await.expect("database"); let amqp = AMQP::new_auto().await; - try_join!( - file_deletion::task(db.clone()), - prune_dangling_files::task(db.clone()), - prune_members::task(db.clone()), - acks::task(db.clone(), amqp.clone()), - ) - .map(|_| ()) + join!( + cron_task_wrapper(file_deletion::task, db.clone(), amqp.clone()), + cron_task_wrapper(prune_dangling_files::task, db.clone(), amqp.clone()), + cron_task_wrapper(prune_members::task, db.clone(), amqp.clone()), + cron_task_wrapper(delete_accounts::task, db.clone(), amqp.clone()), + cron_task_wrapper(acks::task, db.clone(), amqp.clone()), + ); } diff --git a/crates/daemons/crond/src/tasks/delete_accounts.rs b/crates/daemons/crond/src/tasks/delete_accounts.rs new file mode 100644 index 000000000..78cd1810e --- /dev/null +++ b/crates/daemons/crond/src/tasks/delete_accounts.rs @@ -0,0 +1,23 @@ +use std::time::Duration; + +use revolt_database::Database; +use revolt_result::Result; +use tokio::time::sleep; + +pub async fn task(db: Database, _: revolt_database::AMQP) -> Result<()> { + loop { + let accounts = db.fetch_accounts_due_for_deletion().await?; + let count = accounts.len(); + + for mut account in accounts { + let mut user = db.fetch_user(&account.id).await?; + + user.delete(&db).await?; + account.mark_deleted(&db).await?; + } + + log::info!("Deleted {count} accounts."); + + sleep(Duration::from_hours(1)).await + } +} diff --git a/crates/daemons/crond/src/tasks/file_deletion.rs b/crates/daemons/crond/src/tasks/file_deletion.rs index 42942bf35..3629e1895 100644 --- a/crates/daemons/crond/src/tasks/file_deletion.rs +++ b/crates/daemons/crond/src/tasks/file_deletion.rs @@ -6,21 +6,17 @@ use revolt_files::delete_from_s3; use revolt_result::Result; use tokio::time::sleep; -pub async fn task(db: Database) -> Result<()> { +pub async fn task(db: Database, _: revolt_database::AMQP) -> Result<()> { loop { let files = db.fetch_deleted_attachments().await?; for file in files { if let Some(hash) = &file.hash { - let count = db - .count_file_hash_references(hash) - .await?; + let count = db.count_file_hash_references(hash).await?; // No other files reference this file on disk anymore if count <= 1 { - let file_hash = db - .fetch_attachment_hash(hash) - .await?; + let file_hash = db.fetch_attachment_hash(hash).await?; // Delete from S3 delete_from_s3(&file_hash.bucket_id, &file_hash.path).await?; diff --git a/crates/daemons/crond/src/tasks/mod.rs b/crates/daemons/crond/src/tasks/mod.rs index a7dd9040c..a1216d0c6 100644 --- a/crates/daemons/crond/src/tasks/mod.rs +++ b/crates/daemons/crond/src/tasks/mod.rs @@ -1,4 +1,6 @@ +pub mod delete_accounts; pub mod acks; pub mod file_deletion; pub mod prune_dangling_files; pub mod prune_members; +pub mod prune_mfa_tickets; diff --git a/crates/daemons/crond/src/tasks/prune_dangling_files.rs b/crates/daemons/crond/src/tasks/prune_dangling_files.rs index be1eb6d6b..ad0fa56c1 100644 --- a/crates/daemons/crond/src/tasks/prune_dangling_files.rs +++ b/crates/daemons/crond/src/tasks/prune_dangling_files.rs @@ -6,7 +6,7 @@ use tokio::time::sleep; use log::info; -pub async fn task(db: Database) -> Result<()> { +pub async fn task(db: Database, _: revolt_database::AMQP) -> Result<()> { loop { // This could just be a single database query // ... but timestamps are inconsistently serialised diff --git a/crates/daemons/crond/src/tasks/prune_members.rs b/crates/daemons/crond/src/tasks/prune_members.rs index e21b7d732..658555672 100644 --- a/crates/daemons/crond/src/tasks/prune_members.rs +++ b/crates/daemons/crond/src/tasks/prune_members.rs @@ -5,7 +5,7 @@ use revolt_database::Database; use revolt_result::Result; use tokio::time::sleep; -pub async fn task(db: Database) -> Result<()> { +pub async fn task(db: Database, _: revolt_database::AMQP) -> Result<()> { loop { let success = db.remove_dangling_members().await; if let Err(s) = success { diff --git a/crates/daemons/crond/src/tasks/prune_mfa_tickets.rs b/crates/daemons/crond/src/tasks/prune_mfa_tickets.rs new file mode 100644 index 000000000..12dee62aa --- /dev/null +++ b/crates/daemons/crond/src/tasks/prune_mfa_tickets.rs @@ -0,0 +1,14 @@ +use std::time::Duration; + +use revolt_database::Database; +use revolt_result::Result; +use tokio::time::sleep; + +pub async fn task(db: Database) -> Result<()> { + loop { + let count = db.delete_expired_tickets().await?; + log::info!("Pruned {count} expired MFA tickets"); + + sleep(Duration::from_mins(5)).await + } +} diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index 9f38020ef..bc7d3e432 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -25,8 +25,6 @@ tokio = { workspace = true } async-trait = { workspace = true } ulid = { workspace = true } -authifier = { workspace = true } - log = { workspace = true } pretty_env_logger = { workspace = true } diff --git a/crates/daemons/pushd/src/consumers/inbound/ack.rs b/crates/daemons/pushd/src/consumers/inbound/ack.rs index 77df8b272..4c2730c7f 100644 --- a/crates/daemons/pushd/src/consumers/inbound/ack.rs +++ b/crates/daemons/pushd/src/consumers/inbound/ack.rs @@ -10,7 +10,6 @@ use revolt_database::{events::rabbit::*, Database}; #[allow(unused)] pub struct AckConsumer { db: Database, - authifier_db: authifier::Database, connection: Arc, channel: Arc, } @@ -19,13 +18,11 @@ pub struct AckConsumer { impl Consumer for AckConsumer { async fn create( db: Database, - authifier_db: authifier::Database, connection: Arc, channel: Arc, ) -> Self { Self { db, - authifier_db, connection, channel, } @@ -58,7 +55,7 @@ impl Consumer for AckConsumer { return Ok(()); }; - if let Ok(sessions) = self.authifier_db.find_sessions(&payload.user_id).await { + if let Ok(sessions) = self.db.fetch_sessions(&payload.user_id).await { let config = revolt_config::config().await; // Step 2: find any apple sessions, since we don't need to calculate this for anything else. // If there's no apple sessions, we can return early diff --git a/crates/daemons/pushd/src/consumers/inbound/dm_call.rs b/crates/daemons/pushd/src/consumers/inbound/dm_call.rs index 3175d8d8f..d22e04435 100644 --- a/crates/daemons/pushd/src/consumers/inbound/dm_call.rs +++ b/crates/daemons/pushd/src/consumers/inbound/dm_call.rs @@ -11,7 +11,6 @@ use revolt_database::{events::rabbit::*, Database}; #[allow(unused)] pub struct DmCallConsumer { db: Database, - authifier_db: authifier::Database, connection: Arc, channel: Arc, } @@ -20,13 +19,11 @@ pub struct DmCallConsumer { impl Consumer for DmCallConsumer { async fn create( db: Database, - authifier_db: authifier::Database, connection: Arc, channel: Arc, ) -> Self { Self { db, - authifier_db, connection, channel, } @@ -70,7 +67,7 @@ impl Consumer for DmCallConsumer { let config = revolt_config::config().await; for user_id in call_recipients { - if let Ok(sessions) = self.authifier_db.find_sessions(&user_id).await { + if let Ok(sessions) = self.db.fetch_sessions(&user_id).await { for session in sessions { if let Some(sub) = session.subscription { let mut sendable = PayloadToService { diff --git a/crates/daemons/pushd/src/consumers/inbound/fr_accepted.rs b/crates/daemons/pushd/src/consumers/inbound/fr_accepted.rs index bcfa1c2f0..d98057e9d 100644 --- a/crates/daemons/pushd/src/consumers/inbound/fr_accepted.rs +++ b/crates/daemons/pushd/src/consumers/inbound/fr_accepted.rs @@ -11,7 +11,6 @@ use revolt_database::{events::rabbit::*, Database}; #[allow(unused)] pub struct FRAcceptedConsumer { db: Database, - authifier_db: authifier::Database, connection: Arc, channel: Arc, } @@ -20,13 +19,11 @@ pub struct FRAcceptedConsumer { impl Consumer for FRAcceptedConsumer { async fn create( db: Database, - authifier_db: authifier::Database, connection: Arc, channel: Arc, ) -> Self { Self { db, - authifier_db, connection, channel, } @@ -42,7 +39,7 @@ impl Consumer for FRAcceptedConsumer { debug!("Received FR accept event"); - if let Ok(sessions) = self.authifier_db.find_sessions(&payload.user).await { + if let Ok(sessions) = self.db.fetch_sessions(&payload.user).await { let config = revolt_config::config().await; for session in sessions { if let Some(sub) = session.subscription { diff --git a/crates/daemons/pushd/src/consumers/inbound/fr_received.rs b/crates/daemons/pushd/src/consumers/inbound/fr_received.rs index 66fce72df..428aeb207 100644 --- a/crates/daemons/pushd/src/consumers/inbound/fr_received.rs +++ b/crates/daemons/pushd/src/consumers/inbound/fr_received.rs @@ -11,7 +11,6 @@ use revolt_database::{events::rabbit::*, Database}; #[allow(unused)] pub struct FRReceivedConsumer { db: Database, - authifier_db: authifier::Database, connection: Arc, channel: Arc, } @@ -20,13 +19,11 @@ pub struct FRReceivedConsumer { impl Consumer for FRReceivedConsumer { async fn create( db: Database, - authifier_db: authifier::Database, connection: Arc, channel: Arc, ) -> Self { Self { db, - authifier_db, connection, channel, } @@ -42,7 +39,7 @@ impl Consumer for FRReceivedConsumer { debug!("Received FR received event"); - if let Ok(sessions) = self.authifier_db.find_sessions(&payload.user).await { + if let Ok(sessions) = self.db.fetch_sessions(&payload.user).await { let config = revolt_config::config().await; for session in sessions { if let Some(sub) = session.subscription { diff --git a/crates/daemons/pushd/src/consumers/inbound/generic.rs b/crates/daemons/pushd/src/consumers/inbound/generic.rs index f413661d8..6a158c2a4 100644 --- a/crates/daemons/pushd/src/consumers/inbound/generic.rs +++ b/crates/daemons/pushd/src/consumers/inbound/generic.rs @@ -11,7 +11,6 @@ use revolt_database::{events::rabbit::*, Database}; #[allow(unused)] pub struct GenericConsumer { db: Database, - authifier_db: authifier::Database, connection: Arc, channel: Arc, } @@ -20,13 +19,11 @@ pub struct GenericConsumer { impl Consumer for GenericConsumer { async fn create( db: Database, - authifier_db: authifier::Database, connection: Arc, channel: Arc, ) -> Self { Self { db, - authifier_db, connection, channel, } @@ -43,8 +40,8 @@ impl Consumer for GenericConsumer { debug!("Received message event on origin"); if let Ok(sessions) = self - .authifier_db - .find_sessions_with_subscription(&payload.users) + .db + .fetch_sessions_with_subscription(&payload.users) .await { let config = revolt_config::config().await; diff --git a/crates/daemons/pushd/src/consumers/inbound/mass_mention.rs b/crates/daemons/pushd/src/consumers/inbound/mass_mention.rs index 55ab984f7..e0c71d995 100644 --- a/crates/daemons/pushd/src/consumers/inbound/mass_mention.rs +++ b/crates/daemons/pushd/src/consumers/inbound/mass_mention.rs @@ -19,7 +19,6 @@ use revolt_result::ToRevoltError; #[allow(unused)] pub struct MassMessageConsumer { db: Database, - authifier_db: authifier::Database, connection: Arc, channel: Arc, } @@ -31,8 +30,8 @@ impl MassMessageConsumer { users: &[String], ) -> Result<()> { if let Ok(sessions) = self - .authifier_db - .find_sessions_with_subscription(users) + .db + .fetch_sessions_with_subscription(users) .await { let config = revolt_config::config().await; @@ -75,13 +74,11 @@ impl MassMessageConsumer { impl Consumer for MassMessageConsumer { async fn create( db: Database, - authifier_db: authifier::Database, connection: Arc, channel: Arc, ) -> Self { Self { db, - authifier_db, connection, channel, } diff --git a/crates/daemons/pushd/src/consumers/inbound/message.rs b/crates/daemons/pushd/src/consumers/inbound/message.rs index e4aa04d5b..494bfbe5c 100644 --- a/crates/daemons/pushd/src/consumers/inbound/message.rs +++ b/crates/daemons/pushd/src/consumers/inbound/message.rs @@ -11,7 +11,6 @@ use revolt_database::{events::rabbit::*, Database}; #[allow(unused)] pub struct MessageConsumer { db: Database, - authifier_db: authifier::Database, connection: Arc, channel: Arc, } @@ -20,13 +19,11 @@ pub struct MessageConsumer { impl Consumer for MessageConsumer { async fn create( db: Database, - authifier_db: authifier::Database, connection: Arc, channel: Arc, ) -> Self { Self { db, - authifier_db, connection, channel, } @@ -48,8 +45,8 @@ impl Consumer for MessageConsumer { debug!("Received message event on origin"); if let Ok(sessions) = self - .authifier_db - .find_sessions_with_subscription(&payload.users) + .db + .fetch_sessions_with_subscription(&payload.users) .await { let config = revolt_config::config().await; diff --git a/crates/daemons/pushd/src/consumers/outbound/apn.rs b/crates/daemons/pushd/src/consumers/outbound/apn.rs index feb6cb94f..bf46d5bc1 100644 --- a/crates/daemons/pushd/src/consumers/outbound/apn.rs +++ b/crates/daemons/pushd/src/consumers/outbound/apn.rs @@ -80,7 +80,6 @@ impl<'a> PayloadLike for CallStartStopPayload<'a> { #[allow(unused)] pub struct ApnsOutboundConsumer { db: Database, - authifier_db: authifier::Database, connection: Arc, channel: Arc, client: Client, @@ -126,7 +125,6 @@ impl ApnsOutboundConsumer { impl Consumer for ApnsOutboundConsumer { async fn create( db: Database, - authifier_db: authifier::Database, connection: Arc, channel: Arc, ) -> Self { @@ -161,7 +159,6 @@ impl Consumer for ApnsOutboundConsumer { Self { db, - authifier_db, connection, channel, client, diff --git a/crates/daemons/pushd/src/consumers/outbound/fcm.rs b/crates/daemons/pushd/src/consumers/outbound/fcm.rs index e3bd185cf..7d05a9db4 100644 --- a/crates/daemons/pushd/src/consumers/outbound/fcm.rs +++ b/crates/daemons/pushd/src/consumers/outbound/fcm.rs @@ -119,7 +119,6 @@ impl NotificationData { #[allow(unused)] pub struct FcmOutboundConsumer { db: Database, - authifier_db: authifier::Database, connection: Arc, channel: Arc, client: Client, @@ -129,7 +128,6 @@ pub struct FcmOutboundConsumer { impl Consumer for FcmOutboundConsumer { async fn create( db: Database, - authifier_db: authifier::Database, connection: Arc, channel: Arc, ) -> Self { @@ -137,7 +135,6 @@ impl Consumer for FcmOutboundConsumer { Self { db, - authifier_db, connection, channel, client: Client::new( diff --git a/crates/daemons/pushd/src/consumers/outbound/vapid.rs b/crates/daemons/pushd/src/consumers/outbound/vapid.rs index 0acd8be9d..f91b995d6 100644 --- a/crates/daemons/pushd/src/consumers/outbound/vapid.rs +++ b/crates/daemons/pushd/src/consumers/outbound/vapid.rs @@ -19,7 +19,6 @@ use web_push::{ #[allow(unused)] pub struct VapidOutboundConsumer { db: Database, - authifier_db: authifier::Database, connection: Arc, channel: Arc, client: IsahcWebPushClient, @@ -30,7 +29,6 @@ pub struct VapidOutboundConsumer { impl Consumer for VapidOutboundConsumer { async fn create( db: Database, - authifier_db: authifier::Database, connection: Arc, channel: Arc, ) -> Self { @@ -48,7 +46,6 @@ impl Consumer for VapidOutboundConsumer { Self { db, - authifier_db, connection, channel, client: IsahcWebPushClient::new().unwrap(), diff --git a/crates/daemons/pushd/src/main.rs b/crates/daemons/pushd/src/main.rs index b4824b650..21d417a4b 100644 --- a/crates/daemons/pushd/src/main.rs +++ b/crates/daemons/pushd/src/main.rs @@ -32,17 +32,6 @@ async fn main() { // Setup database let db = revolt_database::DatabaseInfo::Auto.connect().await.unwrap(); - let authifier: authifier::Database; - - if let Some(client) = match &db { - revolt_database::Database::Reference(_) => None, - revolt_database::Database::MongoDb(mongo) => Some(mongo), - } { - authifier = - authifier::Database::MongoDb(authifier::database::MongoDb(client.database("revolt"))); - } else { - panic!("Mongo is not in use, can't connect via authifier!") - } let config = config().await; @@ -75,7 +64,6 @@ async fn main() { channels.push( make_queue_and_consume::( &db, - &authifier, &connection, &config, &config.pushd.generic_queue, @@ -88,7 +76,6 @@ async fn main() { channels.push( make_queue_and_consume::( &db, - &authifier, &connection, &config, &config.pushd.message_queue, @@ -101,7 +88,6 @@ async fn main() { channels.push( make_queue_and_consume::( &db, - &authifier, &connection, &config, &config.pushd.fr_received_queue, @@ -114,7 +100,6 @@ async fn main() { channels.push( make_queue_and_consume::( &db, - &authifier, &connection, &config, &config.pushd.fr_accepted_queue, @@ -127,7 +112,6 @@ async fn main() { channels.push( make_queue_and_consume::( &db, - &authifier, &connection, &config, &config.pushd.mass_mention_queue, @@ -140,7 +124,6 @@ async fn main() { channels.push( make_queue_and_consume::( &db, - &authifier, &connection, &config, &config.pushd.dm_call_queue, @@ -154,7 +137,6 @@ async fn main() { channels.push( make_queue_and_consume::( &db, - &authifier, &connection, &config, &config.pushd.apn.queue, @@ -170,7 +152,6 @@ async fn main() { channels.push( make_queue_and_consume::( &db, - &authifier, &connection, &config, &config.pushd.ack_queue, @@ -185,7 +166,6 @@ async fn main() { channels.push( make_queue_and_consume::( &db, - &authifier, &connection, &config, &config.pushd.fcm.queue, @@ -200,7 +180,6 @@ async fn main() { channels.push( make_queue_and_consume::( &db, - &authifier, &connection, &config, &config.pushd.vapid.queue, @@ -220,7 +199,6 @@ async fn main() { async fn make_queue_and_consume( db: &Database, - authifier_db: &authifier::Database, connection: &Arc, config: &Settings, queue_name: &str, @@ -300,7 +278,6 @@ where let delegate = Delegate( F::create( db.clone(), - authifier_db.clone(), connection.clone(), channel.clone(), ) diff --git a/crates/daemons/pushd/src/utils/consumer.rs b/crates/daemons/pushd/src/utils/consumer.rs index 9006aa32c..88f782c6f 100644 --- a/crates/daemons/pushd/src/utils/consumer.rs +++ b/crates/daemons/pushd/src/utils/consumer.rs @@ -18,7 +18,6 @@ use revolt_database::Database; pub trait Consumer: Clone + Send + Sync + 'static { async fn create( db: Database, - authifier_db: authifier::Database, connection: Arc, channel: Arc, ) -> Self; diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index 87028aba7..1bf3fb9e7 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -56,7 +56,6 @@ lettre = { workspace = true } rocket = { workspace = true, features = ["json"] } rocket_cors = { workspace = true } rocket_empty = { workspace = true, features = ["schema"] } -rocket_authifier = { workspace = true } rocket_prometheus = { workspace = true } # spec generation @@ -67,7 +66,6 @@ revolt_rocket_okapi = { workspace = true, features = ["swagger"] } lapin = { workspace = true, features = ["tokio"] } # core -authifier = { workspace = true } revolt-config = { workspace = true } revolt-database = { workspace = true, features = [ "rocket-impl", @@ -88,5 +86,8 @@ revolt-ratelimits = { workspace = true, features = ["rocket"] } livekit-api = { workspace = true } livekit-protocol = { workspace = true } +[dev-dependencies] +revolt-config = { workspace = true, features = ["test"] } + [build-dependencies] vergen = { workspace = true } diff --git a/crates/delta/src/main.rs b/crates/delta/src/main.rs index c1dd1dac0..4ebe941a0 100644 --- a/crates/delta/src/main.rs +++ b/crates/delta/src/main.rs @@ -9,7 +9,7 @@ pub mod routes; pub mod util; use revolt_config::config; -use revolt_database::{AMQP, events::client::EventV1}; +use revolt_database::AMQP; use revolt_ratelimits::rocket as ratelimiter; use rocket::{Build, Rocket}; use rocket_cors::{AllowedOrigins, CorsOptions}; @@ -17,8 +17,6 @@ use rocket_prometheus::PrometheusMetrics; use std::net::Ipv4Addr; use std::str::FromStr; -use async_std::channel::unbounded; -use authifier::AuthifierEvent; use revolt_database::voice::VoiceClient; use rocket::data::ToByteUnit; @@ -33,28 +31,6 @@ pub async fn web() -> Rocket { let db = revolt_database::DatabaseInfo::Auto.connect().await.unwrap(); db.migrate_database().await.unwrap(); - // Setup Authifier event channel - let (_, receiver) = unbounded(); - - // Setup Authifier - let authifier = db.clone().to_authifier().await; - - // Launch a listener for Authifier events - async_std::task::spawn(async move { - while let Ok(event) = receiver.recv().await { - match &event { - AuthifierEvent::CreateSession { .. } | AuthifierEvent::CreateAccount { .. } => { - EventV1::Auth(event).global().await - } - AuthifierEvent::DeleteSession { user_id, .. } - | AuthifierEvent::DeleteAllSessions { user_id, .. } => { - let id = user_id.to_string(); - EventV1::Auth(event).private(id).await - } - } - } - }); - // Configure CORS let cors = CorsOptions { allowed_origins: AllowedOrigins::All, @@ -109,7 +85,6 @@ pub async fn web() -> Rocket { .mount("/", rocket_cors::catch_all_options_routes()) .mount("/", ratelimiter::routes()) .mount("/swagger/", swagger) - .manage(authifier) .manage(db) .manage(amqp) .manage(cors.clone()) diff --git a/crates/delta/src/routes/account/change_email.rs b/crates/delta/src/routes/account/change_email.rs new file mode 100644 index 000000000..88a310b69 --- /dev/null +++ b/crates/delta/src/routes/account/change_email.rs @@ -0,0 +1,187 @@ +//! Change account email. +//! PATCH /account/change/email +use revolt_database::util::email::validate_email; +use revolt_database::{Account, Database, ValidatedTicket}; +use revolt_models::v0; +use rocket::serde::json::Json; +use rocket::State; +use rocket_empty::EmptyResponse; +use revolt_result::{Result, create_error}; + +/// # Change Email +/// +/// Change the associated account email. +#[openapi(tag = "Account")] +#[patch("/change/email", data = "")] +pub async fn change_email( + db: &State, + validated_ticket: Option, + mut account: Account, + data: Json, +) -> Result { + let data = data.into_inner(); + + validate_email(&data.email)?; + + if account.mfa.is_active() && validated_ticket.is_none() { + return Err(create_error!(InvalidCredentials)); + } + + // Ensure given password is correct + account.verify_password(&data.current_password)?; + + // Send email verification for new email + account + .start_email_move(db, data.email) + .await + .map(|_| EmptyResponse) +} + +#[cfg(test)] +mod tests { + use crate::{rocket, util::test::TestHarness}; + use revolt_config::overwrite_config; + use revolt_database::{MFATicket, Totp}; + use revolt_models::v0; + use rocket::http::{ContentType, Header, Status}; + + #[rocket::async_test] + async fn success() { + overwrite_config(|config| config.api.smtp.host = "".to_string()).await; + + let harness = TestHarness::new().await; + let (account, session, _) = harness.new_user().await; + + let res = harness.client + .patch("/auth/account/change/email") + .header(ContentType::JSON) + .header(Header::new("X-Session-Token", session.token.clone())) + .body( + json!({ + "email": "validexample@valid.com", + "current_password": "password_insecure" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::NoContent); + + let account = harness.db.fetch_account(&account.id).await.unwrap(); + + assert_eq!(account.email, "validexample@valid.com"); + } + + #[rocket::async_test] + async fn success_smtp() { + let harness = TestHarness::new().await; + let (account, session, _) = harness.new_user().await; + + let res = harness.client + .patch("/auth/account/change/email") + .header(ContentType::JSON) + .header(Header::new("X-Session-Token", session.token.clone())) + .body( + json!({ + "email": "change_email@smtp.test", + "current_password": "password_insecure" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::NoContent); + + let account = harness.db.fetch_account(&account.id).await.unwrap(); + + let (_, code) = harness.assert_email("change_email@smtp.test").await; + let res = harness.client + .post(format!("/auth/account/verify/{}", code)) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Ok); + + let account = harness.db.fetch_account(&account.id).await.unwrap(); + + assert_eq!(account.email, "change_email@smtp.test"); + + // Ensure that we did not receive a ticket + assert_eq!( + v0::ResponseVerify::NoTicket, + res.into_json().await.expect("`ResponseVerify") + ) + } + + #[rocket::async_test] + async fn success_mfa() { + overwrite_config(|config| config.api.smtp.host = "".to_string()).await; + + let harness = TestHarness::new().await; + let (mut account, session, _) = harness.new_user().await; + + let totp = Totp::Enabled { + secret: "secret".to_string(), + }; + + account.mfa.totp_token = totp.clone(); + account.save(&harness.db).await.unwrap(); + + let ticket = MFATicket::new(account.id.to_string(), true); + ticket.save(&harness.db).await.unwrap(); + + let res = harness.client + .patch("/auth/account/change/email") + .header(ContentType::JSON) + .header(Header::new("X-Session-Token", session.token.clone())) + .header(Header::new("X-MFA-Ticket", ticket.token)) + .body( + json!({ + "email": "validexample@valid.com", + "current_password": "password_insecure" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::NoContent); + + let account = harness.db.fetch_account(&account.id).await.unwrap(); + + assert_eq!(account.email, "validexample@valid.com"); + } + + #[rocket::async_test] + async fn fail_mfa() { + overwrite_config(|config| config.api.smtp.host = "".to_string()).await; + + let harness = TestHarness::new().await; + let (mut account, session, _) = harness.new_user().await; + + let totp = Totp::Enabled { + secret: "secret".to_string(), + }; + + account.mfa.totp_token = totp.clone(); + account.save(&harness.db).await.unwrap(); + + let res = harness.client + .patch("/auth/account/change/email") + .header(ContentType::JSON) + .header(Header::new("X-Session-Token", session.token.clone())) + .body( + json!({ + "email": "validexample@valid.com", + "current_password": "password_insecure" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Unauthorized); + } +} diff --git a/crates/delta/src/routes/account/change_password.rs b/crates/delta/src/routes/account/change_password.rs new file mode 100644 index 000000000..f963347e0 --- /dev/null +++ b/crates/delta/src/routes/account/change_password.rs @@ -0,0 +1,187 @@ +//! Change account password. +//! PATCH /account/change/password +use revolt_database::{ + util::password::{assert_safe, hash_password}, + Account, Database, ValidatedTicket, +}; +use revolt_models::v0; +use revolt_result::{create_error, Result}; +use rocket::serde::json::Json; +use rocket::State; +use rocket_empty::EmptyResponse; + +/// # Change Password +/// +/// Change the current account password. +#[openapi(tag = "Account")] +#[patch("/change/password", data = "")] +pub async fn change_password( + db: &State, + validated_ticket: Option, + mut account: Account, + data: Json, +) -> Result { + let data = data.into_inner(); + + if account.mfa.is_active() && validated_ticket.is_none() { + return Err(create_error!(InvalidCredentials)); + } + + // Verify password can be used + assert_safe(&data.password).await?; + + // Ensure given password is correct + account.verify_password(&data.current_password)?; + + // Hash and replace password + account.password = hash_password(data.password)?; + + // Commit to database + account.save(db).await.map(|_| EmptyResponse) +} + +#[cfg(test)] +mod tests { + use crate::{rocket, util::test::TestHarness}; + use revolt_database::{MFATicket, Totp}; + use rocket::http::{ContentType, Header, Status}; + + #[rocket::async_test] + async fn success() { + let harness = TestHarness::new().await; + let (_, session, _) = harness.new_user().await; + + let res = harness + .client + .patch("/auth/account/change/password") + .header(ContentType::JSON) + .header(Header::new("X-Session-Token", session.token.clone())) + .body( + json!({ + "password": "new password", + "current_password": "password_insecure" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::NoContent); + + let res = harness + .client + .patch("/auth/account/change/password") + .header(ContentType::JSON) + .header(Header::new("X-Session-Token", session.token)) + .body( + json!({ + "password": "sussy password", + "current_password": "new password" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::NoContent); + } + + #[rocket::async_test] + async fn success_mfa() { + let harness = TestHarness::new().await; + let (mut account, session, _) = harness.new_user().await; + + let totp = Totp::Enabled { + secret: "secret".to_string(), + }; + + account.mfa.totp_token = totp.clone(); + account.save(&harness.db).await.unwrap(); + + let ticket = MFATicket::new(account.id.to_string(), true); + ticket.save(&harness.db).await.unwrap(); + + let res = harness + .client + .patch("/auth/account/change/password") + .header(ContentType::JSON) + .header(Header::new("X-Session-Token", session.token.clone())) + .header(Header::new("X-MFA-Ticket", ticket.token)) + .body( + json!({ + "password": "new password", + "current_password": "password_insecure" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::NoContent); + } + + #[rocket::async_test] + async fn fail_mfa_no_ticket() { + let harness = TestHarness::new().await; + let (mut account, session, _) = harness.new_user().await; + + let totp = Totp::Enabled { + secret: "secret".to_string(), + }; + + account.mfa.totp_token = totp.clone(); + account.save(&harness.db).await.unwrap(); + + let res = harness + .client + .patch("/auth/account/change/password") + .header(ContentType::JSON) + .header(Header::new("X-Session-Token", session.token.clone())) + .body( + json!({ + "password": "new password", + "current_password": "password_insecure" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Unauthorized); + } + + #[rocket::async_test] + async fn fail_mfa_invalid_password() { + let harness = TestHarness::new().await; + let (mut account, session, _) = harness.new_user().await; + + let totp = Totp::Enabled { + secret: "secret".to_string(), + }; + + account.mfa.totp_token = totp.clone(); + account.save(&harness.db).await.unwrap(); + + let mut ticket = MFATicket::new(account.id.to_string(), true); + ticket.last_totp_code = Some("token from earlier".into()); + ticket.save(&harness.db).await.unwrap(); + + let res = harness + .client + .patch("/auth/account/change/password") + .header(ContentType::JSON) + .header(Header::new("X-Session-Token", session.token.clone())) + .header(Header::new("X-MFA-Ticket", ticket.token)) + .body( + json!({ + "password": "new password", + "current_password": "incorrect password" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Unauthorized); + } +} diff --git a/crates/delta/src/routes/account/confirm_deletion.rs b/crates/delta/src/routes/account/confirm_deletion.rs new file mode 100644 index 000000000..5d5304844 --- /dev/null +++ b/crates/delta/src/routes/account/confirm_deletion.rs @@ -0,0 +1,59 @@ +//! Confirm an account deletion. +//! PUT /account/delete +use revolt_database::Database; +use revolt_models::v0; +use revolt_result::Result; +use rocket::serde::json::Json; +use rocket::State; +use rocket_empty::EmptyResponse; + +/// # Confirm Account Deletion +/// +/// Schedule an account for deletion by confirming the received token. +#[openapi(tag = "Account")] +#[put("/delete", data = "")] +pub async fn confirm_deletion( + db: &State, + data: Json, +) -> Result { + let data = data.into_inner(); + + // Find the relevant account + let mut account = db.fetch_account_with_deletion_token(&data.token).await?; + + // Schedule the account for deletion + account.schedule_deletion(db).await.map(|_| EmptyResponse) +} + +#[cfg(test)] +mod tests { + use crate::{rocket, util::test::TestHarness}; + use iso8601_timestamp::{Duration, Timestamp}; + use revolt_database::DeletionInfo; + use revolt_models::v0; + use rocket::http::Status; + + #[rocket::async_test] + async fn success() { + let harness = TestHarness::new().await; + let (mut account, _, _) = harness.new_user().await; + + account.deletion = Some(DeletionInfo::WaitingForVerification { + token: "token".to_string(), + expiry: Timestamp::now_utc() + Duration::seconds(100), + }); + + account.save(&harness.db).await.unwrap(); + + let res = harness + .client + .put("/auth/account/delete") + .json(&v0::DataAccountDeletion { + token: "token".to_string(), + }) + .dispatch() + .await; + + assert_eq!(res.status(), Status::NoContent); + } +} diff --git a/crates/delta/src/routes/account/create_account.rs b/crates/delta/src/routes/account/create_account.rs new file mode 100644 index 000000000..019a6adcc --- /dev/null +++ b/crates/delta/src/routes/account/create_account.rs @@ -0,0 +1,347 @@ +//! Create a new account +//! POST /account/create +use std::time::Duration; + +use async_std::task::sleep; +use revolt_config::config; +use revolt_database::{ + util::{ + captcha::check_captcha, + email::validate_email, + password::assert_safe, + shield::{validate_shield, ShieldValidationInput}, + }, + Account, Database, +}; +use revolt_models::v0; +use revolt_result::{create_error, Result}; +use rocket::serde::json::Json; +use rocket::State; +use rocket_empty::EmptyResponse; + +/// # Create Account +/// +/// Create a new account. +#[openapi(tag = "Account")] +#[post("/create", data = "")] +pub async fn create_account( + db: &State, + data: Json, + mut shield: ShieldValidationInput, +) -> Result { + let data = data.into_inner(); + + // Random jitter from 0-1000ms + sleep(Duration::from_millis((rand::random::() * 1000.) as u64)).await; + + // Check Captcha token + check_captcha(data.captcha.as_deref()).await?; + + // Validate the request + shield.email = Some(data.email.to_string()); + validate_shield(shield).await?; + + // Make sure email is valid and not blocked + validate_email(&data.email)?; + + // Ensure password is safe to use + assert_safe(&data.password).await?; + + // If required, fetch valid invite + let invite = if config().await.api.registration.invite_only { + if let Some(invite) = data.invite { + Some(db.fetch_account_invite(&invite).await?) + } else { + return Err(create_error!(MissingInvite)); + } + } else { + None + }; + + // Create account + let account = Account::new(db, data.email, data.password, true).await?; + + // Use up the invite + if let Some(mut invite) = invite { + invite.claimed_by = Some(account.id); + invite.used = true; + + db.save_account_invite(&invite).await?; + } + + Ok(EmptyResponse) +} + +#[cfg(test)] +mod tests { + use crate::{rocket, util::test::TestHarness}; + use revolt_config::overwrite_config; + use revolt_database::{events::client::EventV1, AccountInvite}; + use revolt_result::{Error, ErrorType}; + use rocket::http::{ContentType, Status}; + + #[rocket::async_test] + async fn success() { + let mut harness = TestHarness::new().await; + + let res = harness + .client + .post("/auth/account/create") + .header(ContentType::JSON) + .body( + json!({ + "email": "success@validemail.com", + "password": "valid password" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::NoContent); + drop(res); + + harness + .wait_for_event("global", |e| matches!(e, EventV1::CreateAccount { .. })) + .await; + } + + #[rocket::async_test] + async fn fail_invalid_email() { + let harness = TestHarness::new().await; + + let res = harness + .client + .post("/auth/account/create") + .header(ContentType::JSON) + .body( + json!({ + "email": "invalid", + "password": "valid password" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::BadRequest); + assert!(matches!( + res.into_json::().await.unwrap().error_type, + ErrorType::IncorrectData { .. }, + )); + } + + #[rocket::async_test] + async fn fail_invalid_password() { + let harness = TestHarness::new().await; + + let res = harness + .client + .post("/auth/account/create") + .header(ContentType::JSON) + .body( + json!({ + "email": "fail_invalid_password@validemail.com", + "password": "password" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::BadRequest); + assert!(matches!( + res.into_json::().await.unwrap().error_type, + ErrorType::CompromisedPassword, + )); + } + + #[rocket::async_test] + async fn fail_invalid_invite() { + overwrite_config(|config| config.api.registration.invite_only = true).await; + + let harness = TestHarness::new().await; + + let res = harness + .client + .post("/auth/account/create") + .header(ContentType::JSON) + .body( + json!({ + "email": "fail_invalid_invite@validemail.com", + "password": "valid password", + "invite": "invalid" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::BadRequest); + assert!(matches!( + res.into_json::().await.unwrap().error_type, + ErrorType::InvalidInvite, + )); + } + + #[rocket::async_test] + async fn success_valid_invite() { + overwrite_config(|config| config.api.registration.invite_only = true).await; + + let harness = TestHarness::new().await; + + let invite = AccountInvite { + id: "invite".to_string(), + used: false, + claimed_by: None, + }; + + invite.save(&harness.db).await.unwrap(); + + let res = harness + .client + .post("/auth/account/create") + .header(ContentType::JSON) + .body( + json!({ + "email": "success_valid_invite@validemail.com", + "password": "valid password", + "invite": "invite" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::NoContent); + + let invite = harness + .db + .fetch_account_invite("invite") + .await + .expect("`Invite`"); + + assert!(invite.used); + } + + #[rocket::async_test] + async fn fail_missing_captcha() { + overwrite_config(|config| { + config.api.security.captcha.hcaptcha_key = + "0x0000000000000000000000000000000000000000".to_string() + }) + .await; + + let harness = TestHarness::new().await; + + let res = harness + .client + .post("/auth/account/create") + .header(ContentType::JSON) + .body( + json!({ + "email": "fail_missing_captcha@validemail.com", + "password": "valid password", + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::BadRequest); + assert!(matches!( + res.into_json::().await.unwrap().error_type, + ErrorType::CaptchaFailed, + )); + } + + #[rocket::async_test] + async fn fail_captcha_invalid() { + overwrite_config(|config| { + config.api.security.captcha.hcaptcha_key = + "0x0000000000000000000000000000000000000000".to_string() + }) + .await; + + let harness = TestHarness::new().await; + + let res = harness + .client + .post("/auth/account/create") + .header(ContentType::JSON) + .body( + json!({ + "email": "fail_captcha_invalid@validemail.com", + "password": "valid password", + "captcha": "00000000-aaaa-bbbb-cccc-000000000000" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::BadRequest); + assert!(matches!( + res.into_json::().await.unwrap().error_type, + ErrorType::CaptchaFailed, + )); + } + + #[rocket::async_test] + async fn success_captcha_valid() { + overwrite_config(|config| { + config.api.security.captcha.hcaptcha_key = + "0x0000000000000000000000000000000000000000".to_string() + }) + .await; + + let harness = TestHarness::new().await; + + let res = harness + .client + .post("/auth/account/create") + .header(ContentType::JSON) + .body( + json!({ + "email": "success_captcha_valid@validemail.com", + "password": "valid password", + "captcha": "20000000-aaaa-bbbb-cccc-000000000002" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::NoContent); + } + + #[rocket::async_test] + async fn success_smtp_sent() { + let harness = TestHarness::new().await; + + let res = harness + .client + .post("/auth/account/create") + .header(ContentType::JSON) + .body( + json!({ + "email": "success_smtp_sent@smtp.test", + "password": "valid password", + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::NoContent); + + let (_, code) = harness.assert_email("success_smtp_sent@smtp.test").await; + let res = harness + .client + .post(format!("/auth/account/verify/{code}")) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Ok); + } +} diff --git a/crates/delta/src/routes/account/delete_account.rs b/crates/delta/src/routes/account/delete_account.rs new file mode 100644 index 000000000..755f60fbf --- /dev/null +++ b/crates/delta/src/routes/account/delete_account.rs @@ -0,0 +1,64 @@ +//! Delete an account. +//! POST /account/delete +use rocket::State; +use rocket_empty::EmptyResponse; +use revolt_result::Result; +use revolt_database::{Database, Account, ValidatedTicket}; +/// # Delete Account +/// +/// Request to have an account deleted. +#[openapi(tag = "Account")] +#[post("/delete")] +pub async fn delete_account( + db: &State, + mut account: Account, + _ticket: ValidatedTicket, +) -> Result { + account + .start_account_deletion(db) + .await + .map(|_| EmptyResponse) +} + +#[cfg(test)] +mod tests { + use crate::{rocket, util::test::TestHarness}; + use revolt_database::MFATicket; + use rocket::http::{ContentType, Header, Status}; + + #[rocket::async_test] + async fn success() { + let harness = TestHarness::new().await; + let (mut account, session, _) = harness.new_user().await; + + account.email = "delete_account@smtp.test".to_string(); + account.save(&harness.db).await.unwrap(); + + let ticket = MFATicket::new(account.id.to_string(), true); + ticket.save(&harness.db).await.unwrap(); + + let res = harness.client + .post("/auth/account/delete") + .header(Header::new("X-Session-Token", session.token)) + .header(Header::new("X-MFA-Ticket", ticket.token)) + .dispatch() + .await; + + assert_eq!(res.status(), Status::NoContent); + + let (_, code) = harness.assert_email("delete_account@smtp.test").await; + let res = harness.client + .put("/auth/account/delete") + .header(ContentType::JSON) + .body( + json!({ + "token": code + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::NoContent); + } +} diff --git a/crates/delta/src/routes/account/disable_account.rs b/crates/delta/src/routes/account/disable_account.rs new file mode 100644 index 000000000..d8a5eff7b --- /dev/null +++ b/crates/delta/src/routes/account/disable_account.rs @@ -0,0 +1,67 @@ +//! Disable an account. +//! POST /account/disable +use revolt_result::Result; +use revolt_database::{Database, Account, ValidatedTicket}; +use rocket::State; +use rocket_empty::EmptyResponse; + +/// # Disable Account +/// +/// Disable an account. +#[openapi(tag = "Account")] +#[post("/disable")] +pub async fn disable_account( + db: &State, + mut account: Account, + _ticket: ValidatedTicket, +) -> Result { + account.disable(db).await.map(|_| EmptyResponse) +} + +#[cfg(test)] +mod tests { + use crate::{rocket, util::test::TestHarness}; + use revolt_database::{MFATicket, events::client::EventV1}; + use revolt_result::ErrorType; + use rocket::http::{Header, Status}; + + #[rocket::async_test] + async fn success() { + let mut harness = TestHarness::new().await; + let (account, session, _) = harness.new_user().await; + + let ticket = MFATicket::new(account.id.to_string(), true); + ticket.save(&harness.db).await.unwrap(); + + let res = harness.client + .post("/auth/account/disable") + .header(Header::new("X-Session-Token", session.token.clone())) + .header(Header::new("X-MFA-Ticket", ticket.token)) + .dispatch() + .await; + + assert_eq!(res.status(), Status::NoContent); + drop(res); + assert!( + harness.db + .fetch_account(&account.id) + .await + .unwrap() + .disabled + ); + + assert!(matches!( + harness.db + .fetch_session(&session.id) + .await + .unwrap_err().error_type, + ErrorType::UnknownUser + )); + + harness.wait_for_event(&format!("{}!", &account.id), |e| if let EventV1::DeleteAllSessions { user_id, .. } = e { + user_id == &account.id + } else { + false + }).await; + } +} diff --git a/crates/delta/src/routes/account/fetch_account.rs b/crates/delta/src/routes/account/fetch_account.rs new file mode 100644 index 000000000..41c51ec7b --- /dev/null +++ b/crates/delta/src/routes/account/fetch_account.rs @@ -0,0 +1,40 @@ +//! Fetch your account +//! GET /account +use revolt_database::Account; +use rocket::serde::json::Json; +use revolt_models::v0; +use revolt_result::Result; + +/// # Fetch Account +/// +/// Fetch account information from the current session. +#[openapi(tag = "Account")] +#[get("/")] +pub async fn fetch_account(account: Account) -> Result> { + Ok(Json(account.into())) +} + +#[cfg(test)] +mod tests { + use crate::{rocket, util::test::TestHarness}; + use revolt_models::v0; + use rocket::http::{Header, Status}; + + #[rocket::async_test] + async fn success() { + let harness = TestHarness::new().await; + let (account, session, _) = harness.new_user().await; + + let res = harness.client + .get("/auth/account") + .header(Header::new("X-Session-Token", session.token)) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Ok); + assert_eq!( + &res.into_json::().await.unwrap().id, + &account.id + ); + } +} diff --git a/crates/delta/src/routes/account/mod.rs b/crates/delta/src/routes/account/mod.rs new file mode 100644 index 000000000..19d108727 --- /dev/null +++ b/crates/delta/src/routes/account/mod.rs @@ -0,0 +1,30 @@ +use rocket::Route; +use revolt_rocket_okapi::revolt_okapi::openapi3::OpenApi; + +pub mod change_email; +pub mod change_password; +pub mod confirm_deletion; +pub mod create_account; +pub mod delete_account; +pub mod disable_account; +pub mod fetch_account; +pub mod password_reset; +pub mod resend_verification; +pub mod send_password_reset; +pub mod verify_email; + +pub fn routes() -> (Vec, OpenApi) { + openapi_get_routes_spec![ + create_account::create_account, + resend_verification::resend_verification, + confirm_deletion::confirm_deletion, + fetch_account::fetch_account, + delete_account::delete_account, + disable_account::disable_account, + change_password::change_password, + change_email::change_email, + verify_email::verify_email, + password_reset::password_reset, + send_password_reset::send_password_reset + ] +} diff --git a/crates/delta/src/routes/account/password_reset.rs b/crates/delta/src/routes/account/password_reset.rs new file mode 100644 index 000000000..6ad981537 --- /dev/null +++ b/crates/delta/src/routes/account/password_reset.rs @@ -0,0 +1,140 @@ +//! Confirm a password reset. +//! PATCH /account/reset_password +use rocket::serde::json::Json; +use rocket::State; +use rocket_empty::EmptyResponse; +use revolt_database::util::password::{hash_password, assert_safe}; +use revolt_database::{Database}; +use revolt_models::v0; +use revolt_result::Result; + +/// # Password Reset +/// +/// Confirm password reset and change the password. +#[openapi(tag = "Account")] +#[patch("/reset_password", data = "")] +pub async fn password_reset( + db: &State, + data: Json, +) -> Result { + let data = data.into_inner(); + + // Find the relevant account + let mut account = db + .fetch_account_with_password_reset(&data.token) + .await?; + + // Verify password can be used + assert_safe(&data.password) + .await?; + + // Update the account + account.password = hash_password(data.password)?; + account.password_reset = None; + account.lockout = None; + + // Commit to database + account.save(db).await?; + + // Delete all sessions if required + if data.remove_sessions { + account.delete_all_sessions(db, None).await?; + } + + Ok(EmptyResponse) +} + +#[cfg(test)] +mod tests { + use iso8601_timestamp::{Timestamp, Duration}; + use revolt_database::PasswordReset; + use revolt_models::v0; + use revolt_result::{ErrorType, Error}; + use crate::{rocket, util::test::TestHarness}; + use rocket::http::{ContentType, Status}; + + #[rocket::async_test] + async fn success() { + let harness = TestHarness::new().await; + let (mut account, session, _) = harness.new_user().await; + + account.password_reset = Some(PasswordReset { + token: "token".into(), + expiry: Timestamp::now_utc() + Duration::seconds(100), + }); + + account.save(&harness.db).await.unwrap(); + + let res = harness.client + .patch("/auth/account/reset_password") + .header(ContentType::JSON) + .body( + json!({ + "token": "token", + "password": "valid-password", + "remove_sessions": true + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::NoContent); + + // Make sure it was used and can't be used again + assert!(harness.db + .fetch_account_with_password_reset("token") + .await + .is_err()); + + let res = harness.client + .post("/auth/session/login") + .header(ContentType::JSON) + .body( + json!({ + "email": account.email.clone(), + "password": "valid-password" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Ok); + assert!(res.into_json::().await.is_some()); + + // Ensure sessions were deleted + assert!(matches!( + harness + .db + .fetch_session(&session.id) + .await + .unwrap_err().error_type, + ErrorType::UnknownUser + )); + } + + #[rocket::async_test] + async fn fail_invalid_token() { + let harness = TestHarness::new().await; + + let res = harness.client + .patch("/auth/account/reset_password") + .header(ContentType::JSON) + .body( + json!({ + "token": "invalid", + "password": "valid password" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Unauthorized); + assert!(matches!( + res.into_json::().await.unwrap().error_type, + ErrorType::InvalidToken + )); + } +} diff --git a/crates/delta/src/routes/account/resend_verification.rs b/crates/delta/src/routes/account/resend_verification.rs new file mode 100644 index 000000000..e418c8011 --- /dev/null +++ b/crates/delta/src/routes/account/resend_verification.rs @@ -0,0 +1,155 @@ +//! Resend account verification email +//! POST /account/reverify +use std::time::Duration; + +use async_std::task::sleep; +use rocket::{serde::json::Json, State}; +use rocket_empty::EmptyResponse; +use revolt_result::Result; +use revolt_database::{Database, util::{email::{normalise_email, validate_email}, captcha::check_captcha}, EmailVerification}; +use revolt_models::v0; + +/// # Resend Verification +/// +/// Resend account creation verification email. +#[openapi(tag = "Account")] +#[post("/reverify", data = "")] +pub async fn resend_verification( + db: &State, + data: Json, +) -> Result { + let data = data.into_inner(); + + // Random jitter from 0-1000ms + sleep(Duration::from_millis((rand::random::() * 1000.) as u64)).await; + + // Check Captcha token + check_captcha(data.captcha.as_deref()).await?; + + // Make sure email is valid and not blocked + validate_email(&data.email)?; + + // From this point on, do not report failure to the + // remote client, as this will open us up to user enumeration. + + // Normalise the email + let email_normalised = normalise_email(data.email); + + // Try to find the relevant account + if let Ok(Some(mut account)) = db + .fetch_account_by_normalised_email(&email_normalised) + .await + { + match account.verification { + EmailVerification::Verified => { + // Send password reset if already verified + account.start_password_reset(db, true).await?; + } + EmailVerification::Pending { .. } => { + // Resend if not verified yet + account.start_email_verification(db).await?; + } + // Ignore if pending for another email, + // this should be re-initiated from settings. + EmailVerification::Moving { .. } => {} + } + } + + // Never fail this route, + // You may open the application to email enumeration otherwise. + Ok(EmptyResponse) +} + +#[cfg(test)] +mod tests { + use iso8601_timestamp::Timestamp; + use revolt_database::{Account, EmailVerification}; + use crate::{rocket, util::test::TestHarness}; + use rocket::http::{ContentType, Status}; + use revolt_result::{Error, ErrorType}; + + #[rocket::async_test] + async fn success() { + let harness = TestHarness::new().await; + + let mut account = Account::new( + &harness.db, + "resend_verification@smtp.test".into(), + "password".into(), + false, + ) + .await + .unwrap(); + + account.verification = EmailVerification::Pending { + token: "".into(), + expiry: Timestamp::now_utc(), + }; + + account.save(&harness.db).await.unwrap(); + + let res = harness.client + .post("/auth/account/reverify") + .header(ContentType::JSON) + .body( + json!({ + "email": "resend_verification@smtp.test", + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::NoContent); + + let (_, code) = harness.assert_email("resend_verification@smtp.test").await; + let res = harness.client + .post(format!("/auth/account/verify/{code}")) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Ok); + } + + #[rocket::async_test] + async fn success_unknown() { + let harness = TestHarness::new().await; + + let res = harness.client + .post("/auth/account/reverify") + .header(ContentType::JSON) + .body( + json!({ + "email": "smtptest1@insrt.uk", + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::NoContent); + } + + #[rocket::async_test] + async fn fail_bad_email() { + let harness = TestHarness::new().await; + + let res = harness.client + .post("/auth/account/reverify") + .header(ContentType::JSON) + .body( + json!({ + "email": "invalid", + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::BadRequest); + assert!(matches!( + res.into_json::().await.unwrap().error_type, + ErrorType::IncorrectData { .. }, + )); + } +} diff --git a/crates/delta/src/routes/account/send_password_reset.rs b/crates/delta/src/routes/account/send_password_reset.rs new file mode 100644 index 000000000..862acd928 --- /dev/null +++ b/crates/delta/src/routes/account/send_password_reset.rs @@ -0,0 +1,122 @@ +//! Send a password reset email +//! POST /account/reset_password +use std::time::Duration; + +use async_std::task::sleep; +use rocket::serde::json::Json; +use rocket::State; +use rocket_empty::EmptyResponse; +use revolt_result::Result; +use revolt_database::{Database, EmailVerification, util::{email::{normalise_email, validate_email}, captcha::check_captcha}}; +use revolt_models::v0; + +/// # Send Password Reset +/// +/// Send an email to reset account password. +#[openapi(tag = "Account")] +#[post("/reset_password", data = "")] +pub async fn send_password_reset( + db: &State, + data: Json, +) -> Result { + let data = data.into_inner(); + + // Random jitter from 0-1000ms + sleep(Duration::from_millis((rand::random::() * 1000.) as u64)).await; + + // Check Captcha token + check_captcha(data.captcha.as_deref()).await?; + + // Make sure email is valid and not blocked + validate_email(&data.email)?; + + // From this point on, do not report failure to the + // remote client, as this will open us up to user enumeration. + + // Normalise the email + let email_normalised = normalise_email(data.email); + + // Try to find the relevant account + if let Ok(Some(mut account)) = db + .fetch_account_by_normalised_email(&email_normalised) + .await + { + if !matches!(account.verification, EmailVerification::Pending { .. }) { + if let Err(e) = account.start_password_reset(db, false).await { + revolt_config::capture_error(&e); + } + } + } + + // Never fail this route, (except for db error) + // You may open the application to email enumeration otherwise. + Ok(EmptyResponse) +} + +#[cfg(test)] +mod tests { + use crate::{rocket, util::test::TestHarness}; + use revolt_database::Account; + use revolt_models::v0; + use rocket::http::{ContentType, Status}; + + #[rocket::async_test] + async fn success() { + let harness = TestHarness::new().await; + + Account::new( + &harness.db, + "password_reset@smtp.test".into(), + "password".into(), + false, + ) + .await + .unwrap(); + + let res = harness.client + .post("/auth/account/reset_password") + .header(ContentType::JSON) + .body( + json!({ + "email": "password_reset@smtp.test", + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::NoContent); + + let (_, code) = harness.assert_email("password_reset@smtp.test").await; + let res = harness.client + .patch("/auth/account/reset_password") + .header(ContentType::JSON) + .body( + json!({ + "token": code, + "password": "valid password" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::NoContent); + + let res = harness.client + .post("/auth/session/login") + .header(ContentType::JSON) + .body( + json!({ + "email": "password_reset@smtp.test", + "password": "valid password" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Ok); + assert!(serde_json::from_str::(&res.into_string().await.unwrap()).is_ok()); + } +} diff --git a/crates/delta/src/routes/account/verify_email.rs b/crates/delta/src/routes/account/verify_email.rs new file mode 100644 index 000000000..104e504b8 --- /dev/null +++ b/crates/delta/src/routes/account/verify_email.rs @@ -0,0 +1,104 @@ +//! Verify an account +//! POST /verify/ +use rocket::{serde::json::Json, State}; +use revolt_database::{Database, EmailVerification, MFATicket, util::email::normalise_email}; +use revolt_result::Result; +use revolt_models::v0; + +/// # Verify Email +/// +/// Verify an email address. +#[openapi(tag = "Account")] +#[post("/verify/")] +pub async fn verify_email( + db: &State, + code: String, +) -> Result> { + // Find the account + let mut account = db + .fetch_account_with_email_verification(&code) + .await?; + + // Update account email + let response = if let EmailVerification::Moving { new_email, .. } = &account.verification { + account.email = new_email.clone(); + account.email_normalised = normalise_email(new_email.clone()); + v0::ResponseVerify::NoTicket + } else { + let mut ticket = MFATicket::new(account.id.to_string(), false); + ticket.authorised = true; + ticket.save(db).await?; + v0::ResponseVerify::WithTicket { ticket: ticket.into() } + }; + + // Mark as verified + account.verification = EmailVerification::Verified; + + // Save to database + account.save(db).await?; + Ok(Json(response)) +} + +#[cfg(test)] +mod tests { + use iso8601_timestamp::{Timestamp, Duration}; + use revolt_database::EmailVerification; + use crate::{rocket, util::test::TestHarness}; + use rocket::http::{ContentType, Status}; + use revolt_models::v0; + use revolt_result::{Error, ErrorType}; + + #[rocket::async_test] + async fn success() { + let harness = TestHarness::new().await; + let (mut account, _, _) = harness.new_user().await; + + account.verification = EmailVerification::Pending { + token: "token".into(), + expiry: Timestamp::now_utc() + Duration::seconds(100), + }; + + account.save(&harness.db).await.unwrap(); + + let res = harness.client.post("/auth/account/verify/token").dispatch().await; + + assert_eq!(res.status(), Status::Ok); + + // Make sure it was used and can't be used again + assert!(harness.db + .fetch_account_with_email_verification("token") + .await + .is_err()); + + // Check that we can login using the received MFA ticket + let response = res.into_json::().await + .expect("`ResponseVerify`"); + + if let v0::ResponseVerify::WithTicket { ticket } = response { + let res = harness.client + .post("/auth/session/login") + .header(ContentType::JSON) + .body(json!({ "mfa_ticket": ticket.token }).to_string()) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Ok); + assert!(res.into_json::().await.is_some()); + } else { + panic!("Expected `ResponseVerify::WithTicket`"); + } + } + + #[rocket::async_test] + async fn fail_invalid_token() { + let harness = TestHarness::new().await; + + let res = harness.client.post("/auth/account/verify/token").dispatch().await; + + assert_eq!(res.status(), Status::Unauthorized); + assert!(matches!( + res.into_json::().await.unwrap().error_type, + ErrorType::InvalidToken, + )); + } +} diff --git a/crates/delta/src/routes/mfa/create_ticket.rs b/crates/delta/src/routes/mfa/create_ticket.rs new file mode 100644 index 000000000..aa3f00f31 --- /dev/null +++ b/crates/delta/src/routes/mfa/create_ticket.rs @@ -0,0 +1,157 @@ +//! Create a new MFA ticket or validate an existing one. +//! PUT /mfa/ticket +use revolt_result::{Result, create_error}; +use revolt_database::{Account, Database, MFATicket, UnvalidatedTicket}; +use revolt_models::v0; +use rocket::serde::json::Json; +use rocket::State; + + +/// # Create MFA ticket +/// +/// Create a new MFA ticket or validate an existing one. +#[openapi(tag = "MFA")] +#[put("/ticket", data = "")] +pub async fn create_ticket( + db: &State, + account: Option, + existing_ticket: Option, + data: Json, +) -> Result> { + // Find the relevant account + let mut account = match (account, existing_ticket) { + (Some(_), Some(_)) => return Err(create_error!(OperationFailed)), + (Some(account), _) => account, + (_, Some(ticket)) => { + db.delete_ticket(&ticket.id).await?; + db.fetch_account(&ticket.account_id).await? + } + _ => return Err(create_error!(InvalidToken)), + }; + + // Validate the MFA response + account + .consume_mfa_response(db, data.into_inner(), None) + .await?; + + // Create a new ticket for this account + let ticket = MFATicket::new(account.id, true); + ticket.save(db).await?; + Ok(Json(ticket.into())) +} + +#[cfg(test)] +mod tests { + use crate::{rocket, util::test::TestHarness}; + use revolt_database::Totp; + use rocket::http::{Header, Status}; + use revolt_models::v0; + use revolt_result::{Error, ErrorType}; + + #[rocket::async_test] + async fn success() { + let harness = TestHarness::new().await; + let (_, session, _) = harness.new_user().await; + + let res = harness.client + .put("/auth/mfa/ticket") + .header(Header::new("X-Session-Token", session.token.clone())) + .body( + json!({ + "password": "password_insecure" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Ok); + assert!(res.into_json::().await.unwrap().validated); + } + + #[rocket::async_test] + async fn success_totp() { + let harness = TestHarness::new().await; + let (mut account, session, _) = harness.new_user().await; + + account.mfa.totp_token = Totp::Enabled { + secret: "secret".to_string(), + }; + account.save(&harness.db).await.unwrap(); + + let res = harness.client + .put("/auth/mfa/ticket") + .header(Header::new("X-Session-Token", session.token.clone())) + .body( + json!({ + "totp_code": Totp::Enabled { + secret: "secret".to_string(), + }.generate_code().unwrap() + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Ok); + assert!(res.into_json::().await.is_some()); + } + + #[rocket::async_test] + async fn failure_totp() { + let harness = TestHarness::new().await; + let (mut account, session, _) = harness.new_user().await; + + account.mfa.totp_token = Totp::Enabled { + secret: "secret".to_string(), + }; + account.save(&harness.db).await.unwrap(); + + let res = harness.client + .put("/auth/mfa/ticket") + .header(Header::new("X-Session-Token", session.token.clone())) + .body( + json!({ + "totp_code": "000000" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Unauthorized); + assert!(matches!( + res.into_json::().await.unwrap().error_type, + ErrorType::InvalidToken, + )); + } + + #[rocket::async_test] + async fn failure_no_totp() { + let harness = TestHarness::new().await; + let (mut account, session, _) = harness.new_user().await; + + account.mfa.totp_token = Totp::Enabled { + secret: "secret".to_string(), + }; + account.save(&harness.db).await.unwrap(); + + let res = harness.client + .put("/auth/mfa/ticket") + .header(Header::new("X-Session-Token", session.token.clone())) + .body( + json!({ + "password": "this is the wrong mfa method" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::BadRequest); + assert!(matches!( + res.into_json::().await.unwrap().error_type, + ErrorType::DisallowedMFAMethod, + )); + } +} diff --git a/crates/delta/src/routes/mfa/fetch_recovery.rs b/crates/delta/src/routes/mfa/fetch_recovery.rs new file mode 100644 index 000000000..65a20a1d6 --- /dev/null +++ b/crates/delta/src/routes/mfa/fetch_recovery.rs @@ -0,0 +1,45 @@ +//! Fetch recovery codes for an account. +//! POST /mfa/recovery +use rocket::serde::json::Json; +use revolt_database::{Account, ValidatedTicket}; +use revolt_result::Result; + +/// # Fetch Recovery Codes +/// +/// Fetch recovery codes for an account. +#[openapi(tag = "MFA")] +#[post("/recovery")] +pub async fn fetch_recovery( + account: Account, + _ticket: ValidatedTicket, +) -> Result>> { + Ok(Json(account.mfa.recovery_codes)) +} + +#[cfg(test)] +mod tests { + use crate::{rocket, util::test::TestHarness}; + use revolt_database::MFATicket; + use rocket::http::{ContentType, Header, Status}; + + + #[rocket::async_test] + async fn success() { + let harness = TestHarness::new().await; + let (account, session, _) = harness.new_user().await; + + let ticket = MFATicket::new(account.id, true); + ticket.save(&harness.db).await.unwrap(); + + let res = harness.client + .post("/auth/mfa/recovery") + .header(Header::new("X-Session-Token", session.token)) + .header(Header::new("X-MFA-Ticket", ticket.token)) + .header(ContentType::JSON) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Ok); + assert!(res.into_json::>().await.unwrap().is_empty()); + } +} diff --git a/crates/delta/src/routes/mfa/fetch_status.rs b/crates/delta/src/routes/mfa/fetch_status.rs new file mode 100644 index 000000000..0c138b05e --- /dev/null +++ b/crates/delta/src/routes/mfa/fetch_status.rs @@ -0,0 +1,37 @@ +//! Fetch MFA status of an account. +//! GET /mfa +use revolt_database::Account; +use revolt_result::Result; +use revolt_models::v0; +use rocket::serde::json::Json; + +/// # MFA Status +/// +/// Fetch MFA status of an account. +#[openapi(tag = "MFA")] +#[get("/")] +pub async fn fetch_status(account: Account) -> Result> { + Ok(Json(account.mfa.into())) +} + +#[cfg(test)] +mod tests { + use crate::{rocket, util::test::TestHarness}; + use rocket::http::{Header, Status}; + use revolt_models::v0; + + #[rocket::async_test] + async fn success() { + let harness = TestHarness::new().await; + let (_, session, _) = harness.new_user().await; + + let res = harness.client + .get("/auth/mfa") + .header(Header::new("X-Session-Token", session.token)) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Ok); + assert!(res.into_json::().await.is_some()); + } +} diff --git a/crates/delta/src/routes/mfa/generate_recovery.rs b/crates/delta/src/routes/mfa/generate_recovery.rs new file mode 100644 index 000000000..37edac9a9 --- /dev/null +++ b/crates/delta/src/routes/mfa/generate_recovery.rs @@ -0,0 +1,66 @@ +//! Re-generate recovery codes for an account. +//! PATCH /mfa/recovery +use revolt_database::{Account, ValidatedTicket, Database}; +use revolt_result::Result; +use rocket::serde::json::Json; +use rocket::State; + +/// # Generate Recovery Codes +/// +/// Re-generate recovery codes for an account. +#[openapi(tag = "MFA")] +#[patch("/recovery")] +pub async fn generate_recovery( + db: &State, + mut account: Account, + _ticket: ValidatedTicket, +) -> Result>> { + // Generate new codes + account.mfa.generate_recovery_codes(); + + // Save account model + account.save(db).await?; + + // Return them to the user + Ok(Json(account.mfa.recovery_codes)) +} + +#[cfg(test)] +mod tests { + use crate::{rocket, util::test::TestHarness}; + use revolt_database::MFATicket; + use rocket::http::{ContentType, Header, Status}; + #[rocket::async_test] + async fn success() { + let harness = TestHarness::new().await; + let (account, session, _) = harness.new_user().await; + + let ticket1 = MFATicket::new(account.id.to_string(), true); + ticket1.save(&harness.db).await.unwrap(); + + let ticket2 = MFATicket::new(account.id, true); + ticket2.save(&harness.db).await.unwrap(); + + let res = harness.client + .patch("/auth/mfa/recovery") + .header(Header::new("X-Session-Token", session.token.clone())) + .header(Header::new("X-MFA-Ticket", ticket1.token)) + .header(ContentType::JSON) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Ok); + assert!(res.into_json::>().await.is_some()); + + let res = harness.client + .post("/auth/mfa/recovery") + .header(Header::new("X-Session-Token", session.token)) + .header(Header::new("X-MFA-Ticket", ticket2.token)) + .header(ContentType::JSON) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Ok); + assert_eq!(res.into_json::>().await.unwrap().len(), 10); + } +} diff --git a/crates/delta/src/routes/mfa/get_mfa_methods.rs b/crates/delta/src/routes/mfa/get_mfa_methods.rs new file mode 100644 index 000000000..9f13e8e9c --- /dev/null +++ b/crates/delta/src/routes/mfa/get_mfa_methods.rs @@ -0,0 +1,71 @@ +//! Fetch available MFA methods. +//! GET /mfa/methods +use revolt_database::Account; +use revolt_models::v0; +use rocket::serde::json::Json; + +/// # Get MFA Methods +/// +/// Fetch available MFA methods. +#[openapi(tag = "MFA")] +#[get("/methods")] +pub async fn get_mfa_methods(account: Account) -> Json> { + Json( + account + .mfa + .get_methods() + .into_iter() + .map(Into::into) + .collect(), + ) +} + +#[cfg(test)] +mod tests { + use crate::{rocket, util::test::TestHarness}; + use revolt_database::Totp; + use rocket::http::{Header, Status}; + use revolt_models::v0; + + #[rocket::async_test] + async fn success() { + let harness = TestHarness::new().await; + let (_, session, _) = harness.new_user().await; + + let res = harness.client + .get("/auth/mfa/methods") + .header(Header::new("X-Session-Token", session.token)) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Ok); + assert_eq!( + res.into_json::>().await.unwrap(), + vec![v0::MFAMethod::Password] + ); + } + + #[rocket::async_test] + async fn success_has_recovery_and_totp() { + let harness = TestHarness::new().await; + let (mut account, session, _) = harness.new_user().await; + + account.mfa.totp_token = Totp::Enabled { + secret: "some".to_string(), + }; + account.mfa.generate_recovery_codes(); + account.save(&harness.db).await.unwrap(); + + let res = harness.client + .get("/auth/mfa/methods") + .header(Header::new("X-Session-Token", session.token)) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Ok); + assert_eq!( + res.into_json::>().await.unwrap(), + vec![v0::MFAMethod::Totp, v0::MFAMethod::Recovery] + ); + } +} diff --git a/crates/delta/src/routes/mfa/mod.rs b/crates/delta/src/routes/mfa/mod.rs new file mode 100644 index 000000000..1b7c9e9b4 --- /dev/null +++ b/crates/delta/src/routes/mfa/mod.rs @@ -0,0 +1,24 @@ +use revolt_rocket_okapi::revolt_okapi::openapi3::OpenApi; +use rocket::Route; + +pub mod create_ticket; +pub mod fetch_recovery; +pub mod fetch_status; +pub mod generate_recovery; +pub mod get_mfa_methods; +pub mod totp_disable; +pub mod totp_enable; +pub mod totp_generate_secret; + +pub fn routes() -> (Vec, OpenApi) { + openapi_get_routes_spec![ + create_ticket::create_ticket, + fetch_status::fetch_status, + fetch_recovery::fetch_recovery, + generate_recovery::generate_recovery, + get_mfa_methods::get_mfa_methods, + totp_disable::totp_disable, + totp_enable::totp_enable, + totp_generate_secret::totp_generate_secret, + ] +} diff --git a/crates/delta/src/routes/mfa/totp_disable.rs b/crates/delta/src/routes/mfa/totp_disable.rs new file mode 100644 index 000000000..283483155 --- /dev/null +++ b/crates/delta/src/routes/mfa/totp_disable.rs @@ -0,0 +1,49 @@ +//! Disable TOTP 2FA. +//! DELETE /mfa/totp +use revolt_database::{Database, Account, ValidatedTicket, Totp}; +use revolt_result::Result; +use rocket::State; +use rocket_empty::EmptyResponse; + +/// # Disable TOTP 2FA +/// +/// Disable TOTP 2FA for an account. +#[openapi(tag = "MFA")] +#[delete("/totp")] +pub async fn totp_disable( + db: &State, + mut account: Account, + _ticket: ValidatedTicket, +) -> Result { + // Disable TOTP + account.mfa.totp_token = Totp::Disabled; + + // Save model to database + account.save(db).await.map(|_| EmptyResponse) +} + +#[cfg(test)] +mod tests { + use crate::{rocket, util::test::TestHarness}; + use revolt_database::MFATicket; + use rocket::http::{Header, Status}; + + #[rocket::async_test] + async fn success() { + let harness = TestHarness::new().await; + let (account, session, _) = harness.new_user().await; + + let ticket = MFATicket::new(account.id, true); + ticket.save(&harness.db).await.unwrap(); + + + let res = harness.client + .delete("/auth/mfa/totp") + .header(Header::new("X-Session-Token", session.token.clone())) + .header(Header::new("X-MFA-Ticket", ticket.token)) + .dispatch() + .await; + + assert_eq!(res.status(), Status::NoContent); + } +} diff --git a/crates/delta/src/routes/mfa/totp_enable.rs b/crates/delta/src/routes/mfa/totp_enable.rs new file mode 100644 index 000000000..ca06e4613 --- /dev/null +++ b/crates/delta/src/routes/mfa/totp_enable.rs @@ -0,0 +1,102 @@ +//! Generate a new secret for TOTP. +//! POST /mfa/totp +use revolt_database::{Database, Account}; +use revolt_models::v0; +use revolt_result::Result; +use rocket::serde::json::Json; +use rocket::State; +use rocket_empty::EmptyResponse; + +/// # Enable TOTP 2FA +/// +/// Generate a new secret for TOTP. +#[openapi(tag = "MFA")] +#[put("/totp", data = "")] +pub async fn totp_enable( + db: &State, + mut account: Account, + data: Json, +) -> Result { + // Enable TOTP 2FA + account.mfa.enable_totp(data.into_inner())?; + + // Save model to database + account.save(db).await.map(|_| EmptyResponse) +} + +#[cfg(test)] +mod tests { + use crate::{rocket, util::test::TestHarness}; + use revolt_database::{MFATicket, Totp}; + use rocket::http::{ContentType, Header, Status}; + use revolt_models::v0; + + #[rocket::async_test] + async fn success() { + let harness = TestHarness::new().await; + let (account, session, _) = harness.new_user().await; + + let ticket = MFATicket::new(account.id.to_string(), true); + ticket.save(&harness.db).await.unwrap(); + + let res = harness.client + .post("/auth/mfa/totp") + .header(Header::new("X-Session-Token", session.token.clone())) + .header(Header::new("X-MFA-Ticket", ticket.token)) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Ok); + + let secret = res.into_json::().await.unwrap().secret; + + let code = Totp::Enabled { secret }.generate_code().unwrap(); + + let res = harness.client + .put("/auth/mfa/totp") + .header(Header::new("X-Session-Token", session.token)) + .header(ContentType::JSON) + .body(json!({ "totp_code": code }).to_string()) + .dispatch() + .await; + + assert_eq!(res.status(), Status::NoContent); + + let res = harness.client + .post("/auth/session/login") + .header(ContentType::JSON) + .body( + json!({ + "email": account.email.clone(), + "password": "password_insecure" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Ok); + let response = res.into_json::().await.unwrap(); + + if let v0::ResponseLogin::MFA { ticket, .. } = response { + let res = harness.client + .post("/auth/session/login") + .header(ContentType::JSON) + .body( + json!({ + "mfa_ticket": ticket, + "mfa_response": { + "totp_code": code + } + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Ok); + } else { + unreachable!("Did not receive MFA challenge!"); + } + } +} diff --git a/crates/delta/src/routes/mfa/totp_generate_secret.rs b/crates/delta/src/routes/mfa/totp_generate_secret.rs new file mode 100644 index 000000000..86c2e0a58 --- /dev/null +++ b/crates/delta/src/routes/mfa/totp_generate_secret.rs @@ -0,0 +1,59 @@ +//! Generate a new secret for TOTP. +//! POST /mfa/totp +use revolt_result::Result; +use revolt_models::v0; +use revolt_database::{Database, Account, ValidatedTicket}; +use rocket::serde::json::Json; +use rocket::State; + + +/// # Generate TOTP Secret +/// +/// Generate a new secret for TOTP. +#[openapi(tag = "MFA")] +#[post("/totp")] +pub async fn totp_generate_secret( + db: &State, + mut account: Account, + _ticket: ValidatedTicket, +) -> Result> { + // Generate a new secret + let secret = account.mfa.generate_new_totp_secret()?; + + // Save model to database + account.save(db).await?; + + // Send secret to user + Ok(Json(v0::ResponseTotpSecret { secret })) +} + +#[cfg(test)] +mod tests { + use crate::{rocket, util::test::TestHarness}; + use revolt_database::{MFATicket, Totp}; + use rocket::http::{Header, Status}; + use revolt_models::v0; + + #[rocket::async_test] + async fn success() { + let harness = TestHarness::new().await; + let (account, session, _) = harness.new_user().await; + + let ticket = MFATicket::new(account.id.to_string(), true); + ticket.save(&harness.db).await.unwrap(); + + let res = harness.client + .post("/auth/mfa/totp") + .header(Header::new("X-Session-Token", session.token)) + .header(Header::new("X-MFA-Ticket", ticket.token)) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Ok); + + let secret = res.into_json::().await.unwrap().secret; + + let account = harness.db.fetch_account(&account.id).await.unwrap(); + assert_eq!(account.mfa.totp_token, Totp::Pending { secret }); + } +} diff --git a/crates/delta/src/routes/mod.rs b/crates/delta/src/routes/mod.rs index 768531fcd..ad12c2c31 100644 --- a/crates/delta/src/routes/mod.rs +++ b/crates/delta/src/routes/mod.rs @@ -17,6 +17,9 @@ mod servers; mod sync; mod users; mod webhooks; +mod account; +mod session; +mod mfa; pub fn mount(config: Settings, mut rocket: Rocket) -> Rocket { let settings = OpenApiSettings::default(); @@ -33,9 +36,9 @@ pub fn mount(config: Settings, mut rocket: Rocket) -> Rocket { "/invites" => invites::routes(), "/custom" => customisation::routes(), "/safety" => safety::routes(), - "/auth/account" => rocket_authifier::routes::account::routes(), - "/auth/session" => rocket_authifier::routes::session::routes(), - "/auth/mfa" => rocket_authifier::routes::mfa::routes(), + "/auth/account" => account::routes(), + "/auth/session" => session::routes(), + "/auth/mfa" => mfa::routes(), "/onboard" => onboard::routes(), "/policy" => policy::routes(), "/push" => push::routes(), @@ -54,9 +57,9 @@ pub fn mount(config: Settings, mut rocket: Rocket) -> Rocket { "/invites" => invites::routes(), "/custom" => customisation::routes(), "/safety" => safety::routes(), - "/auth/account" => rocket_authifier::routes::account::routes(), - "/auth/session" => rocket_authifier::routes::session::routes(), - "/auth/mfa" => rocket_authifier::routes::mfa::routes(), + "/auth/account" => account::routes(), + "/auth/session" => session::routes(), + "/auth/mfa" => mfa::routes(), "/onboard" => onboard::routes(), "/policy" => policy::routes(), "/push" => push::routes(), diff --git a/crates/delta/src/routes/onboard/complete.rs b/crates/delta/src/routes/onboard/complete.rs index e3621a192..eae1b787f 100644 --- a/crates/delta/src/routes/onboard/complete.rs +++ b/crates/delta/src/routes/onboard/complete.rs @@ -1,7 +1,6 @@ -use authifier::models::Session; use once_cell::sync::Lazy; use regex::Regex; -use revolt_database::{Database, User}; +use revolt_database::{Database, User, Session}; use revolt_models::v0; use revolt_result::{create_error, Result}; diff --git a/crates/delta/src/routes/onboard/hello.rs b/crates/delta/src/routes/onboard/hello.rs index 92a0a8ddd..9559c8fdb 100644 --- a/crates/delta/src/routes/onboard/hello.rs +++ b/crates/delta/src/routes/onboard/hello.rs @@ -1,5 +1,4 @@ -use authifier::models::Session; -use revolt_database::User; +use revolt_database::{Session, User}; use rocket::serde::json::Json; use serde::Serialize; diff --git a/crates/delta/src/routes/push/subscribe.rs b/crates/delta/src/routes/push/subscribe.rs index 0d3d09e46..0a69f7cff 100644 --- a/crates/delta/src/routes/push/subscribe.rs +++ b/crates/delta/src/routes/push/subscribe.rs @@ -1,7 +1,5 @@ -use authifier::{ - models::{Session, WebPushSubscription}, - Authifier, -}; +use revolt_database::{Database, Session}; +use revolt_models::v0; use revolt_result::{create_database_error, Result}; use rocket::{serde::json::Json, State}; use rocket_empty::EmptyResponse; @@ -14,13 +12,13 @@ use rocket_empty::EmptyResponse; #[openapi(tag = "Web Push")] #[post("/subscribe", data = "")] pub async fn subscribe( - authifier: &State, + db: &State, mut session: Session, - data: Json, + data: Json, ) -> Result { - session.subscription = Some(data.into_inner()); + session.subscription = Some(data.into_inner().into()); session - .save(authifier) + .save(db) .await .map(|_| EmptyResponse) .map_err(|_| create_database_error!("save", "session")) diff --git a/crates/delta/src/routes/push/unsubscribe.rs b/crates/delta/src/routes/push/unsubscribe.rs index dcc9179f3..c5a65a32c 100644 --- a/crates/delta/src/routes/push/unsubscribe.rs +++ b/crates/delta/src/routes/push/unsubscribe.rs @@ -1,5 +1,4 @@ -use authifier::{models::Session, Authifier}; - +use revolt_database::{Database, Session}; use revolt_result::{create_database_error, Result}; use rocket_empty::EmptyResponse; @@ -10,13 +9,10 @@ use rocket::State; /// Remove the Web Push subscription associated with the current session. #[openapi(tag = "Web Push")] #[post("/unsubscribe")] -pub async fn unsubscribe( - authifier: &State, - mut session: Session, -) -> Result { +pub async fn unsubscribe(db: &State, mut session: Session) -> Result { session.subscription = None; session - .save(authifier) + .save(db) .await .map(|_| EmptyResponse) .map_err(|_| create_database_error!("save", "session")) diff --git a/crates/delta/src/routes/servers/server_edit.rs b/crates/delta/src/routes/servers/server_edit.rs index 986c3b08a..c27bf72eb 100644 --- a/crates/delta/src/routes/servers/server_edit.rs +++ b/crates/delta/src/routes/servers/server_edit.rs @@ -1,14 +1,13 @@ use std::collections::HashSet; -use authifier::models::{totp::Totp, Account, ValidatedTicket}; use revolt_database::{ util::{permissions::DatabasePermissionQuery, reference::Reference}, - Database, File, PartialServer, User, + Database, File, PartialServer, User, ValidatedTicket, }; use revolt_models::v0; use revolt_permissions::{calculate_server_permissions, ChannelPermission}; use revolt_result::{create_error, Result}; -use rocket::{serde::json::Json, Request, State}; +use rocket::{serde::json::Json, State}; use validator::Validate; /// # Edit Server @@ -18,7 +17,6 @@ use validator::Validate; #[patch("/", data = "")] pub async fn edit( db: &State, - account: Account, user: User, target: Reference<'_>, data: Json, diff --git a/crates/delta/src/routes/session/edit.rs b/crates/delta/src/routes/session/edit.rs new file mode 100644 index 000000000..df59b8786 --- /dev/null +++ b/crates/delta/src/routes/session/edit.rs @@ -0,0 +1,67 @@ +//! Edit a session +//! PATCH /session/:id +use revolt_database::{Database, Session}; +use revolt_models::v0; +use revolt_result::{Result, create_error}; +use rocket::serde::json::Json; +use rocket::State; + + +/// # Edit Session +/// +/// Edit current session information. +#[openapi(tag = "Session")] +#[patch("/", data = "")] +pub async fn edit( + db: &State, + user: Session, + id: String, + data: Json, +) -> Result> { + let mut session = db.fetch_session(&id).await?; + + // Make sure we own this session + if user.user_id != session.user_id { + return Err(create_error!(InvalidSession)); + } + + // Rename the session + session.name = data.into_inner().friendly_name; + + // Save session + session.save(db).await?; + + Ok(Json(session.into())) +} + +#[cfg(test)] +mod tests { + use crate::{rocket, util::test::TestHarness}; + use rocket::http::{ContentType, Status}; + use revolt_models::v0; + + #[rocket::async_test] + async fn success() { + use rocket::http::Header; + + let harness = TestHarness::new().await; + let (_, session, _) = harness.new_user().await; + + let res = harness.client + .patch(format!("/auth/session/{}", session.id)) + .header(ContentType::JSON) + .header(Header::new("X-Session-Token", session.token)) + .body( + json!({ + "friendly_name": "test name" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Ok); + + assert_eq!(res.into_json::().await.unwrap().name, "test name"); + } +} diff --git a/crates/delta/src/routes/session/fetch_all.rs b/crates/delta/src/routes/session/fetch_all.rs new file mode 100644 index 000000000..4808e4077 --- /dev/null +++ b/crates/delta/src/routes/session/fetch_all.rs @@ -0,0 +1,52 @@ +//! Fetch all sessions +//! GET /session/all +use revolt_result::Result; +use revolt_database::{Database, Session}; +use revolt_models::v0; +use rocket::serde::json::Json; +use rocket::State; + +/// # Fetch Sessions +/// +/// Fetch all sessions associated with this account. +#[openapi(tag = "Session")] +#[get("/all")] +pub async fn fetch_all( + db: &State, + session: Session, +) -> Result>> { + db + .fetch_sessions(&session.user_id) + .await + .map(|ok| ok.into_iter().map(|session| session.into()).collect()) + .map(Json) +} + +#[cfg(test)] +mod tests { + use crate::{rocket, util::test::TestHarness}; + use rocket::http::{Header, Status}; + use revolt_models::v0; + + #[rocket::async_test] + async fn success() { + let harness = TestHarness::new().await; + let (account, session, _) = harness.new_user().await; + + for i in 1..=3 { + account + .create_session(&harness.db, format!("session{}", i)) + .await + .unwrap(); + } + + let res = harness.client + .get("/auth/session/all") + .header(Header::new("X-Session-Token", session.token)) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Ok); + assert_eq!(res.into_json::>().await.unwrap().len(), 4); + } +} diff --git a/crates/delta/src/routes/session/login.rs b/crates/delta/src/routes/session/login.rs new file mode 100644 index 000000000..7dc4571eb --- /dev/null +++ b/crates/delta/src/routes/session/login.rs @@ -0,0 +1,588 @@ +//! Login to an account +//! POST /session/login +use std::ops::Add; +use std::time::Duration; + +use async_std::task::sleep; +use iso8601_timestamp::Timestamp; +use revolt_database::{ + util::{email::normalise_email, password::assert_safe}, + Database, EmailVerification, Lockout, MFATicket, +}; +use revolt_models::v0; +use revolt_result::{create_error, Result}; +use rocket::serde::json::Json; +use rocket::State; + +/// # Login +/// +/// Login to an account. +#[openapi(tag = "Session")] +#[post("/login", data = "")] +pub async fn login( + db: &State, + data: Json, +) -> Result> { + // Random jitter from 0-1000ms + sleep(Duration::from_millis((rand::random::() * 1000.) as u64)).await; + + let (account, name) = match data.into_inner() { + v0::DataLogin::Email { + email, + password, + friendly_name, + } => { + // Try to find the account we want + let email_normalised = normalise_email(email); + + // Lookup the email in database + if let Some(mut account) = db + .fetch_account_by_normalised_email(&email_normalised) + .await? + { + // Make sure the account has been verified + if let EmailVerification::Pending { .. } = account.verification { + return Err(create_error!(UnverifiedAccount)); + } + + // Make sure password has not been compromised + assert_safe(&password).await?; + + // Check for account lockout + if let Some(lockout) = &account.lockout { + if let Some(expiry) = lockout.expiry { + if expiry > Timestamp::now_utc() { + return Err(create_error!(LockedOut)); + } + } + } + + // Verify the password is correct. + if let Err(err) = account.verify_password(&password) { + // Lock out account if attempts are too high + if let Some(lockout) = &mut account.lockout { + lockout.attempts += 1; + + // Allow 3 attempts + // + // Lockout for 1 minute on 3rd attempt + // Lockout for 5 minutes on 4th attempt + // Lockout for 1 hour on each subsequent attempt + if lockout.attempts >= 3 { + lockout.expiry = Some(Timestamp::now_utc().add(Duration::from_secs( + if lockout.attempts >= 5 { + 3600 + } else if lockout.attempts == 4 { + 300 + } else { + 60 + }, + ))); + } + } else { + account.lockout = Some(Lockout { + attempts: 1, + expiry: None, + }); + } + + account.save(db).await?; + return Err(err); + } + + // Clear lockout information if present + if account.lockout.is_some() { + account.lockout = None; + account.save(db).await?; + } + + // Check whether an MFA step is required + if account.mfa.is_active() { + // Create a new ticket + let mut ticket = MFATicket::new(account.id, false); + ticket.populate(&account.mfa).await; + ticket.save(db).await?; + + // Return applicable methods + return Ok(Json(v0::ResponseLogin::MFA { + ticket: ticket.token, + allowed_methods: account + .mfa + .get_methods() + .into_iter() + .map(Into::into) + .collect(), + })); + } + + (account, friendly_name) + } else { + return Err(create_error!(InvalidCredentials)); + } + } + v0::DataLogin::MFA { + mfa_ticket, + mfa_response, + friendly_name, + } => { + // Resolve the MFA ticket + let ticket = db + .fetch_ticket_by_token(&mfa_ticket) + .await?; + + // Find the corresponding account + let mut account = db.fetch_account(&ticket.account_id).await?; + + // Verify the MFA response + if let Some(mfa_response) = mfa_response { + account + .consume_mfa_response(db, mfa_response, Some(ticket)) + .await?; + } else if !ticket.authorised { + return Err(create_error!(InvalidToken)); + } + + (account, friendly_name) + } + }; + + // Generate a session name + let name = name.unwrap_or_else(|| "Unknown".to_string()); + + // Prevent disabled accounts from logging in + if account.disabled { + return Ok(Json(v0::ResponseLogin::Disabled { + user_id: account.id, + })); + } + + // Create and return a new session + Ok(Json(v0::ResponseLogin::Success( + account.create_session(db, name).await?.into(), + ))) +} + +#[cfg(test)] +mod tests { + use iso8601_timestamp::Timestamp; + use revolt_database::{Account, EmailVerification, Lockout, MFATicket, Totp, events::client::EventV1}; + use crate::{rocket, util::test::TestHarness}; + use rocket::http::{ContentType, Status}; + use revolt_models::v0; + use revolt_result::{Error, ErrorType}; + + #[rocket::async_test] + async fn success() { + let mut harness = TestHarness::new().await; + + Account::new( + &harness.db, + "example@validemail.com".into(), + "password_insecure".into(), + false, + ) + .await + .unwrap(); + + harness.wait_for_event("global", |_| true).await; + + let res = harness.client + .post("/auth/session/login") + .header(ContentType::JSON) + .body( + json!({ + "email": "EXAMPLE@validemail.com", + "password": "password_insecure" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Ok); + assert!(res.into_json::().await.is_some()); + + let event = harness.wait_for_event("global", |_| true).await; + if !matches!(event, EventV1::CreateSession { .. }) { + panic!("Received incorrect event type. {:?}", event); + } + } + + #[rocket::async_test] + async fn success_totp_mfa() { + let harness = TestHarness::new().await; + let (mut account, _, _) = harness.new_user().await; + + let totp = Totp::Enabled { + secret: "secret".to_string(), + }; + + account.mfa.totp_token = totp.clone(); + account.save(&harness.db).await.unwrap(); + + let res = harness.client + .post("/auth/session/login") + .header(ContentType::JSON) + .body( + json!({ + "email": &account.email, + "password": "password_insecure" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Ok); + let response = serde_json::from_str::( + &res.into_string().await.unwrap(), + ) + .expect("`ResponseLogin`"); + + if let v0::ResponseLogin::MFA { + ticket, + allowed_methods, + } = response + { + assert!(allowed_methods.contains(&v0::MFAMethod::Totp)); + + let res = harness.client + .post("/auth/session/login") + .header(ContentType::JSON) + .body( + json!({ + "mfa_ticket": ticket, + "mfa_response": { + "totp_code": totp.generate_code().expect("totp code") + } + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Ok); + assert!(serde_json::from_str::(&res.into_string().await.unwrap()).is_ok()); + } else { + panic!("expected `ResponseLogin::MFA`") + } + } + + #[rocket::async_test] + async fn success_totp_stored_mfa() { + let harness = TestHarness::new().await; + let (mut account, _, _) = harness.new_user().await; + + let totp = Totp::Enabled { + secret: "secret".to_string(), + }; + + account.mfa.totp_token = totp.clone(); + account.save(&harness.db).await.unwrap(); + + let mut ticket = MFATicket::new(account.id.to_string(), true); + ticket.last_totp_code = Some("token from earlier".into()); + ticket.save(&harness.db).await.unwrap(); + + let res = harness.client + .post("/auth/session/login") + .header(ContentType::JSON) + .body( + json!({ + "mfa_ticket": ticket.token, + "mfa_response": { + "totp_code": "token from earlier" + } + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Ok); + assert!(serde_json::from_str::(&res.into_string().await.unwrap()).is_ok()); + } + + #[rocket::async_test] + async fn fail_totp_invalid_mfa() { + let harness = TestHarness::new().await; + let (mut account, _, _) = harness.new_user().await; + + let totp = Totp::Enabled { + secret: "secret".to_string(), + }; + + account.mfa.totp_token = totp.clone(); + account.save(&harness.db).await.unwrap(); + + let res = harness.client + .post("/auth/session/login") + .json( + &json!({ + "email": account.email.clone(), + "password": "password_insecure" + }) + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Ok); + let response = serde_json::from_str::( + &res.into_string().await.unwrap(), + ) + .expect("`ResponseLogin`"); + + if let v0::ResponseLogin::MFA { + ticket, + allowed_methods, + } = response + { + assert!(allowed_methods.contains(&v0::MFAMethod::Totp)); + + let res = harness.client + .post("/auth/session/login") + .json( + &json!({ + "mfa_ticket": ticket, + "mfa_response": { + "totp_code": "some random data" + } + }) + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Unauthorized); + assert!(matches!( + res.into_json::().await.unwrap().error_type, + ErrorType::InvalidToken, + )); + } else { + panic!("expected `ResponseLogin::MFA`") + } + } + + #[rocket::async_test] + async fn fail_invalid_user() { + let harness = TestHarness::new().await; + + let res = harness.client + .post("/auth/session/login") + .json( + &json!({ + "email": "example@validemail.com", + "password": "password_insecure" + }) + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Unauthorized); + assert!(matches!( + res.into_json::().await.unwrap().error_type, + ErrorType::InvalidCredentials, + )); + } + + #[rocket::async_test] + async fn fail_disabled_account() { + let harness = TestHarness::new().await; + + let mut account = Account::new( + &harness.db, + "example@validemail.com".into(), + "password_insecure".into(), + false, + ) + .await + .unwrap(); + + account.disabled = true; + account.save(&harness.db).await.unwrap(); + + let res = harness.client + .post("/auth/session/login") + .header(ContentType::JSON) + .body( + json!({ + "email": "example@validemail.com", + "password": "password_insecure" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Ok); + let response = serde_json::from_str::( + &res.into_string().await.unwrap(), + ) + .expect("`ResponseLogin`"); + + assert!(matches!( + response, + v0::ResponseLogin::Disabled { .. } + )); + } + + #[rocket::async_test] + async fn fail_unverified_account() { + let harness = TestHarness::new().await; + + let mut account = Account::new( + &harness.db, + "example@validemail.com".into(), + "password_insecure".into(), + false, + ) + .await + .unwrap(); + + account.verification = EmailVerification::Pending { + token: "".to_string(), + expiry: Timestamp::now_utc(), + }; + + account.save(&harness.db).await.unwrap(); + + let res = harness.client + .post("/auth/session/login") + .header(ContentType::JSON) + .body( + json!({ + "email": "example@validemail.com", + "password": "password_insecure" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Forbidden); + assert!(matches!( + res.into_json::().await.unwrap().error_type, + ErrorType::UnverifiedAccount, + )); + } + + #[rocket::async_test] + async fn fail_locked_account() { + let harness = TestHarness::new().await; + + let mut account = Account::new( + &harness.db, + "example@validemail.com".into(), + "password_insecure".into(), + false, + ) + .await + .unwrap(); + + account.save(&harness.db).await.unwrap(); + + + // Attempt 1 + let res = harness.client + .post("/auth/session/login") + .header(ContentType::JSON) + .body( + json!({ + "email": "example@validemail.com", + "password": "wrong_password" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Unauthorized); + assert!(matches!( + res.into_json::().await.unwrap().error_type, + ErrorType::InvalidCredentials, + )); + + // Attempt 2 + let res = harness.client + .post("/auth/session/login") + .header(ContentType::JSON) + .body( + json!({ + "email": "example@validemail.com", + "password": "wrong_password" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Unauthorized); + assert!(matches!( + res.into_json::().await.unwrap().error_type, + ErrorType::InvalidCredentials, + )); + + // Attempt 3 + let res = harness.client + .post("/auth/session/login") + .header(ContentType::JSON) + .body( + json!({ + "email": "example@validemail.com", + "password": "wrong_password" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Unauthorized); + assert!(matches!( + res.into_json::().await.unwrap().error_type, + ErrorType::InvalidCredentials, + )); + + // Attempt 4: Locked Out + let res = harness.client + .post("/auth/session/login") + .header(ContentType::JSON) + .body( + json!({ + "email": "example@validemail.com", + "password": "password_insecure" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Forbidden); + assert!(matches!( + res.into_json::().await.unwrap().error_type, + ErrorType::LockedOut, + )); + // Pretend it expired + account.lockout = Some(Lockout { + attempts: 9001, + expiry: Some(Timestamp::now_utc()), + }); + + account.save(&harness.db).await.unwrap(); + + // Once it expires, we can log in. + let res = harness.client + .post("/auth/session/login") + .header(ContentType::JSON) + .body( + json!({ + "email": "example@validemail.com", + "password": "password_insecure" + }) + .to_string(), + ) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Ok); + assert!(serde_json::from_str::(&res.into_string().await.unwrap()).is_ok()); + } +} diff --git a/crates/delta/src/routes/session/logout.rs b/crates/delta/src/routes/session/logout.rs new file mode 100644 index 000000000..c442a5793 --- /dev/null +++ b/crates/delta/src/routes/session/logout.rs @@ -0,0 +1,79 @@ +//! Logout of current session +//! POST /session/logout +use revolt_database::{Database, Session}; +use revolt_result::Result; +use rocket::State; +use rocket_empty::EmptyResponse; + +/// # Logout +/// +/// Delete current session. +#[openapi(tag = "Session")] +#[post("/logout")] +pub async fn logout(db: &State, session: Session) -> Result { + session.delete(db).await.map(|_| EmptyResponse) +} + +#[cfg(test)] +mod tests { + use crate::{rocket, util::test::TestHarness}; + use revolt_database::events::client::EventV1; + use revolt_result::ErrorType; + use rocket::http::{Header, Status}; + + #[rocket::async_test] + async fn success() { + let mut harness = TestHarness::new().await; + let (_, session, _) = harness.new_user().await; + + let res = harness.client + .post("/auth/session/logout") + .header(Header::new("X-Session-Token", session.token)) + .dispatch() + .await; + + assert_eq!(res.status(), Status::NoContent); + drop(res); + assert!(matches!( + harness.db + .fetch_session(&session.id) + .await + .unwrap_err().error_type, + ErrorType::UnknownUser + )); + + let event = harness.wait_for_event(&format!("{}!", &session.user_id), |evt| matches!(evt, EventV1::DeleteSession { .. })).await; + if let EventV1::DeleteSession { + user_id, + session_id, + } = event + { + assert_eq!(user_id, session.user_id); + assert_eq!(session_id, session.id); + } else { + panic!("Received incorrect event type. {:?}", event); + } + } + + #[rocket::async_test] + async fn fail_invalid_session() { + let harness = TestHarness::new().await; + + let res = harness.client + .post("/auth/session/logout") + .header(Header::new("X-Session-Token", "invalid")) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Unauthorized); + } + + #[rocket::async_test] + async fn fail_no_session() { + let harness = TestHarness::new().await; + + let res = harness.client.post("/auth/session/logout").dispatch().await; + + assert_eq!(res.status(), Status::Unauthorized); + } +} diff --git a/crates/delta/src/routes/session/mod.rs b/crates/delta/src/routes/session/mod.rs new file mode 100644 index 000000000..9e1156122 --- /dev/null +++ b/crates/delta/src/routes/session/mod.rs @@ -0,0 +1,20 @@ +use revolt_rocket_okapi::revolt_okapi::openapi3::OpenApi; +use rocket::Route; + +pub mod edit; +pub mod fetch_all; +pub mod login; +pub mod logout; +pub mod revoke; +pub mod revoke_all; + +pub fn routes() -> (Vec, OpenApi) { + openapi_get_routes_spec![ + login::login, + logout::logout, + fetch_all::fetch_all, + revoke::revoke, + revoke_all::revoke_all, + edit::edit + ] +} diff --git a/crates/delta/src/routes/session/revoke.rs b/crates/delta/src/routes/session/revoke.rs new file mode 100644 index 000000000..3b3ffe283 --- /dev/null +++ b/crates/delta/src/routes/session/revoke.rs @@ -0,0 +1,114 @@ +//! Revoke an active session +//! DELETE /session/:id +use revolt_database::{Database, Session, ValidatedTicket}; +use revolt_result::{Result, create_error}; +use rocket::State; +use rocket_empty::EmptyResponse; + +/// # Revoke Session +/// +/// Delete a specific active session. +#[openapi(tag = "Session")] +#[delete("/")] +pub async fn revoke( + db: &State, + _ticket: ValidatedTicket, + user: Session, + id: String, +) -> Result { + let session = db.fetch_session(&id).await?; + + if session.user_id != user.user_id { + return Err(create_error!(InvalidToken)); + } + + session.delete(db).await.map(|_| EmptyResponse) +} + +#[cfg(test)] +mod tests { + use crate::{rocket, util::test::TestHarness}; + use revolt_database::{MFATicket, Totp}; + use revolt_result::ErrorType; + use rocket::http::{Header, Status}; + + #[rocket::async_test] + async fn success() { + let harness = TestHarness::new().await; + let (account, session, _) = harness.new_user().await; + + let ticket = MFATicket::new(account.id.to_string(), true); + ticket.save(&harness.db).await.unwrap(); + + let res = harness.client + .delete(format!("/auth/session/{}", session.id)) + .header(Header::new("X-Session-Token", session.token)) + .header(Header::new("X-MFA-Ticket", ticket.token)) + .dispatch() + .await; + + assert_eq!(res.status(), Status::NoContent); + assert!(matches!( + harness.db + .fetch_session(&session.id) + .await + .unwrap_err() + .error_type, + ErrorType::UnknownUser + )); + } + + #[rocket::async_test] + async fn success_mfa() { + let harness = TestHarness::new().await; + let (mut account, session, _) = harness.new_user().await; + + let totp = Totp::Enabled { + secret: "secret".to_string(), + }; + + account.mfa.totp_token = totp.clone(); + account.save(&harness.db).await.unwrap(); + + let ticket = MFATicket::new(account.id.to_string(), true); + ticket.save(&harness.db).await.unwrap(); + + let res = harness.client + .delete(format!("/auth/session/{}", session.id)) + .header(Header::new("X-Session-Token", session.token)) + .header(Header::new("X-MFA-Ticket", ticket.token)) + .dispatch() + .await; + + assert_eq!(res.status(), Status::NoContent); + assert!(matches!( + harness.db + .fetch_session(&session.id) + .await + .unwrap_err() + .error_type, + ErrorType::UnknownUser + )); + } + + #[rocket::async_test] + async fn fail_mfa() { + let harness = TestHarness::new().await; + let (mut account, session, _) = harness.new_user().await; + + let totp = Totp::Enabled { + secret: "secret".to_string(), + }; + + account.mfa.totp_token = totp.clone(); + account.save(&harness.db).await.unwrap(); + + let res = harness.client + .delete(format!("/auth/session/{}", session.id)) + .header(Header::new("X-Session-Token", session.token)) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Unauthorized); + } +} diff --git a/crates/delta/src/routes/session/revoke_all.rs b/crates/delta/src/routes/session/revoke_all.rs new file mode 100644 index 000000000..6e1b6f880 --- /dev/null +++ b/crates/delta/src/routes/session/revoke_all.rs @@ -0,0 +1,196 @@ +//! Revoke all sessions +//! DELETE /session/all +use revolt_database::{Account, Database, Session, ValidatedTicket}; +use revolt_result::Result; +use rocket::State; +use rocket_empty::EmptyResponse; + +/// # Delete All Sessions +/// +/// Delete all active sessions, optionally including current one. +#[openapi(tag = "Session")] +#[delete("/all?")] +pub async fn revoke_all( + db: &State, + _ticket: ValidatedTicket, + session: Session, + account: Account, + revoke_self: Option, +) -> Result { + let ignore = if revoke_self.unwrap_or(false) { + None + } else { + Some(session.id) + }; + + account + .delete_all_sessions(db, ignore) + .await + .map(|_| EmptyResponse) +} + +#[cfg(test)] +mod tests { + use crate::{rocket, util::test::TestHarness}; + use revolt_database::{MFATicket, Totp}; + use rocket::http::{Header, Status}; + + #[rocket::async_test] + async fn success() { + let harness = TestHarness::new().await; + let (account, session, _) = harness.new_user().await; + + for i in 1..=3 { + account + .create_session(&harness.db, format!("session{}", i)) + .await + .unwrap(); + } + + let ticket = MFATicket::new(account.id.to_string(), true); + ticket.save(&harness.db).await.unwrap(); + + let res = harness.client + .delete("/auth/session/all?revoke_self=true") + .header(Header::new("X-Session-Token", session.token)) + .header(Header::new("X-MFA-Ticket", ticket.token)) + .dispatch() + .await; + + assert_eq!(res.status(), Status::NoContent); + assert!(harness.db + .fetch_sessions(&session.user_id) + .await + .unwrap() + .is_empty()); + } + + #[rocket::async_test] + async fn success_not_including_self() { + let harness = TestHarness::new().await; + let (account, session, _) = harness.new_user().await; + + for i in 1..=3 { + account + .create_session(&harness.db, format!("session{}", i)) + .await + .unwrap(); + } + + let ticket = MFATicket::new(account.id.to_string(), true); + ticket.save(&harness.db).await.unwrap(); + + let res = harness.client + .delete("/auth/session/all?revoke_self=false") + .header(Header::new("X-Session-Token", session.token)) + .header(Header::new("X-MFA-Ticket", ticket.token)) + .dispatch() + .await; + + assert_eq!(res.status(), Status::NoContent); + let sessions = harness.db + .fetch_sessions(&session.user_id) + .await + .unwrap(); + + assert_eq!(sessions.len(), 1); + assert_eq!(sessions[0].id, session.id); + } + + #[rocket::async_test] + async fn success_mfa() { + let harness = TestHarness::new().await; + let (mut account, session, _) = harness.new_user().await; + + let totp = Totp::Enabled { + secret: "secret".to_string(), + }; + + account.mfa.totp_token = totp.clone(); + account.save(&harness.db).await.unwrap(); + + for i in 1..=3 { + account + .create_session(&harness.db, format!("session{}", i)) + .await + .unwrap(); + } + + let ticket = MFATicket::new(account.id.to_string(), true); + ticket.save(&harness.db).await.unwrap(); + + let res = harness.client + .delete("/auth/session/all?revoke_self=true") + .header(Header::new("X-Session-Token", session.token)) + .header(Header::new("X-MFA-Ticket", ticket.token)) + .dispatch() + .await; + + assert_eq!(res.status(), Status::NoContent); + assert!(harness.db + .fetch_sessions(&session.user_id) + .await + .unwrap() + .is_empty()); + } + + #[rocket::async_test] + async fn success_not_including_self_mfa() { + let harness = TestHarness::new().await; + let (mut account, session, _) = harness.new_user().await; + + let totp = Totp::Enabled { + secret: "secret".to_string(), + }; + + account.mfa.totp_token = totp.clone(); + account.save(&harness.db).await.unwrap(); + + for i in 1..=3 { + account + .create_session(&harness.db, format!("session{}", i)) + .await + .unwrap(); + } + + let ticket = MFATicket::new(account.id.to_string(), true); + ticket.save(&harness.db).await.unwrap(); + + let res = harness.client + .delete("/auth/session/all?revoke_self=false") + .header(Header::new("X-Session-Token", session.token)) + .header(Header::new("X-MFA-Ticket", ticket.token)) + .dispatch() + .await; + + assert_eq!(res.status(), Status::NoContent); + let sessions = harness.db + .fetch_sessions(&session.user_id) + .await + .unwrap(); + + assert_eq!(sessions.len(), 1); + assert_eq!(sessions[0].id, session.id); + } + + #[rocket::async_test] + async fn fail_mfa() { + let harness = TestHarness::new().await; + let (mut account, session, _) = harness.new_user().await; + + let totp = Totp::Enabled { + secret: "secret".to_string(), + }; + + account.mfa.totp_token = totp.clone(); + account.save(&harness.db).await.unwrap(); + + let res = harness.client + .delete("/auth/session/all") + .header(Header::new("X-Session-Token", session.token)) + .dispatch() + .await; + + assert_eq!(res.status(), Status::Unauthorized); + } +} diff --git a/crates/delta/src/routes/users/change_username.rs b/crates/delta/src/routes/users/change_username.rs index 7c3f98c97..ba097b695 100644 --- a/crates/delta/src/routes/users/change_username.rs +++ b/crates/delta/src/routes/users/change_username.rs @@ -1,7 +1,6 @@ -use authifier::models::Account; use once_cell::sync::Lazy; use regex::Regex; -use revolt_database::{Database, User}; +use revolt_database::{Database, User, Account}; use revolt_models::v0; use revolt_result::{create_error, Result}; use rocket::{serde::json::Json, State}; diff --git a/crates/delta/src/util/mod.rs b/crates/delta/src/util/mod.rs index 61e6d0dae..1c32be841 100644 --- a/crates/delta/src/util/mod.rs +++ b/crates/delta/src/util/mod.rs @@ -1,2 +1,4 @@ pub mod ratelimits; + +#[cfg(test)] pub mod test; diff --git a/crates/delta/src/util/test.rs b/crates/delta/src/util/test.rs index 3c8d6835c..731129a70 100644 --- a/crates/delta/src/util/test.rs +++ b/crates/delta/src/util/test.rs @@ -1,22 +1,24 @@ -use authifier::{ - models::{Account, EmailVerification, Session}, - Authifier, -}; +use std::time::Duration; + use futures::StreamExt; use rand::Rng; -use redis_kiss::{redis::aio::PubSub}; +use redis_kiss::redis::aio::PubSub; +use revolt_database::util::email::normalise_email; +use revolt_database::util::password::hash_password; use revolt_database::{ events::client::EventV1, Channel, Database, Member, Message, PartialRole, Server, User, AMQP, }; use revolt_database::{util::idempotency::IdempotencyKey, Role}; +use revolt_database::{Account, EmailVerification, Session}; use revolt_models::v0; use revolt_permissions::OverrideField; use rocket::http::Header; use rocket::local::asynchronous::{Client, LocalRequest, LocalResponse}; +use rocket::tokio; +use serde::{Deserialize, Serialize}; pub struct TestHarness { pub client: Client, - authifier: Authifier, pub db: Database, pub amqp: AMQP, sub: PubSub, @@ -41,17 +43,10 @@ impl TestHarness { .expect("`Database`") .clone(); - let authifier = client - .rocket() - .state::() - .expect("`Authifier`") - .clone(); - let amqp = AMQP::new_auto().await; TestHarness { client, - authifier, db, amqp, sub, @@ -79,11 +74,12 @@ impl TestHarness { } pub async fn account_from_user(&self, id: String) -> (Account, Session) { + let email = format!("{}@stoat.chat", TestHarness::rand_string()); let account = Account { id, - email: format!("{}@revolt.chat", TestHarness::rand_string()), - password: Default::default(), - email_normalised: Default::default(), + email: email.clone(), + password: hash_password("password_insecure".to_string()).unwrap(), + email_normalised: normalise_email(email), deletion: None, disabled: false, lockout: None, @@ -92,14 +88,10 @@ impl TestHarness { verification: EmailVerification::Verified, }; - self.authifier - .database - .save_account(&account) - .await - .expect("`Account`"); + self.db.save_account(&account).await.expect("`Account`"); let session = account - .create_session(&self.authifier, String::new()) + .create_session(&self.db, String::new()) .await .expect("`Session`"); @@ -237,6 +229,40 @@ impl TestHarness { unreachable!() } + pub async fn assert_email(&self, mailbox: &str) -> (Mail, String) { + // Wait a moment for maildev to catch the email + + tokio::time::sleep(Duration::from_secs(1)).await; + + let client = reqwest::Client::new(); + let results = client + .get("http://localhost:14080/email") + .send() + .await + .unwrap() + .json::>() + .await + .unwrap(); + + let re = regex::Regex::new(r"\[\[([A-Za-z0-9_-]*)\]\]").unwrap(); + + for entry in results.into_iter().rev() { + if entry.envelope.to[0].address == mailbox { + client + .delete(format!("http://localhost:14080/delete/{}", &entry.id)) + .send() + .await + .unwrap(); + + let code = re.captures_iter(&entry.text).next().unwrap()[1].to_string(); + + return (entry, code); + } + } + + panic!("Email not found.") + } + pub async fn wait_for_message(&mut self, channel_id: &str) -> v0::Message { dbg!(&self.event_buffer); @@ -252,3 +278,22 @@ impl TestHarness { } } } + +#[derive(Debug, Serialize, Deserialize)] +pub struct Mail { + pub id: String, + pub envelope: MailEnvelope, + pub subject: String, + pub text: String, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct MailEnvelope { + pub from: MailAddress, + pub to: Vec, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct MailAddress { + pub address: String, +} From ffab2369ab5c9b88e007dcd74b91bb48e1988d26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0spik?= Date: Sun, 21 Jun 2026 10:55:23 +0300 Subject: [PATCH 200/211] feat: add pronouns to user and server members field (#811) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: İspik --- .../database/src/models/server_members/model.rs | 6 ++++++ .../src/models/server_members/ops/mongodb.rs | 1 + crates/core/database/src/models/users/model.rs | 6 ++++++ .../core/database/src/models/users/ops/mongodb.rs | 1 + crates/core/database/src/util/bridge/v0.rs | 14 ++++++++++++++ crates/core/models/src/v0/server_members.rs | 7 +++++++ crates/core/models/src/v0/users.rs | 7 +++++++ crates/delta/src/routes/channels/message_send.rs | 2 ++ crates/delta/src/routes/servers/member_edit.rs | 8 ++++++++ crates/delta/src/routes/users/edit_user.rs | 2 ++ 10 files changed, 54 insertions(+) diff --git a/crates/core/database/src/models/server_members/model.rs b/crates/core/database/src/models/server_members/model.rs index e242c62f5..2b8d3761d 100644 --- a/crates/core/database/src/models/server_members/model.rs +++ b/crates/core/database/src/models/server_members/model.rs @@ -28,6 +28,9 @@ auto_derived_partial!( /// Member's nickname #[serde(skip_serializing_if = "Option::is_none")] pub nickname: Option, + /// Member's pronouns + #[serde(skip_serializing_if = "Option::is_none")] + pub pronouns: Option, /// Avatar attachment #[serde(skip_serializing_if = "Option::is_none")] pub avatar: Option, @@ -65,6 +68,7 @@ auto_derived!( /// Optional fields on server member object pub enum FieldsMember { Nickname, + Pronouns, Avatar, Roles, Timeout, @@ -88,6 +92,7 @@ impl Default for Member { id: Default::default(), joined_at: Timestamp::now_utc(), nickname: None, + pronouns: None, avatar: None, roles: vec![], timeout: None, @@ -231,6 +236,7 @@ impl Member { FieldsMember::JoinedAt => {} FieldsMember::Avatar => self.avatar = None, FieldsMember::Nickname => self.nickname = None, + FieldsMember::Pronouns => self.pronouns = None, FieldsMember::Roles => self.roles.clear(), FieldsMember::Timeout => self.timeout = None, FieldsMember::CanReceive => self.can_receive = true, diff --git a/crates/core/database/src/models/server_members/ops/mongodb.rs b/crates/core/database/src/models/server_members/ops/mongodb.rs index 99cce7c9d..f9db0d350 100644 --- a/crates/core/database/src/models/server_members/ops/mongodb.rs +++ b/crates/core/database/src/models/server_members/ops/mongodb.rs @@ -345,6 +345,7 @@ impl IntoDocumentPath for FieldsMember { FieldsMember::JoinedAt => Some("joined_at"), FieldsMember::Avatar => Some("avatar"), FieldsMember::Nickname => Some("nickname"), + FieldsMember::Pronouns => Some("pronouns"), FieldsMember::Roles => Some("roles"), FieldsMember::Timeout => Some("timeout"), FieldsMember::CanPublish => Some("can_publish"), diff --git a/crates/core/database/src/models/users/model.rs b/crates/core/database/src/models/users/model.rs index 834485191..cb2d3dfe3 100644 --- a/crates/core/database/src/models/users/model.rs +++ b/crates/core/database/src/models/users/model.rs @@ -31,6 +31,9 @@ auto_derived_partial!( /// Display name #[serde(skip_serializing_if = "Option::is_none")] pub display_name: Option, + /// User's pronouns + #[serde(skip_serializing_if = "Option::is_none", default)] + pub pronouns: Option, #[serde(skip_serializing_if = "Option::is_none")] /// Avatar attachment pub avatar: Option, @@ -76,6 +79,7 @@ auto_derived!( ProfileContent, ProfileBackground, DisplayName, + Pronouns, // internal fields Suspension, @@ -182,6 +186,7 @@ impl Default for User { username: Default::default(), discriminator: Default::default(), display_name: Default::default(), + pronouns: Default::default(), avatar: Default::default(), relations: Default::default(), badges: Default::default(), @@ -706,6 +711,7 @@ impl User { } } FieldsUser::DisplayName => self.display_name = None, + FieldsUser::Pronouns => self.pronouns = None, FieldsUser::Suspension => self.suspended_until = None, FieldsUser::None => {} } diff --git a/crates/core/database/src/models/users/ops/mongodb.rs b/crates/core/database/src/models/users/ops/mongodb.rs index 0a6f641f7..b2a8eb1df 100644 --- a/crates/core/database/src/models/users/ops/mongodb.rs +++ b/crates/core/database/src/models/users/ops/mongodb.rs @@ -336,6 +336,7 @@ impl IntoDocumentPath for FieldsUser { FieldsUser::StatusPresence => "status.presence", FieldsUser::StatusText => "status.text", FieldsUser::DisplayName => "display_name", + FieldsUser::Pronouns => "pronouns", FieldsUser::Suspension => "suspended_until", FieldsUser::None => "none", }) diff --git a/crates/core/database/src/util/bridge/v0.rs b/crates/core/database/src/util/bridge/v0.rs index 911bc3717..2cce67999 100644 --- a/crates/core/database/src/util/bridge/v0.rs +++ b/crates/core/database/src/util/bridge/v0.rs @@ -631,6 +631,7 @@ impl From for Member { id: value.id.into(), joined_at: value.joined_at, nickname: value.nickname, + pronouns: value.pronouns, avatar: value.avatar.map(|f| f.into()), roles: value.roles, timeout: value.timeout, @@ -646,6 +647,7 @@ impl From for crate::Member { id: value.id.into(), joined_at: value.joined_at, nickname: value.nickname, + pronouns: value.pronouns, avatar: value.avatar.map(|f| f.into()), roles: value.roles, timeout: value.timeout, @@ -661,6 +663,7 @@ impl From for PartialMember { id: value.id.map(|id| id.into()), joined_at: value.joined_at, nickname: value.nickname, + pronouns: value.pronouns, avatar: value.avatar.map(|f| f.into()), roles: value.roles, timeout: value.timeout, @@ -676,6 +679,7 @@ impl From for crate::PartialMember { id: value.id.map(|id| id.into()), joined_at: value.joined_at, nickname: value.nickname, + pronouns: value.pronouns, avatar: value.avatar.map(|f| f.into()), roles: value.roles, timeout: value.timeout, @@ -708,6 +712,7 @@ impl From for FieldsMember { match value { crate::FieldsMember::Avatar => FieldsMember::Avatar, crate::FieldsMember::Nickname => FieldsMember::Nickname, + crate::FieldsMember::Pronouns => FieldsMember::Pronouns, crate::FieldsMember::Roles => FieldsMember::Roles, crate::FieldsMember::Timeout => FieldsMember::Timeout, crate::FieldsMember::CanReceive => FieldsMember::CanReceive, @@ -723,6 +728,7 @@ impl From for crate::FieldsMember { match value { FieldsMember::Avatar => crate::FieldsMember::Avatar, FieldsMember::Nickname => crate::FieldsMember::Nickname, + FieldsMember::Pronouns => crate::FieldsMember::Pronouns, FieldsMember::Roles => crate::FieldsMember::Roles, FieldsMember::Timeout => crate::FieldsMember::Timeout, FieldsMember::CanReceive => crate::FieldsMember::CanReceive, @@ -1032,6 +1038,7 @@ impl crate::User { username: self.username, discriminator: self.discriminator, display_name: self.display_name, + pronouns: self.pronouns, avatar: self.avatar.map(|file| file.into()), relations: if let Some(crate::User { id, .. }) = perspective { if id == &self.id { @@ -1108,6 +1115,7 @@ impl crate::User { username: self.username, discriminator: self.discriminator, display_name: self.display_name, + pronouns: self.pronouns, avatar: self.avatar.map(|file| file.into()), relations: vec![], badges, @@ -1141,6 +1149,7 @@ impl crate::User { username: self.username, discriminator: self.discriminator, display_name: self.display_name, + pronouns: self.pronouns, avatar: self.avatar.map(|file| file.into()), relations: vec![], badges, @@ -1168,6 +1177,7 @@ impl crate::User { username: self.username, discriminator: self.discriminator, display_name: self.display_name, + pronouns: self.pronouns, avatar: self.avatar.map(|file| file.into()), relations: self .relations @@ -1211,6 +1221,7 @@ impl From for crate::User { username: value.username, discriminator: value.discriminator, display_name: value.display_name, + pronouns: value.pronouns, avatar: value.avatar.map(Into::into), relations: None, badges: Some(value.badges as i32), @@ -1231,6 +1242,7 @@ impl From for PartialUser { username: value.username, discriminator: value.discriminator, display_name: value.display_name, + pronouns: value.pronouns, avatar: value.avatar.map(|file| file.into()), relations: value.relations.map(|relationships| { relationships @@ -1259,6 +1271,7 @@ impl From for crate::FieldsUser { FieldsUser::StatusPresence => crate::FieldsUser::StatusPresence, FieldsUser::StatusText => crate::FieldsUser::StatusText, FieldsUser::DisplayName => crate::FieldsUser::DisplayName, + FieldsUser::Pronouns => crate::FieldsUser::Pronouns, FieldsUser::Internal => crate::FieldsUser::None, } @@ -1274,6 +1287,7 @@ impl From for FieldsUser { crate::FieldsUser::StatusPresence => FieldsUser::StatusPresence, crate::FieldsUser::StatusText => FieldsUser::StatusText, crate::FieldsUser::DisplayName => FieldsUser::DisplayName, + crate::FieldsUser::Pronouns => FieldsUser::Pronouns, crate::FieldsUser::Suspension => FieldsUser::Internal, crate::FieldsUser::None => FieldsUser::Internal, diff --git a/crates/core/models/src/v0/server_members.rs b/crates/core/models/src/v0/server_members.rs index 41ec99ae8..bcded0b08 100644 --- a/crates/core/models/src/v0/server_members.rs +++ b/crates/core/models/src/v0/server_members.rs @@ -52,6 +52,9 @@ auto_derived_partial!( /// Member's nickname #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] pub nickname: Option, + /// Member's pronouns + #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + pub pronouns: Option, /// Avatar attachment #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] pub avatar: Option, @@ -89,6 +92,7 @@ auto_derived!( /// Optional fields on server member object pub enum FieldsMember { Nickname, + Pronouns, Avatar, Roles, Timeout, @@ -136,6 +140,9 @@ auto_derived!( /// Member nickname #[cfg_attr(feature = "validator", validate(length(min = 1, max = 32)))] pub nickname: Option, + /// Member pronouns + #[cfg_attr(feature = "validator", validate(length(min = 1, max = 24)))] + pub pronouns: Option, /// Attachment Id to set for avatar pub avatar: Option, /// Array of role ids diff --git a/crates/core/models/src/v0/users.rs b/crates/core/models/src/v0/users.rs index 73957768b..217324c28 100644 --- a/crates/core/models/src/v0/users.rs +++ b/crates/core/models/src/v0/users.rs @@ -32,6 +32,9 @@ auto_derived_partial!( /// Display name #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] pub display_name: Option, + /// User's pronouns + #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] + pub pronouns: Option, #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] /// Avatar attachment pub avatar: Option, @@ -89,6 +92,7 @@ auto_derived!( ProfileContent, ProfileBackground, DisplayName, + Pronouns, /// Internal field, ignore this. Internal, @@ -225,6 +229,9 @@ auto_derived!( validate(length(min = 2, max = 32), regex = "RE_DISPLAY_NAME") )] pub display_name: Option, + /// New pronouns + #[cfg_attr(feature = "validator", validate(length(min = 1, max = 24)))] + pub pronouns: Option, /// Attachment Id for avatar #[cfg_attr(feature = "validator", validate(length(min = 1, max = 128)))] pub avatar: Option, diff --git a/crates/delta/src/routes/channels/message_send.rs b/crates/delta/src/routes/channels/message_send.rs index e6551d0c4..a809df0c1 100644 --- a/crates/delta/src/routes/channels/message_send.rs +++ b/crates/delta/src/routes/channels/message_send.rs @@ -359,6 +359,7 @@ mod test { id: None, joined_at: None, nickname: None, + pronouns: None, avatar: None, timeout: None, roles: Some(second_member_roles), @@ -688,6 +689,7 @@ mod test { id: None, joined_at: None, nickname: None, + pronouns: None, roles: Some(vec![role.id.clone()]), timeout: None, can_publish: None, diff --git a/crates/delta/src/routes/servers/member_edit.rs b/crates/delta/src/routes/servers/member_edit.rs index e3f63e498..848e776f7 100644 --- a/crates/delta/src/routes/servers/member_edit.rs +++ b/crates/delta/src/routes/servers/member_edit.rs @@ -64,6 +64,12 @@ pub async fn edit( } } + if data.pronouns.is_some() || data.remove.contains(&v0::FieldsMember::Pronouns) { + if user.id != member.id.user { + return Err(create_error!(InvalidOperation)) + } + } + if data.avatar.is_some() || data.remove.contains(&v0::FieldsMember::Avatar) { if user.id == member.id.user { permissions.throw_if_lacking_channel_permission(ChannelPermission::ChangeAvatar)?; @@ -172,6 +178,7 @@ pub async fn edit( // Apply edits to the member object let v0::DataMemberEdit { nickname, + pronouns, avatar, roles, timeout, @@ -183,6 +190,7 @@ pub async fn edit( let mut partial = PartialMember { nickname, + pronouns, roles, timeout, can_publish, diff --git a/crates/delta/src/routes/users/edit_user.rs b/crates/delta/src/routes/users/edit_user.rs index 535fc05c9..1334909f1 100644 --- a/crates/delta/src/routes/users/edit_user.rs +++ b/crates/delta/src/routes/users/edit_user.rs @@ -48,6 +48,7 @@ pub async fn edit( // Exit out early if nothing is changed if data.display_name.is_none() + && data.pronouns.is_none() && data.status.is_none() && data.profile.is_none() && data.avatar.is_none() @@ -80,6 +81,7 @@ pub async fn edit( let mut partial: PartialUser = PartialUser { display_name: data.display_name, + pronouns: data.pronouns, badges: data.badges, flags: data.flags, ..Default::default() From abdba5ce93f100f47c6e75a4d1240e517720b44e Mon Sep 17 00:00:00 2001 From: "stoat-release[bot]" <245062572+stoat-release[bot]@users.noreply.github.com> Date: Sun, 21 Jun 2026 20:19:14 -0700 Subject: [PATCH 201/211] chore(deps): update rust crate chrono to v0.4.45 (#815) Co-authored-by: stoat-release[bot] <245062572+stoat-release[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b9c27cd5f..dff583677 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1615,9 +1615,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.44" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" dependencies = [ "iana-time-zone", "js-sys", From a386e84c7d2323e47ec15dda808b8138b4e7b221 Mon Sep 17 00:00:00 2001 From: "stoat-release[bot]" <245062572+stoat-release[bot]@users.noreply.github.com> Date: Sun, 21 Jun 2026 20:23:23 -0700 Subject: [PATCH 202/211] chore(deps): update rust crate aws-config to v1.8.18 (#799) Co-authored-by: stoat-release[bot] <245062572+stoat-release[bot]@users.noreply.github.com> --- Cargo.lock | 235 +++++++++++++++++------------------------------------ 1 file changed, 73 insertions(+), 162 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dff583677..d33a9fdef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -637,9 +637,9 @@ dependencies = [ [[package]] name = "aws-config" -version = "1.8.16" +version = "1.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f156acdd2cf55f5aa53ee416c4ac851cf1222694506c0b1f78c85695e9ca9d" +checksum = "e33f815b73a3899c03b380d543532e5865f230dce9678d108dc10732a8682275" dependencies = [ "aws-credential-types", "aws-runtime", @@ -651,6 +651,7 @@ dependencies = [ "aws-smithy-json", "aws-smithy-runtime", "aws-smithy-runtime-api", + "aws-smithy-schema", "aws-smithy-types", "aws-types", "bytes 1.11.1", @@ -701,9 +702,9 @@ dependencies = [ [[package]] name = "aws-runtime" -version = "1.7.3" +version = "1.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dcd93c82209ac7413532388067dce79be5a8780c1786e5fae3df22e4dee2864" +checksum = "6c9b9de216a988dd54b754a82a7660cfe14cee4f6782ae4524470972fa0ccb39" dependencies = [ "aws-credential-types", "aws-sigv4", @@ -764,10 +765,11 @@ dependencies = [ [[package]] name = "aws-sdk-sso" -version = "1.98.0" +version = "1.102.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d69c77aafa20460c68b6b3213c84f6423b6e76dbf89accd3e1789a686ffd9489" +checksum = "8c82b3ac19f1431854f7ace3a7531674633e286bfdde21976893bfee36fd493b" dependencies = [ + "arc-swap", "aws-credential-types", "aws-runtime", "aws-smithy-async", @@ -788,10 +790,11 @@ dependencies = [ [[package]] name = "aws-sdk-ssooidc" -version = "1.100.0" +version = "1.104.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c7e7b09346d5ca22a2a08267555843a6a0127fb20d8964cb6ecfb8fdb190225" +checksum = "321000d2b4c5519ee573f73167f612efd7329322d9b26969ad1979f0427f1913" dependencies = [ + "arc-swap", "aws-credential-types", "aws-runtime", "aws-smithy-async", @@ -812,10 +815,11 @@ dependencies = [ [[package]] name = "aws-sdk-sts" -version = "1.103.0" +version = "1.107.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2249b81a2e73a8027c41c378463a81ec39b8510f184f2caab87de912af0f49b" +checksum = "3d0d328ba962af23ecfa3c9f23b98d3d35e325fa218d7f13d17a6bf522f8a560" dependencies = [ + "arc-swap", "aws-credential-types", "aws-runtime", "aws-smithy-async", @@ -837,9 +841,9 @@ dependencies = [ [[package]] name = "aws-sigv4" -version = "1.4.3" +version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68dc0b907359b120170613b5c09ccc61304eac3998ff6274b97d93ee6490115a" +checksum = "bae38512beae0ffee7010fc24e7a8a123c53efdfef42a61e80fda4882418dc71" dependencies = [ "aws-credential-types", "aws-smithy-eventstream", @@ -847,15 +851,14 @@ dependencies = [ "aws-smithy-runtime-api", "aws-smithy-types", "bytes 1.11.1", - "crypto-bigint 0.5.5", + "crypto-bigint", "form_urlencoded", "hex", "hmac 0.13.0", "http 0.2.12", "http 1.4.0", - "p256 0.11.1", + "p256", "percent-encoding", - "ring", "sha2 0.11.0", "subtle", "time", @@ -897,9 +900,9 @@ dependencies = [ [[package]] name = "aws-smithy-eventstream" -version = "0.60.20" +version = "0.60.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faf09d74e5e32f76b8762da505a3cd59303e367a664ca67295387baa8c1d7548" +checksum = "78d8391e65fcea47c586a22e1a41f173b38615b112b2c6b7a44e80cec3e6b706" dependencies = [ "aws-smithy-types", "bytes 1.11.1", @@ -960,10 +963,12 @@ dependencies = [ [[package]] name = "aws-smithy-json" -version = "0.62.5" +version = "0.62.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9648b0bb82a2eedd844052c6ad2a1a822d1f8e3adee5fbf668366717e428856a" +checksum = "701a947f4797e52a911e114a898667c746c39feea467bbd1abd7b3721f702ffa" dependencies = [ + "aws-smithy-runtime-api", + "aws-smithy-schema", "aws-smithy-types", ] @@ -988,15 +993,16 @@ dependencies = [ [[package]] name = "aws-smithy-runtime" -version = "1.11.1" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0504b1ab12debb5959e5165ee5fe97dd387e7aa7ea6a477bfd7635dfe769a4f5" +checksum = "b8e6f5caf6fea86f8c2206541ab5857cfcda9013426cdbe8fa0098b9e2d32182" dependencies = [ "aws-smithy-async", "aws-smithy-http", "aws-smithy-http-client", "aws-smithy-observability", "aws-smithy-runtime-api", + "aws-smithy-schema", "aws-smithy-types", "bytes 1.11.1", "fastrand 2.4.1", @@ -1013,9 +1019,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime-api" -version = "1.12.0" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71a13df6ada0aafbf21a73bdfcdf9324cfa9df77d96b8446045be3cde61b42e" +checksum = "9db177daa6ba8afb9ee1aefcf548c907abcf52065e394ee11a92780057fe0e8c" dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api-macros", @@ -1040,11 +1046,22 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "aws-smithy-schema" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7442cb268338f0eb8278140a107c046756aa01093d8ef5e99628d34ae09c94f5" +dependencies = [ + "aws-smithy-runtime-api", + "aws-smithy-types", + "http 1.4.0", +] + [[package]] name = "aws-smithy-types" -version = "1.4.7" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d73dbfbaa8e4bc57b9045137680b958d274823509a360abfd8e1d514d40c95c" +checksum = "32b42fcf341259d85ca10fac9a2f6448a8ec691c6955a18e45bc3b71a85fab85" dependencies = [ "base64-simd", "bytes 1.11.1", @@ -1077,13 +1094,14 @@ dependencies = [ [[package]] name = "aws-types" -version = "1.3.15" +version = "1.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f4bbcaa9304ea40902d3d5f42a0428d1bd895a2b0f6999436fb279ffddc58ac" +checksum = "d16bf10b03a3c01e6b3b7d47cd964e873ffe9e7d4e80fad16bd4c077cb068531" dependencies = [ "aws-credential-types", "aws-smithy-async", "aws-smithy-runtime-api", + "aws-smithy-schema", "aws-smithy-types", "rustc_version", "tracing", @@ -1238,12 +1256,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "base16ct" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" - [[package]] name = "base16ct" version = "0.2.0" @@ -1951,18 +1963,6 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" -[[package]] -name = "crypto-bigint" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" -dependencies = [ - "generic-array 0.14.7", - "rand_core 0.6.4", - "subtle", - "zeroize", -] - [[package]] name = "crypto-bigint" version = "0.5.5" @@ -2566,18 +2566,6 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" -[[package]] -name = "ecdsa" -version = "0.14.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" -dependencies = [ - "der 0.6.1", - "elliptic-curve 0.12.3", - "rfc6979 0.3.1", - "signature 1.6.4", -] - [[package]] name = "ecdsa" version = "0.16.9" @@ -2586,8 +2574,8 @@ checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ "der 0.7.10", "digest 0.10.7", - "elliptic-curve 0.13.8", - "rfc6979 0.4.0", + "elliptic-curve", + "rfc6979", "signature 2.2.0", "spki 0.7.3", ] @@ -2656,43 +2644,23 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" -[[package]] -name = "elliptic-curve" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" -dependencies = [ - "base16ct 0.1.1", - "crypto-bigint 0.4.9", - "der 0.6.1", - "digest 0.10.7", - "ff 0.12.1", - "generic-array 0.14.7", - "group 0.12.1", - "pkcs8 0.9.0", - "rand_core 0.6.4", - "sec1 0.3.0", - "subtle", - "zeroize", -] - [[package]] name = "elliptic-curve" version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ - "base16ct 0.2.0", - "crypto-bigint 0.5.5", + "base16ct", + "crypto-bigint", "digest 0.10.7", - "ff 0.13.1", + "ff", "generic-array 0.14.7", - "group 0.13.0", + "group", "hkdf", "pem-rfc7468 0.7.0", "pkcs8 0.10.2", "rand_core 0.6.4", - "sec1 0.7.3", + "sec1", "subtle", "zeroize", ] @@ -2809,7 +2777,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -2906,16 +2874,6 @@ dependencies = [ "simd-adler32", ] -[[package]] -name = "ff" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" -dependencies = [ - "rand_core 0.6.4", - "subtle", -] - [[package]] name = "ff" version = "0.13.1" @@ -3459,24 +3417,13 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "group" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" -dependencies = [ - "ff 0.12.1", - "rand_core 0.6.4", - "subtle", -] - [[package]] name = "group" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ - "ff 0.13.1", + "ff", "rand_core 0.6.4", "subtle", ] @@ -3951,7 +3898,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite 0.2.17", - "socket2 0.5.10", + "socket2 0.4.10", "tokio 1.52.3", "tower-service", "tracing", @@ -4393,7 +4340,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ "hermit-abi 0.5.2", "libc", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -4587,7 +4534,7 @@ dependencies = [ "getrandom 0.2.17", "hmac 0.12.1", "js-sys", - "p256 0.13.2", + "p256", "p384", "rand 0.8.6", "rsa 0.9.10", @@ -4613,7 +4560,7 @@ dependencies = [ "hmac-sha256", "hmac-sha512", "k256", - "p256 0.13.2", + "p256", "p384", "rand 0.8.6", "rsa 0.7.2", @@ -4811,8 +4758,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" dependencies = [ "cfg-if", - "ecdsa 0.16.9", - "elliptic-curve 0.13.8", + "ecdsa", + "elliptic-curve", "once_cell", "sha2 0.10.9", "signature 2.2.0", @@ -5622,7 +5569,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -6052,25 +5999,14 @@ dependencies = [ "x509-parser", ] -[[package]] -name = "p256" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" -dependencies = [ - "ecdsa 0.14.8", - "elliptic-curve 0.12.3", - "sha2 0.10.9", -] - [[package]] name = "p256" version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" dependencies = [ - "ecdsa 0.16.9", - "elliptic-curve 0.13.8", + "ecdsa", + "elliptic-curve", "primeorder", "sha2 0.10.9", ] @@ -6081,8 +6017,8 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6" dependencies = [ - "ecdsa 0.16.9", - "elliptic-curve 0.13.8", + "ecdsa", + "elliptic-curve", "primeorder", "sha2 0.10.9", ] @@ -6751,7 +6687,7 @@ version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" dependencies = [ - "elliptic-curve 0.13.8", + "elliptic-curve", ] [[package]] @@ -6882,7 +6818,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" dependencies = [ "bytes 1.11.1", - "heck 0.5.0", + "heck 0.4.1", "itertools 0.12.1", "log", "multimap", @@ -8047,17 +7983,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "rfc6979" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" -dependencies = [ - "crypto-bigint 0.4.9", - "hmac 0.12.1", - "zeroize", -] - [[package]] name = "rfc6979" version = "0.4.0" @@ -8372,7 +8297,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.12.1", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -8502,7 +8427,7 @@ dependencies = [ "security-framework 3.7.0", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -8682,27 +8607,13 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" -[[package]] -name = "sec1" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" -dependencies = [ - "base16ct 0.1.1", - "der 0.6.1", - "generic-array 0.14.7", - "pkcs8 0.9.0", - "subtle", - "zeroize", -] - [[package]] name = "sec1" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ - "base16ct 0.2.0", + "base16ct", "der 0.7.10", "generic-array 0.14.7", "pkcs8 0.10.2", @@ -9285,7 +9196,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -9610,7 +9521,7 @@ dependencies = [ "getrandom 0.4.2", "once_cell", "rustix 1.1.4", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -10856,7 +10767,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.48.0", ] [[package]] From 34dffa942595b6721fa1d8cf2aca03959aad2250 Mon Sep 17 00:00:00 2001 From: "stoat-release[bot]" <245062572+stoat-release[bot]@users.noreply.github.com> Date: Mon, 22 Jun 2026 12:24:35 -0700 Subject: [PATCH 203/211] chore(deps): update rust crate regex to v1.12.4 (#816) Co-authored-by: stoat-release[bot] <245062572+stoat-release[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d33a9fdef..b1f214fc8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7280,9 +7280,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.12.3" +version = "1.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba" dependencies = [ "aho-corasick", "memchr", @@ -7309,9 +7309,9 @@ checksum = "cab834c73d247e67f4fae452806d17d3c7501756d98c8808d7c9c7aa7d18f973" [[package]] name = "regex-syntax" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "reqwest" From a15a542f439170ad1d0972c51ac999d6c9495588 Mon Sep 17 00:00:00 2001 From: "stoat-release[bot]" <245062572+stoat-release[bot]@users.noreply.github.com> Date: Mon, 22 Jun 2026 12:26:53 -0700 Subject: [PATCH 204/211] chore(deps): update react monorepo to v19.2.7 (#787) Co-authored-by: stoat-release[bot] <245062572+stoat-release[bot]@users.noreply.github.com> --- docs/package-lock.json | 495 +++++++++++++++++++++++++++++++++++++-- docs/pnpm-lock.yaml | 512 +++++++++++++++++++++-------------------- 2 files changed, 738 insertions(+), 269 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index 069f607ce..29bc71f8f 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -9,8 +9,10 @@ "version": "0.0.0", "dependencies": { "@docusaurus/core": "3.9.2", + "@docusaurus/plugin-client-redirects": "^3.9.2", "@docusaurus/preset-classic": "3.9.2", "@mdx-js/react": "^3.0.0", + "@scalar/docusaurus": "^0.7.21", "clsx": "^2.0.0", "prism-react-renderer": "^2.3.0", "react": "^19.0.0", @@ -3545,6 +3547,359 @@ "react-dom": "*" } }, + "node_modules/@docusaurus/plugin-client-redirects": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-client-redirects/-/plugin-client-redirects-3.10.1.tgz", + "integrity": "sha512-LHgd+YDvkhfOHMAE6XtUng3DQNzVM765RqVRrMJgHtzAvfopQhY6ieprqjxDVBdv21cLma6I0jHr+YCZH8fL9A==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.10.1", + "@docusaurus/logger": "3.10.1", + "@docusaurus/utils": "3.10.1", + "@docusaurus/utils-common": "3.10.1", + "@docusaurus/utils-validation": "3.10.1", + "eta": "^2.2.0", + "fs-extra": "^11.1.1", + "lodash": "^4.17.21", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-client-redirects/node_modules/@docusaurus/babel": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/babel/-/babel-3.10.1.tgz", + "integrity": "sha512-DZzFO1K3v/GoEt1fx1DiYHF4en+PuhtQf1AkQJa5zu3CoeKSpr5cpQRUlz3jr0m44wyzmSXu9bVpfir+N4+8bg==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-transform-runtime": "^7.25.9", + "@babel/preset-env": "^7.25.9", + "@babel/preset-react": "^7.25.9", + "@babel/preset-typescript": "^7.25.9", + "@babel/runtime": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@docusaurus/logger": "3.10.1", + "@docusaurus/utils": "3.10.1", + "babel-plugin-dynamic-import-node": "^2.3.3", + "fs-extra": "^11.1.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/plugin-client-redirects/node_modules/@docusaurus/bundler": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/bundler/-/bundler-3.10.1.tgz", + "integrity": "sha512-HIqQPvbqnnQRe4NsBd1774KRarjXqS6wHsWELtyuSs1gCfvixJO2jUGH/OEBtr1Gvzpw+ze5CjGMvSJ8UE1KUw==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.25.9", + "@docusaurus/babel": "3.10.1", + "@docusaurus/cssnano-preset": "3.10.1", + "@docusaurus/logger": "3.10.1", + "@docusaurus/types": "3.10.1", + "@docusaurus/utils": "3.10.1", + "babel-loader": "^9.2.1", + "clean-css": "^5.3.3", + "copy-webpack-plugin": "^11.0.0", + "css-loader": "^6.11.0", + "css-minimizer-webpack-plugin": "^5.0.1", + "cssnano": "^6.1.2", + "file-loader": "^6.2.0", + "html-minifier-terser": "^7.2.0", + "mini-css-extract-plugin": "^2.9.2", + "null-loader": "^4.0.1", + "postcss": "^8.5.4", + "postcss-loader": "^7.3.4", + "postcss-preset-env": "^10.2.1", + "terser-webpack-plugin": "^5.3.9", + "tslib": "^2.6.0", + "url-loader": "^4.1.1", + "webpack": "^5.95.0", + "webpackbar": "^7.0.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "@docusaurus/faster": "*" + }, + "peerDependenciesMeta": { + "@docusaurus/faster": { + "optional": true + } + } + }, + "node_modules/@docusaurus/plugin-client-redirects/node_modules/@docusaurus/core": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.10.1.tgz", + "integrity": "sha512-3pf2fXXw0eVk8WnC3T4LIigRDupcpvngpKo9Vy7mYyBhuddc0klDUuZAIfzMoK6z05pdlk6EFC/vBSX43+1O5w==", + "license": "MIT", + "dependencies": { + "@docusaurus/babel": "3.10.1", + "@docusaurus/bundler": "3.10.1", + "@docusaurus/logger": "3.10.1", + "@docusaurus/mdx-loader": "3.10.1", + "@docusaurus/utils": "3.10.1", + "@docusaurus/utils-common": "3.10.1", + "@docusaurus/utils-validation": "3.10.1", + "boxen": "^6.2.1", + "chalk": "^4.1.2", + "chokidar": "^3.5.3", + "cli-table3": "^0.6.3", + "combine-promises": "^1.1.0", + "commander": "^5.1.0", + "core-js": "^3.31.1", + "detect-port": "^1.5.1", + "escape-html": "^1.0.3", + "eta": "^2.2.0", + "eval": "^0.1.8", + "execa": "^5.1.1", + "fs-extra": "^11.1.1", + "html-tags": "^3.3.1", + "html-webpack-plugin": "^5.6.0", + "leven": "^3.1.0", + "lodash": "^4.17.21", + "open": "^8.4.0", + "p-map": "^4.0.0", + "prompts": "^2.4.2", + "react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0", + "react-loadable": "npm:@docusaurus/react-loadable@6.0.0", + "react-loadable-ssr-addon-v5-slorber": "^1.0.3", + "react-router": "^5.3.4", + "react-router-config": "^5.1.1", + "react-router-dom": "^5.3.4", + "semver": "^7.5.4", + "serve-handler": "^6.1.7", + "tinypool": "^1.0.2", + "tslib": "^2.6.0", + "update-notifier": "^6.0.2", + "webpack": "^5.95.0", + "webpack-bundle-analyzer": "^4.10.2", + "webpack-dev-server": "^5.2.2", + "webpack-merge": "^6.0.1" + }, + "bin": { + "docusaurus": "bin/docusaurus.mjs" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "@docusaurus/faster": "*", + "@mdx-js/react": "^3.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@docusaurus/faster": { + "optional": true + } + } + }, + "node_modules/@docusaurus/plugin-client-redirects/node_modules/@docusaurus/cssnano-preset": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.10.1.tgz", + "integrity": "sha512-eNfHGcTKCSq6xmcavAkX3RRclHaE2xRCMParlDXLdXVP01/a2e/jKXMj/0ULnLFQSNwwuI62L0Ge8J+nZsR7UQ==", + "license": "MIT", + "dependencies": { + "cssnano-preset-advanced": "^6.1.2", + "postcss": "^8.5.4", + "postcss-sort-media-queries": "^5.2.0", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/plugin-client-redirects/node_modules/@docusaurus/logger": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.10.1.tgz", + "integrity": "sha512-oPjNFnfJsRCkePVjkGrxWGq4MvJKRQT0r9jOP0eRBTZ7Wr9FAbzdP/Gjs0I2Ss6YRkPoEgygKG112OkE6skvJw==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/plugin-client-redirects/node_modules/@docusaurus/mdx-loader": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.10.1.tgz", + "integrity": "sha512-GRmeb/wQ+iXRrFwcHBfgQhrJxGElgCsoTWZYDhccjsZVne1p8MK/EpQVIloXttz76TCe78kKD5AEG9n1xc1oxQ==", + "license": "MIT", + "dependencies": { + "@docusaurus/logger": "3.10.1", + "@docusaurus/utils": "3.10.1", + "@docusaurus/utils-validation": "3.10.1", + "@mdx-js/mdx": "^3.0.0", + "@slorber/remark-comment": "^1.0.0", + "escape-html": "^1.0.3", + "estree-util-value-to-estree": "^3.0.1", + "file-loader": "^6.2.0", + "fs-extra": "^11.1.1", + "image-size": "^2.0.2", + "mdast-util-mdx": "^3.0.0", + "mdast-util-to-string": "^4.0.0", + "rehype-raw": "^7.0.0", + "remark-directive": "^3.0.0", + "remark-emoji": "^4.0.0", + "remark-frontmatter": "^5.0.0", + "remark-gfm": "^4.0.0", + "stringify-object": "^3.3.0", + "tslib": "^2.6.0", + "unified": "^11.0.3", + "unist-util-visit": "^5.0.0", + "url-loader": "^4.1.1", + "vfile": "^6.0.1", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-client-redirects/node_modules/@docusaurus/types": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.10.1.tgz", + "integrity": "sha512-XYMK8k1szDCFMw2V+Xyen0g7Kee1sP3dtFnl7vkGkZOkeAJ/oPDQPL8iz4HBKOo/cwU8QeV6onVjMqtP+tFzsw==", + "license": "MIT", + "dependencies": { + "@mdx-js/mdx": "^3.0.0", + "@types/history": "^4.7.11", + "@types/mdast": "^4.0.2", + "@types/react": "*", + "commander": "^5.1.0", + "joi": "^17.9.2", + "react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0", + "utility-types": "^3.10.0", + "webpack": "^5.95.0", + "webpack-merge": "^5.9.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-client-redirects/node_modules/@docusaurus/types/node_modules/webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@docusaurus/plugin-client-redirects/node_modules/@docusaurus/utils": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.10.1.tgz", + "integrity": "sha512-3ojeJry9xBYdJO6qoyyzqeJFSJBVx2mXhyDzSdjwL2+URFQMf+h25gG38iswGImicK0ELjTd1EL2xzk8hf3QPw==", + "license": "MIT", + "dependencies": { + "@docusaurus/logger": "3.10.1", + "@docusaurus/types": "3.10.1", + "@docusaurus/utils-common": "3.10.1", + "escape-string-regexp": "^4.0.0", + "execa": "^5.1.1", + "file-loader": "^6.2.0", + "fs-extra": "^11.1.1", + "github-slugger": "^1.5.0", + "globby": "^11.1.0", + "gray-matter": "^4.0.3", + "jiti": "^1.20.0", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "micromatch": "^4.0.5", + "p-queue": "^6.6.2", + "prompts": "^2.4.2", + "resolve-pathname": "^3.0.0", + "tslib": "^2.6.0", + "url-loader": "^4.1.1", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/plugin-client-redirects/node_modules/@docusaurus/utils-common": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.10.1.tgz", + "integrity": "sha512-5mFSgEADtnFxFH7RLw02QA5MpU5JVUCj0MPeIvi/aF4Fi45tQRIuTwXoXDqJ+1VfQJuYJGz3SI63wmGz4HvXzA==", + "license": "MIT", + "dependencies": { + "@docusaurus/types": "3.10.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/plugin-client-redirects/node_modules/@docusaurus/utils-validation": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.10.1.tgz", + "integrity": "sha512-cRv1X69jwaWv47waglllgZVWzeBFLhl53XT/XED/83BerVBTC5FTP8WTcVl8Z6sZOegDSwitu/wpCSPCDOT6lg==", + "license": "MIT", + "dependencies": { + "@docusaurus/logger": "3.10.1", + "@docusaurus/utils": "3.10.1", + "@docusaurus/utils-common": "3.10.1", + "fs-extra": "^11.2.0", + "joi": "^17.9.2", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/plugin-client-redirects/node_modules/webpackbar": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-7.0.0.tgz", + "integrity": "sha512-aS9soqSO2iCHgqHoCrj4LbfGQUboDCYJPSFOAchEK+9psIjNrfSWW4Y0YEz67MKURNvMmfo0ycOg9d/+OOf9/Q==", + "license": "MIT", + "dependencies": { + "ansis": "^3.2.0", + "consola": "^3.2.3", + "pretty-time": "^1.1.0", + "std-env": "^3.7.0" + }, + "engines": { + "node": ">=14.21.3" + }, + "peerDependencies": { + "@rspack/core": "*", + "webpack": "3 || 4 || 5" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, "node_modules/@docusaurus/plugin-content-blog": { "version": "3.9.2", "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.9.2.tgz", @@ -4390,6 +4745,79 @@ "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", "license": "MIT" }, + "node_modules/@scalar/docusaurus": { + "version": "0.7.44", + "resolved": "https://registry.npmjs.org/@scalar/docusaurus/-/docusaurus-0.7.44.tgz", + "integrity": "sha512-GUop+mdVe761bcUw/PDdyhR969dF948REosp7JyiQ+6TnlaDfg/7C3lUbwV8sGa1DTNrjKeXqHBh8AOMgubIWQ==", + "license": "MIT", + "dependencies": { + "@scalar/types": "0.6.10" + }, + "engines": { + "node": ">=20" + }, + "peerDependencies": { + "@docusaurus/utils": "^3.9.2", + "react": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@scalar/helpers": { + "version": "0.2.18", + "resolved": "https://registry.npmjs.org/@scalar/helpers/-/helpers-0.2.18.tgz", + "integrity": "sha512-w1d4tpNEVZ293oB2BAgLrS0kVPUtG3eByNmOCJA5eK9vcT4D3cmsGtWjUaaqit0BQCsBFHK51rasGvSWnApYTw==", + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/@scalar/types": { + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/@scalar/types/-/types-0.6.10.tgz", + "integrity": "sha512-fZkelRwcEeAhsn4c0wjYXWrzSzLaEyfxTn/eazXJ4XfCIsgJTQyK0FD8mnOBZJ2vEIbtT2E1mBKnCbDxrJIlxA==", + "license": "MIT", + "dependencies": { + "@scalar/helpers": "0.2.18", + "nanoid": "^5.1.6", + "type-fest": "^5.3.1", + "zod": "^4.3.5" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@scalar/types/node_modules/nanoid": { + "version": "5.1.15", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.15.tgz", + "integrity": "sha512-kBg3RpGtIe+RpTbyXwoI6pk5yD7KUiI3sygUqgeBMRst42KmhB4RZC7eiO9Wa1HIpaCCtpE2DJ6OI4Wi5ebwFw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.js" + }, + "engines": { + "node": "^18 || >=20" + } + }, + "node_modules/@scalar/types/node_modules/type-fest": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.7.0.tgz", + "integrity": "sha512-1URUxUqfHFM1c+zfSPsa3gnkO7Aq21qyH75SIduNYz4SzY964rn1X2vCMQaHSHhktiw+0kPa2iyb6PUpXqB6Vg==", + "license": "(MIT OR CC0-1.0)", + "dependencies": { + "tagged-tag": "^1.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@sideway/address": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", @@ -5580,6 +6008,15 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/ansis": { + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/ansis/-/ansis-3.17.0.tgz", + "integrity": "sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg==", + "license": "ISC", + "engines": { + "node": ">=14" + } + }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -5879,9 +6316,9 @@ } }, "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz", + "integrity": "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -12503,9 +12940,9 @@ "license": "ISC" }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -14917,24 +15354,24 @@ } }, "node_modules/react": { - "version": "19.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", - "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", + "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/react-dom": { - "version": "19.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz", - "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==", + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", + "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", "license": "MIT", "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^19.2.0" + "react": "^19.2.7" } }, "node_modules/react-fast-compare": { @@ -14993,9 +15430,9 @@ } }, "node_modules/react-loadable-ssr-addon-v5-slorber": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.1.tgz", - "integrity": "sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.3.tgz", + "integrity": "sha512-GXfh9VLwB5ERaCsU6RULh7tkemeX15aNh6wuMEBtfdyMa7fFG8TXrhXlx1SoEK2Ty/l6XIkzzYIQmyaWW3JgdQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.10.3" @@ -15855,15 +16292,15 @@ } }, "node_modules/serve-handler": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.6.tgz", - "integrity": "sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==", + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.7.tgz", + "integrity": "sha512-CinAq1xWb0vR3twAv9evEU8cNWkXCb9kd5ePAHUKJBkOsUpR1wt/CvGdeca7vqumL1U5cSaeVQ6zZMxiJ3yWsg==", "license": "MIT", "dependencies": { "bytes": "3.0.0", "content-disposition": "0.5.2", "mime-types": "2.1.18", - "minimatch": "3.1.2", + "minimatch": "3.1.5", "path-is-inside": "1.0.2", "path-to-regexp": "3.3.0", "range-parser": "1.2.0" @@ -16560,6 +16997,18 @@ "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, + "node_modules/tagged-tag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz", + "integrity": "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==", + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/tapable": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", @@ -17978,9 +18427,9 @@ } }, "node_modules/zod": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.12.tgz", - "integrity": "sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", + "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml index 7692b806f..499532942 100644 --- a/docs/pnpm-lock.yaml +++ b/docs/pnpm-lock.yaml @@ -10,41 +10,41 @@ importers: dependencies: '@docusaurus/core': specifier: 3.9.2 - version: 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + version: 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) '@docusaurus/plugin-client-redirects': specifier: ^3.9.2 - version: 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + version: 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) '@docusaurus/preset-classic': specifier: 3.9.2 - version: 3.9.2(@algolia/client-search@5.43.0)(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(search-insights@2.17.3)(typescript@5.6.3) + version: 3.9.2(@algolia/client-search@5.43.0)(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(search-insights@2.17.3)(typescript@5.6.3) '@mdx-js/react': specifier: ^3.0.0 - version: 3.1.1(@types/react@19.2.4)(react@19.2.0) + version: 3.1.1(@types/react@19.2.17)(react@19.2.7) '@scalar/docusaurus': specifier: ^0.7.21 - version: 0.7.21(@docusaurus/utils@3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0) + version: 0.7.21(@docusaurus/utils@3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7) clsx: specifier: ^2.0.0 version: 2.1.1 prism-react-renderer: specifier: ^2.3.0 - version: 2.4.1(react@19.2.0) + version: 2.4.1(react@19.2.7) react: - specifier: ^19.0.0 - version: 19.2.0 + specifier: ^19.2.7 + version: 19.2.7 react-dom: - specifier: ^19.0.0 - version: 19.2.0(react@19.2.0) + specifier: ^19.2.7 + version: 19.2.7(react@19.2.7) devDependencies: '@docusaurus/module-type-aliases': specifier: 3.9.2 - version: 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + version: 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@docusaurus/tsconfig': specifier: 3.9.2 version: 3.9.2 '@docusaurus/types': specifier: 3.9.2 - version: 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + version: 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) typescript: specifier: ~5.6.2 version: 5.6.3 @@ -708,6 +708,10 @@ packages: resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} engines: {node: '>=6.9.0'} + '@babel/runtime@7.29.7': + resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==} + engines: {node: '>=6.9.0'} + '@babel/template@7.27.2': resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} engines: {node: '>=6.9.0'} @@ -1565,6 +1569,9 @@ packages: '@types/react-router@5.1.20': resolution: {integrity: sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==} + '@types/react@19.2.17': + resolution: {integrity: sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==} + '@types/react@19.2.4': resolution: {integrity: sha512-tBFxBp9Nfyy5rsmefN+WXc1JeW/j2BpBHFdLZbEVfs9wn3E3NRFxwV0pJg8M1qQAexFpvz73hJXFofV0ZAu92A==} @@ -1606,6 +1613,7 @@ packages: '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + deprecated: Potential CWE-502 - Update to 1.3.1 or higher '@vercel/oidc@3.0.3': resolution: {integrity: sha512-yNEQvPcVrK9sIe637+I0jD6leluPxzwJKx/Haw6F4H77CdDsszUn5V3o96LPziXkSNE2B83+Z3mjqGKBK/R6Gg==} @@ -2239,6 +2247,9 @@ packages: csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + debounce@1.2.1: resolution: {integrity: sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==} @@ -4171,10 +4182,10 @@ packages: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true - react-dom@19.2.0: - resolution: {integrity: sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==} + react-dom@19.2.7: + resolution: {integrity: sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==} peerDependencies: - react: ^19.2.0 + react: ^19.2.7 react-fast-compare@3.2.2: resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==} @@ -4211,8 +4222,8 @@ packages: peerDependencies: react: '>=15' - react@19.2.0: - resolution: {integrity: sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==} + react@19.2.7: + resolution: {integrity: sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==} engines: {node: '>=0.10.0'} readable-stream@2.3.8: @@ -4842,6 +4853,7 @@ packages: uuid@8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). hasBin: true value-equal@1.0.1: @@ -5028,12 +5040,12 @@ snapshots: dependencies: json-schema: 0.4.0 - '@ai-sdk/react@2.0.93(react@19.2.0)(zod@4.1.12)': + '@ai-sdk/react@2.0.93(react@19.2.7)(zod@4.1.12)': dependencies: '@ai-sdk/provider-utils': 3.0.17(zod@4.1.12) ai: 5.0.93(zod@4.1.12) - react: 19.2.0 - swr: 2.3.6(react@19.2.0) + react: 19.2.7 + swr: 2.3.6(react@19.2.7) throttleit: 2.1.0 optionalDependencies: zod: 4.1.12 @@ -5876,6 +5888,8 @@ snapshots: '@babel/runtime@7.28.4': {} + '@babel/runtime@7.29.7': {} + '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.27.1 @@ -6192,33 +6206,33 @@ snapshots: '@discoveryjs/json-ext@0.5.7': {} - '@docsearch/core@4.3.1(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@docsearch/core@4.3.1(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': optionalDependencies: - '@types/react': 19.2.4 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@types/react': 19.2.17 + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) '@docsearch/css@4.3.2': {} - '@docsearch/react@4.3.2(@algolia/client-search@5.43.0)(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(search-insights@2.17.3)': + '@docsearch/react@4.3.2(@algolia/client-search@5.43.0)(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(search-insights@2.17.3)': dependencies: - '@ai-sdk/react': 2.0.93(react@19.2.0)(zod@4.1.12) + '@ai-sdk/react': 2.0.93(react@19.2.7)(zod@4.1.12) '@algolia/autocomplete-core': 1.19.2(@algolia/client-search@5.43.0)(algoliasearch@5.43.0)(search-insights@2.17.3) - '@docsearch/core': 4.3.1(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docsearch/core': 4.3.1(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@docsearch/css': 4.3.2 ai: 5.0.93(zod@4.1.12) algoliasearch: 5.43.0 marked: 16.4.2 zod: 4.1.12 optionalDependencies: - '@types/react': 19.2.4 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@types/react': 19.2.17 + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) search-insights: 2.17.3 transitivePeerDependencies: - '@algolia/client-search' - '@docusaurus/babel@3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@docusaurus/babel@3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: '@babel/core': 7.28.5 '@babel/generator': 7.28.5 @@ -6231,7 +6245,7 @@ snapshots: '@babel/runtime-corejs3': 7.28.4 '@babel/traverse': 7.28.5 '@docusaurus/logger': 3.9.2 - '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) babel-plugin-dynamic-import-node: 2.3.3 fs-extra: 11.3.2 tslib: 2.8.1 @@ -6244,14 +6258,14 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/bundler@3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@docusaurus/bundler@3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3)': dependencies: '@babel/core': 7.28.5 - '@docusaurus/babel': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/babel': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@docusaurus/cssnano-preset': 3.9.2 '@docusaurus/logger': 3.9.2 - '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/types': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) babel-loader: 9.2.1(@babel/core@7.28.5)(webpack@5.102.1) clean-css: 5.3.3 copy-webpack-plugin: 11.0.0(webpack@5.102.1) @@ -6285,16 +6299,16 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/core@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@docusaurus/core@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3)': dependencies: - '@docusaurus/babel': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/bundler': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/babel': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/bundler': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) '@docusaurus/logger': 3.9.2 - '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-common': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@mdx-js/react': 3.1.1(@types/react@19.2.4)(react@19.2.0) + '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@mdx-js/react': 3.1.1(@types/react@19.2.17)(react@19.2.7) boxen: 6.2.1 chalk: 4.1.2 chokidar: 3.6.0 @@ -6315,14 +6329,14 @@ snapshots: open: 8.4.2 p-map: 4.0.0 prompts: 2.4.2 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0)' - react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.0)' - react-loadable-ssr-addon-v5-slorber: 1.0.1(@docusaurus/react-loadable@6.0.0(react@19.2.0))(webpack@5.102.1) - react-router: 5.3.4(react@19.2.0) - react-router-config: 5.1.1(react-router@5.3.4(react@19.2.0))(react@19.2.0) - react-router-dom: 5.3.4(react@19.2.0) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7)' + react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.7)' + react-loadable-ssr-addon-v5-slorber: 1.0.1(@docusaurus/react-loadable@6.0.0(react@19.2.7))(webpack@5.102.1) + react-router: 5.3.4(react@19.2.7) + react-router-config: 5.1.1(react-router@5.3.4(react@19.2.7))(react@19.2.7) + react-router-dom: 5.3.4(react@19.2.7) semver: 7.7.3 serve-handler: 6.1.6 tinypool: 1.1.1 @@ -6361,11 +6375,11 @@ snapshots: chalk: 4.1.2 tslib: 2.8.1 - '@docusaurus/mdx-loader@3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@docusaurus/mdx-loader@3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: '@docusaurus/logger': 3.9.2 - '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@mdx-js/mdx': 3.1.1 '@slorber/remark-comment': 1.0.0 escape-html: 1.0.3 @@ -6375,8 +6389,8 @@ snapshots: image-size: 2.0.2 mdast-util-mdx: 3.0.0 mdast-util-to-string: 4.0.0 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) rehype-raw: 7.0.0 remark-directive: 3.0.1 remark-emoji: 4.0.1 @@ -6396,17 +6410,17 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/module-type-aliases@3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@docusaurus/module-type-aliases@3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/types': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@types/history': 4.7.11 '@types/react': 19.2.4 '@types/react-router-config': 5.0.11 '@types/react-router-dom': 5.3.3 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0)' - react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.0)' + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7)' + react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.7)' transitivePeerDependencies: - '@swc/core' - esbuild @@ -6414,18 +6428,18 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/plugin-client-redirects@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@docusaurus/plugin-client-redirects@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) '@docusaurus/logger': 3.9.2 - '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-common': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) eta: 2.2.0 fs-extra: 11.3.2 lodash: 4.17.21 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' @@ -6445,23 +6459,23 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-content-blog@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@docusaurus/plugin-content-blog@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3))(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) '@docusaurus/logger': 3.9.2 - '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-common': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/types': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) cheerio: 1.0.0-rc.12 feed: 4.2.2 fs-extra: 11.3.2 lodash: 4.17.21 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) schema-dts: 1.1.5 srcset: 4.0.0 tslib: 2.8.1 @@ -6486,24 +6500,24 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) '@docusaurus/logger': 3.9.2 - '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/module-type-aliases': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-common': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/module-type-aliases': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/types': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@types/react-router-config': 5.0.11 combine-promises: 1.2.0 fs-extra: 11.3.2 js-yaml: 4.1.1 lodash: 4.17.21 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) schema-dts: 1.1.5 tslib: 2.8.1 utility-types: 3.11.0 @@ -6526,16 +6540,16 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-content-pages@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@docusaurus/plugin-content-pages@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) + '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/types': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) fs-extra: 11.3.2 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) tslib: 2.8.1 webpack: 5.102.1 transitivePeerDependencies: @@ -6556,12 +6570,12 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-css-cascade-layers@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@docusaurus/plugin-css-cascade-layers@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) + '@docusaurus/types': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' @@ -6583,15 +6597,15 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-debug@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@docusaurus/plugin-debug@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) + '@docusaurus/types': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) fs-extra: 11.3.2 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - react-json-view-lite: 2.5.0(react@19.2.0) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + react-json-view-lite: 2.5.0(react@19.2.7) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' @@ -6611,13 +6625,13 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-google-analytics@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@docusaurus/plugin-google-analytics@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) + '@docusaurus/types': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' @@ -6637,14 +6651,14 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-google-gtag@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@docusaurus/plugin-google-gtag@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) + '@docusaurus/types': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@types/gtag.js': 0.0.12 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' @@ -6664,13 +6678,13 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-google-tag-manager@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@docusaurus/plugin-google-tag-manager@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) + '@docusaurus/types': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' @@ -6690,17 +6704,17 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-sitemap@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@docusaurus/plugin-sitemap@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) '@docusaurus/logger': 3.9.2 - '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-common': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/types': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) fs-extra: 11.3.2 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) sitemap: 7.1.2 tslib: 2.8.1 transitivePeerDependencies: @@ -6721,16 +6735,16 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-svgr@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@docusaurus/plugin-svgr@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) + '@docusaurus/types': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@svgr/core': 8.1.0(typescript@5.6.3) '@svgr/webpack': 8.1.0(typescript@5.6.3) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) tslib: 2.8.1 webpack: 5.102.1 transitivePeerDependencies: @@ -6751,25 +6765,25 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/preset-classic@3.9.2(@algolia/client-search@5.43.0)(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(search-insights@2.17.3)(typescript@5.6.3)': - dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/plugin-content-blog': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/plugin-content-pages': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/plugin-css-cascade-layers': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/plugin-debug': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/plugin-google-analytics': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/plugin-google-gtag': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/plugin-google-tag-manager': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/plugin-sitemap': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/plugin-svgr': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/theme-classic': 3.9.2(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/theme-search-algolia': 3.9.2(@algolia/client-search@5.43.0)(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(search-insights@2.17.3)(typescript@5.6.3) - '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@docusaurus/preset-classic@3.9.2(@algolia/client-search@5.43.0)(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(search-insights@2.17.3)(typescript@5.6.3)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) + '@docusaurus/plugin-content-blog': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3))(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) + '@docusaurus/plugin-content-pages': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) + '@docusaurus/plugin-css-cascade-layers': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) + '@docusaurus/plugin-debug': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) + '@docusaurus/plugin-google-analytics': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) + '@docusaurus/plugin-google-gtag': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) + '@docusaurus/plugin-google-tag-manager': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) + '@docusaurus/plugin-sitemap': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) + '@docusaurus/plugin-svgr': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) + '@docusaurus/theme-classic': 3.9.2(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/theme-search-algolia': 3.9.2(@algolia/client-search@5.43.0)(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(search-insights@2.17.3)(typescript@5.6.3) + '@docusaurus/types': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) transitivePeerDependencies: - '@algolia/client-search' - '@docusaurus/faster' @@ -6791,37 +6805,37 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/react-loadable@6.0.0(react@19.2.0)': + '@docusaurus/react-loadable@6.0.0(react@19.2.7)': dependencies: '@types/react': 19.2.4 - react: 19.2.0 + react: 19.2.7 - '@docusaurus/theme-classic@3.9.2(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@docusaurus/theme-classic@3.9.2(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) '@docusaurus/logger': 3.9.2 - '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/module-type-aliases': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/plugin-content-blog': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/plugin-content-pages': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/module-type-aliases': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/plugin-content-blog': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3))(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) + '@docusaurus/plugin-content-pages': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@docusaurus/theme-translations': 3.9.2 - '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-common': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@mdx-js/react': 3.1.1(@types/react@19.2.4)(react@19.2.0) + '@docusaurus/types': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@mdx-js/react': 3.1.1(@types/react@19.2.17)(react@19.2.7) clsx: 2.1.1 infima: 0.2.0-alpha.45 lodash: 4.17.21 nprogress: 0.2.0 postcss: 8.5.6 - prism-react-renderer: 2.4.1(react@19.2.0) + prism-react-renderer: 2.4.1(react@19.2.7) prismjs: 1.30.0 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - react-router-dom: 5.3.4(react@19.2.0) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + react-router-dom: 5.3.4(react@19.2.7) rtlcss: 4.3.0 tslib: 2.8.1 utility-types: 3.11.0 @@ -6843,21 +6857,21 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/theme-common@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@docusaurus/theme-common@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/module-type-aliases': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-common': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/module-type-aliases': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) + '@docusaurus/utils': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@types/history': 4.7.11 - '@types/react': 19.2.4 + '@types/react': 19.2.17 '@types/react-router-config': 5.0.11 clsx: 2.1.1 parse-numeric-range: 1.3.0 - prism-react-renderer: 2.4.1(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + prism-react-renderer: 2.4.1(react@19.2.7) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) tslib: 2.8.1 utility-types: 3.11.0 transitivePeerDependencies: @@ -6867,24 +6881,24 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/theme-search-algolia@3.9.2(@algolia/client-search@5.43.0)(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(search-insights@2.17.3)(typescript@5.6.3)': + '@docusaurus/theme-search-algolia@3.9.2(@algolia/client-search@5.43.0)(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(search-insights@2.17.3)(typescript@5.6.3)': dependencies: - '@docsearch/react': 4.3.2(@algolia/client-search@5.43.0)(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(search-insights@2.17.3) - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docsearch/react': 4.3.2(@algolia/client-search@5.43.0)(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(search-insights@2.17.3) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) '@docusaurus/logger': 3.9.2 - '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@5.6.3))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@docusaurus/theme-translations': 3.9.2 - '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) algoliasearch: 5.43.0 algoliasearch-helper: 3.26.1(algoliasearch@5.43.0) clsx: 2.1.1 eta: 2.2.0 fs-extra: 11.3.2 lodash: 4.17.21 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) tslib: 2.8.1 utility-types: 3.11.0 transitivePeerDependencies: @@ -6915,7 +6929,7 @@ snapshots: '@docusaurus/tsconfig@3.9.2': {} - '@docusaurus/types@3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@docusaurus/types@3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: '@mdx-js/mdx': 3.1.1 '@types/history': 4.7.11 @@ -6923,9 +6937,9 @@ snapshots: '@types/react': 19.2.4 commander: 5.1.0 joi: 17.13.3 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0)' + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7)' utility-types: 3.11.0 webpack: 5.102.1 webpack-merge: 5.10.0 @@ -6936,9 +6950,9 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/utils-common@3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@docusaurus/utils-common@3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/types': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) tslib: 2.8.1 transitivePeerDependencies: - '@swc/core' @@ -6949,11 +6963,11 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/utils-validation@3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@docusaurus/utils-validation@3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: '@docusaurus/logger': 3.9.2 - '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-common': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) fs-extra: 11.3.2 joi: 17.13.3 js-yaml: 4.1.1 @@ -6968,11 +6982,11 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/utils@3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@docusaurus/utils@3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: '@docusaurus/logger': 3.9.2 - '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-common': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/types': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@docusaurus/utils-common': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) escape-string-regexp: 4.0.0 execa: 5.1.1 file-loader: 6.2.0(webpack@5.102.1) @@ -7111,11 +7125,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@mdx-js/react@3.1.1(@types/react@19.2.4)(react@19.2.0)': + '@mdx-js/react@3.1.1(@types/react@19.2.17)(react@19.2.7)': dependencies: '@types/mdx': 2.0.13 - '@types/react': 19.2.4 - react: 19.2.0 + '@types/react': 19.2.17 + react: 19.2.7 '@nodelib/fs.scandir@2.1.5': dependencies: @@ -7145,11 +7159,11 @@ snapshots: '@polka/url@1.0.0-next.29': {} - '@scalar/docusaurus@0.7.21(@docusaurus/utils@3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(react@19.2.0)': + '@scalar/docusaurus@0.7.21(@docusaurus/utils@3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7)': dependencies: - '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils': 3.9.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@scalar/types': 0.4.0 - react: 19.2.0 + react: 19.2.7 '@scalar/openapi-types@0.5.1': dependencies: @@ -7176,13 +7190,13 @@ snapshots: '@sindresorhus/is@5.6.0': {} - '@slorber/react-helmet-async@1.3.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@slorber/react-helmet-async@1.3.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.29.7 invariant: 2.2.4 prop-types: 15.8.1 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) react-fast-compare: 3.2.2 shallowequal: 1.1.0 @@ -7418,6 +7432,10 @@ snapshots: '@types/history': 4.7.11 '@types/react': 19.2.4 + '@types/react@19.2.17': + dependencies: + csstype: 3.2.3 + '@types/react@19.2.4': dependencies: csstype: 3.1.3 @@ -8180,6 +8198,8 @@ snapshots: csstype@3.1.3: {} + csstype@3.2.3: {} + debounce@1.2.1: {} debug@2.6.9: @@ -10393,11 +10413,11 @@ snapshots: pretty-time@1.1.0: {} - prism-react-renderer@2.4.1(react@19.2.0): + prism-react-renderer@2.4.1(react@19.2.7): dependencies: '@types/prismjs': 1.26.5 clsx: 2.1.1 - react: 19.2.0 + react: 19.2.7 prismjs@1.30.0: {} @@ -10461,43 +10481,43 @@ snapshots: minimist: 1.2.8 strip-json-comments: 2.0.1 - react-dom@19.2.0(react@19.2.0): + react-dom@19.2.7(react@19.2.7): dependencies: - react: 19.2.0 + react: 19.2.7 scheduler: 0.27.0 react-fast-compare@3.2.2: {} react-is@16.13.1: {} - react-json-view-lite@2.5.0(react@19.2.0): + react-json-view-lite@2.5.0(react@19.2.7): dependencies: - react: 19.2.0 + react: 19.2.7 - react-loadable-ssr-addon-v5-slorber@1.0.1(@docusaurus/react-loadable@6.0.0(react@19.2.0))(webpack@5.102.1): + react-loadable-ssr-addon-v5-slorber@1.0.1(@docusaurus/react-loadable@6.0.0(react@19.2.7))(webpack@5.102.1): dependencies: '@babel/runtime': 7.28.4 - react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.0)' + react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.7)' webpack: 5.102.1 - react-router-config@5.1.1(react-router@5.3.4(react@19.2.0))(react@19.2.0): + react-router-config@5.1.1(react-router@5.3.4(react@19.2.7))(react@19.2.7): dependencies: '@babel/runtime': 7.28.4 - react: 19.2.0 - react-router: 5.3.4(react@19.2.0) + react: 19.2.7 + react-router: 5.3.4(react@19.2.7) - react-router-dom@5.3.4(react@19.2.0): + react-router-dom@5.3.4(react@19.2.7): dependencies: '@babel/runtime': 7.28.4 history: 4.10.1 loose-envify: 1.4.0 prop-types: 15.8.1 - react: 19.2.0 - react-router: 5.3.4(react@19.2.0) + react: 19.2.7 + react-router: 5.3.4(react@19.2.7) tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - react-router@5.3.4(react@19.2.0): + react-router@5.3.4(react@19.2.7): dependencies: '@babel/runtime': 7.28.4 history: 4.10.1 @@ -10505,12 +10525,12 @@ snapshots: loose-envify: 1.4.0 path-to-regexp: 1.9.0 prop-types: 15.8.1 - react: 19.2.0 + react: 19.2.7 react-is: 16.13.1 tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - react@19.2.0: {} + react@19.2.7: {} readable-stream@2.3.8: dependencies: @@ -11042,11 +11062,11 @@ snapshots: csso: 5.0.5 picocolors: 1.1.1 - swr@2.3.6(react@19.2.0): + swr@2.3.6(react@19.2.7): dependencies: dequal: 2.0.3 - react: 19.2.0 - use-sync-external-store: 1.6.0(react@19.2.0) + react: 19.2.7 + use-sync-external-store: 1.6.0(react@19.2.7) tagged-tag@1.0.0: {} @@ -11217,9 +11237,9 @@ snapshots: optionalDependencies: file-loader: 6.2.0(webpack@5.102.1) - use-sync-external-store@1.6.0(react@19.2.0): + use-sync-external-store@1.6.0(react@19.2.7): dependencies: - react: 19.2.0 + react: 19.2.7 util-deprecate@1.0.2: {} From 01c7d925b0849f856bbc6b0c8e13c3ebc4af687a Mon Sep 17 00:00:00 2001 From: Zomatree Date: Wed, 24 Jun 2026 13:38:20 +0100 Subject: [PATCH 205/211] chore: replace async-std with tokio (#813) Signed-off-by: Zomatree --- Cargo.lock | 1725 ++++++----------- Cargo.toml | 8 +- crates/bonfire/Cargo.toml | 7 +- crates/bonfire/src/events/state.rs | 2 +- crates/bonfire/src/main.rs | 6 +- crates/bonfire/src/websocket.rs | 9 +- crates/core/config/Cargo.toml | 4 +- crates/core/config/src/lib.rs | 2 +- crates/core/database/Cargo.toml | 8 +- crates/core/database/src/lib.rs | 4 +- .../src/models/admin_migrations/model.rs | 2 +- .../admin_migrations/ops/mongodb/scripts.rs | 2 +- crates/core/database/src/models/bots/model.rs | 2 +- .../src/models/channel_webhooks/model.rs | 2 +- .../database/src/models/channels/model.rs | 4 +- .../src/models/server_members/model.rs | 2 +- .../core/database/src/models/servers/model.rs | 2 +- .../core/database/src/models/users/model.rs | 8 +- crates/core/database/src/tasks/ack.rs | 2 +- .../database/src/tasks/last_message_id.rs | 2 +- crates/core/database/src/tasks/mod.rs | 2 +- .../core/database/src/tasks/process_embeds.rs | 3 +- crates/core/database/src/util/idempotency.rs | 2 +- crates/core/permissions/Cargo.toml | 2 +- crates/core/permissions/src/test.rs | 8 +- crates/core/presence/Cargo.toml | 4 +- crates/core/presence/src/lib.rs | 2 +- crates/daemons/crond/Cargo.toml | 2 +- crates/daemons/pushd/Cargo.toml | 2 +- crates/daemons/voice-ingress/Cargo.toml | 7 +- crates/delta/Cargo.toml | 8 +- .../src/routes/account/create_account.rs | 2 +- .../src/routes/account/resend_verification.rs | 2 +- .../src/routes/account/send_password_reset.rs | 2 +- crates/delta/src/routes/session/login.rs | 2 +- 35 files changed, 703 insertions(+), 1150 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b1f214fc8..872ee2a0a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -111,9 +111,9 @@ checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" [[package]] name = "alloc-stdlib" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +checksum = "0e76a019e91224d279006ff972f1e984179a6e9feb050adba6ce8274aef23195" dependencies = [ "alloc-no-stdlib", ] @@ -126,9 +126,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "amq-protocol" -version = "10.3.2" +version = "10.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46b92ce9a8b7d332c4b54ef7ea1b00570692bd94fe225901eab63bd12930c63f" +checksum = "2eab68e8836c5812a01b34c5364d28db50bf686b442e902d9d93e4472318d86e" dependencies = [ "amq-protocol-tcp", "amq-protocol-types", @@ -140,9 +140,9 @@ dependencies = [ [[package]] name = "amq-protocol-tcp" -version = "10.3.2" +version = "10.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06f3177d5d2aff2ec51e1d77ac433fcd1b297ea2bb97c2089152a7d2a58a7e3f" +checksum = "8689f976dbd9864922f4f53e01ad2b43700ed3eb1bb5667b260522f291434dae" dependencies = [ "amq-protocol-uri", "async-rs", @@ -153,9 +153,9 @@ dependencies = [ [[package]] name = "amq-protocol-types" -version = "10.3.2" +version = "10.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b9f2a0015cd0471a2b823060f3424760a7a84787ee89edd1039ca8d715f6de0" +checksum = "27894e9e57d07f701251aeee3d2ab3d7d114bc830bf722d6626027eb55f3b222" dependencies = [ "cookie-factory", "nom 8.0.0", @@ -165,9 +165,9 @@ dependencies = [ [[package]] name = "amq-protocol-uri" -version = "10.3.2" +version = "10.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f66f887c5445e087e811794d7e5d071145c81e83568f77529e2f1203b68202" +checksum = "64fd5ca63f1b8cba2309aaec8595483c36f3a671225d5ab9fe8265adb9213514" dependencies = [ "amq-protocol-types", "percent-encoding", @@ -211,8 +211,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -223,9 +223,9 @@ checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +checksum = "f02882884d3e1bc524fb12c79f107f6ad0e1cfd498c536ffb494301740995dfe" [[package]] name = "as-slice" @@ -259,8 +259,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", "synstructure 0.13.2", ] @@ -271,29 +271,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", -] - -[[package]] -name = "async-attributes" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5" -dependencies = [ - "quote 1.0.45", - "syn 1.0.109", -] - -[[package]] -name = "async-channel" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" -dependencies = [ - "concurrent-queue", - "event-listener 2.5.3", - "futures-core", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -305,7 +284,7 @@ dependencies = [ "concurrent-queue", "event-listener-strategy", "futures-core", - "pin-project-lite 0.2.17", + "pin-project-lite", ] [[package]] @@ -317,8 +296,8 @@ dependencies = [ "futures-core", "futures-io", "once_cell", - "pin-project-lite 0.2.17", - "tokio 1.52.3", + "pin-project-lite", + "tokio", ] [[package]] @@ -331,57 +310,22 @@ dependencies = [ "concurrent-queue", "fastrand 2.4.1", "futures-lite", - "pin-project-lite 0.2.17", + "pin-project-lite", "slab", ] -[[package]] -name = "async-global-executor" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" -dependencies = [ - "async-channel 2.5.0", - "async-executor", - "async-io", - "async-lock 3.4.2", - "blocking", - "futures-lite", - "once_cell", - "tokio 0.2.25", - "tokio 1.52.3", -] - [[package]] name = "async-global-executor" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13f937e26114b93193065fd44f507aa2e9169ad0cdabbb996920b1fe1ddea7ba" dependencies = [ - "async-channel 2.5.0", + "async-channel", "async-executor", "async-lock 3.4.2", "blocking", "futures-lite", - "tokio 1.52.3", -] - -[[package]] -name = "async-io" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" -dependencies = [ - "autocfg", - "cfg-if", - "concurrent-queue", - "futures-io", - "futures-lite", - "parking", - "polling", - "rustix 1.1.4", - "slab", - "windows-sys 0.61.2", + "tokio", ] [[package]] @@ -401,25 +345,7 @@ checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" dependencies = [ "event-listener 5.4.1", "event-listener-strategy", - "pin-project-lite 0.2.17", -] - -[[package]] -name = "async-process" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75" -dependencies = [ - "async-channel 2.5.0", - "async-io", - "async-lock 3.4.2", - "async-signal", - "async-task", - "blocking", - "cfg-if", - "event-listener 5.4.1", - "futures-lite", - "rustix 1.1.4", + "pin-project-lite", ] [[package]] @@ -429,72 +355,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] name = "async-rs" -version = "0.8.7" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53bf71bee8a75907b6e3c81c5476efa7fcbb34df6e12d30b706888abded72091" +checksum = "3cd5147201b63ba6883ffabca3a153822f71541748d7108e3e799beaeb283131" dependencies = [ "async-compat", - "async-global-executor 3.1.0", + "async-global-executor", "async-trait", "futures-core", "futures-io", - "hickory-resolver 0.26.1", - "tokio 1.52.3", + "hickory-resolver", + "tokio", "tokio-stream", ] -[[package]] -name = "async-signal" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52b5aaafa020cf5053a01f2a60e8ff5dccf550f0f77ec54a4e47285ac2bab485" -dependencies = [ - "async-io", - "async-lock 3.4.2", - "atomic-waker", - "cfg-if", - "futures-core", - "futures-io", - "rustix 1.1.4", - "signal-hook-registry", - "slab", - "windows-sys 0.61.2", -] - -[[package]] -name = "async-std" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c8e079a4ab67ae52b7403632e4618815d6db36d2a010cfe41b02c1b1578f93b" -dependencies = [ - "async-attributes", - "async-channel 1.9.0", - "async-global-executor 2.4.1", - "async-io", - "async-lock 3.4.2", - "async-process", - "crossbeam-utils", - "futures-channel", - "futures-core", - "futures-io", - "futures-lite", - "gloo-timers", - "kv-log-macro", - "log", - "memchr", - "once_cell", - "pin-project-lite 0.2.17", - "pin-utils", - "slab", - "wasm-bindgen-futures", -] - [[package]] name = "async-stream" version = "0.3.6" @@ -503,7 +383,7 @@ checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" dependencies = [ "async-stream-impl", "futures-core", - "pin-project-lite 0.2.17", + "pin-project-lite", ] [[package]] @@ -513,8 +393,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -530,8 +410,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -540,11 +420,11 @@ version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1b71b31561643aa8e7df3effe284fa83ab1a840e52294c5f4bd7bfd8b2becbb" dependencies = [ - "async-std", "futures-io", "futures-util", "log", - "pin-project-lite 0.2.17", + "pin-project-lite", + "tokio", "tungstenite 0.17.3", ] @@ -588,9 +468,9 @@ checksum = "7460f7dd8e100147b82a63afca1a20eb6c231ee36b90ba7272e14951cb58af59" [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "av-scenechange" @@ -654,13 +534,13 @@ dependencies = [ "aws-smithy-schema", "aws-smithy-types", "aws-types", - "bytes 1.11.1", + "bytes", "fastrand 2.4.1", "hex", - "http 1.4.0", + "http 1.4.2", "sha1 0.10.6", "time", - "tokio 1.52.3", + "tokio", "tracing", "url", "zeroize", @@ -715,25 +595,26 @@ dependencies = [ "aws-smithy-runtime-api", "aws-smithy-types", "aws-types", - "bytes 1.11.1", + "bytes", "bytes-utils", "fastrand 2.4.1", "http 0.2.12", - "http 1.4.0", + "http 1.4.2", "http-body 0.4.6", "http-body 1.0.1", "percent-encoding", - "pin-project-lite 0.2.17", + "pin-project-lite", "tracing", "uuid", ] [[package]] name = "aws-sdk-s3" -version = "1.132.0" +version = "1.137.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5575840a3a6b11f6011463ebe359320dfe5b67babb5e9b06fed6ddf809a9ab40" +checksum = "c2dd7213994e2ff9382ff100403b78c30d1b74cdfcd8fa9d0d1dc3a94a5c4874" dependencies = [ + "arc-swap", "aws-credential-types", "aws-runtime", "aws-sigv4", @@ -748,12 +629,12 @@ dependencies = [ "aws-smithy-types", "aws-smithy-xml", "aws-types", - "bytes 1.11.1", + "bytes", "fastrand 2.4.1", "hex", "hmac 0.13.0", "http 0.2.12", - "http 1.4.0", + "http 1.4.2", "http-body 1.0.1", "lru", "percent-encoding", @@ -780,10 +661,10 @@ dependencies = [ "aws-smithy-runtime-api", "aws-smithy-types", "aws-types", - "bytes 1.11.1", + "bytes", "fastrand 2.4.1", "http 0.2.12", - "http 1.4.0", + "http 1.4.2", "regex-lite", "tracing", ] @@ -805,10 +686,10 @@ dependencies = [ "aws-smithy-runtime-api", "aws-smithy-types", "aws-types", - "bytes 1.11.1", + "bytes", "fastrand 2.4.1", "http 0.2.12", - "http 1.4.0", + "http 1.4.2", "regex-lite", "tracing", ] @@ -834,7 +715,7 @@ dependencies = [ "aws-types", "fastrand 2.4.1", "http 0.2.12", - "http 1.4.0", + "http 1.4.2", "regex-lite", "tracing", ] @@ -850,13 +731,13 @@ dependencies = [ "aws-smithy-http", "aws-smithy-runtime-api", "aws-smithy-types", - "bytes 1.11.1", + "bytes", "crypto-bigint", "form_urlencoded", "hex", "hmac 0.13.0", "http 0.2.12", - "http 1.4.0", + "http 1.4.2", "p256", "percent-encoding", "sha2 0.11.0", @@ -873,26 +754,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2ffcaf626bdda484571968400c326a244598634dc75fd451325a54ad1a59acfc" dependencies = [ "futures-util", - "pin-project-lite 0.2.17", - "tokio 1.52.3", + "pin-project-lite", + "tokio", ] [[package]] name = "aws-smithy-checksums" -version = "0.64.7" +version = "0.64.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10efbbcec1e044b81600e2fc562a391951d291152d95b482d5b7e7132299d762" +checksum = "e9e8e65f4f81fcccdeb6c3eca2af17ac21d421a1786a26a394aecf421d616d3a" dependencies = [ "aws-smithy-http", "aws-smithy-types", - "bytes 1.11.1", + "bytes", "crc-fast", "hex", - "http 1.4.0", + "http 1.4.2", "http-body 1.0.1", "http-body-util", "md-5 0.11.0", - "pin-project-lite 0.2.17", + "pin-project-lite", "sha1 0.11.0", "sha2 0.11.0", "tracing", @@ -905,7 +786,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78d8391e65fcea47c586a22e1a41f173b38615b112b2c6b7a44e80cec3e6b706" dependencies = [ "aws-smithy-types", - "bytes 1.11.1", + "bytes", "crc32fast", ] @@ -918,44 +799,44 @@ dependencies = [ "aws-smithy-eventstream", "aws-smithy-runtime-api", "aws-smithy-types", - "bytes 1.11.1", + "bytes", "bytes-utils", "futures-core", "futures-util", - "http 1.4.0", + "http 1.4.2", "http-body 1.0.1", "http-body-util", "percent-encoding", - "pin-project-lite 0.2.17", + "pin-project-lite", "pin-utils", "tracing", ] [[package]] name = "aws-smithy-http-client" -version = "1.1.12" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a2f165a7feee6f263028b899d0a181987f4fa7179a6411a32a439fba7c5f769" +checksum = "5c3ef8931ad1c98aa6a55b4256f847f3116090819844e0dd41ea682cac5dd2d3" dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api", "aws-smithy-types", "h2 0.3.27", - "h2 0.4.14", + "h2 0.4.15", "http 0.2.12", - "http 1.4.0", + "http 1.4.2", "http-body 0.4.6", "hyper 0.14.32", - "hyper 1.9.0", + "hyper 1.10.1", "hyper-rustls 0.24.2", "hyper-rustls 0.27.9", "hyper-util", - "pin-project-lite 0.2.17", + "pin-project-lite", "rustls 0.21.12", - "rustls 0.23.40", - "rustls-native-certs 0.8.3", + "rustls 0.23.41", + "rustls-native-certs 0.8.4", "rustls-pki-types", - "tokio 1.52.3", + "tokio", "tokio-rustls 0.26.4", "tower", "tracing", @@ -1004,16 +885,16 @@ dependencies = [ "aws-smithy-runtime-api", "aws-smithy-schema", "aws-smithy-types", - "bytes 1.11.1", + "bytes", "fastrand 2.4.1", "http 0.2.12", - "http 1.4.0", + "http 1.4.2", "http-body 0.4.6", "http-body 1.0.1", "http-body-util", - "pin-project-lite 0.2.17", + "pin-project-lite", "pin-utils", - "tokio 1.52.3", + "tokio", "tracing", ] @@ -1026,11 +907,11 @@ dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api-macros", "aws-smithy-types", - "bytes 1.11.1", + "bytes", "http 0.2.12", - "http 1.4.0", - "pin-project-lite 0.2.17", - "tokio 1.52.3", + "http 1.4.2", + "pin-project-lite", + "tokio", "tracing", "zeroize", ] @@ -1042,8 +923,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d7396fd9500589e62e460e987ecb671bad374934e55ec3b5f498cc7a8a8a7b7" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -1054,7 +935,7 @@ checksum = "7442cb268338f0eb8278140a107c046756aa01093d8ef5e99628d34ae09c94f5" dependencies = [ "aws-smithy-runtime-api", "aws-smithy-types", - "http 1.4.0", + "http 1.4.2", ] [[package]] @@ -1064,22 +945,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32b42fcf341259d85ca10fac9a2f6448a8ec691c6955a18e45bc3b71a85fab85" dependencies = [ "base64-simd", - "bytes 1.11.1", + "bytes", "bytes-utils", "futures-core", "http 0.2.12", - "http 1.4.0", + "http 1.4.2", "http-body 0.4.6", "http-body 1.0.1", "http-body-util", "itoa", "num-integer", - "pin-project-lite 0.2.17", + "pin-project-lite", "pin-utils", "ryu", "serde", "time", - "tokio 1.52.3", + "tokio", "tokio-util", ] @@ -1116,12 +997,12 @@ dependencies = [ "async-trait", "axum-core", "axum-macros", - "bytes 1.11.1", + "bytes", "futures-util", - "http 1.4.0", + "http 1.4.2", "http-body 1.0.1", "http-body-util", - "hyper 1.9.0", + "hyper 1.10.1", "hyper-util", "itoa", "matchit", @@ -1129,14 +1010,14 @@ dependencies = [ "mime", "multer", "percent-encoding", - "pin-project-lite 0.2.17", + "pin-project-lite", "rustversion", "serde", "serde_json", "serde_path_to_error", "serde_urlencoded", "sync_wrapper 1.0.2", - "tokio 1.52.3", + "tokio", "tower", "tower-layer", "tower-service", @@ -1150,13 +1031,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" dependencies = [ "async-trait", - "bytes 1.11.1", + "bytes", "futures-util", - "http 1.4.0", + "http 1.4.2", "http-body 1.0.1", "http-body-util", "mime", - "pin-project-lite 0.2.17", + "pin-project-lite", "rustversion", "sync_wrapper 1.0.2", "tower-layer", @@ -1172,16 +1053,16 @@ checksum = "c794b30c904f0a1c2fb7740f7df7f7972dfaa14ef6f57cb6178dc63e5dca2f04" dependencies = [ "axum", "axum-core", - "bytes 1.11.1", + "bytes", "fastrand 2.4.1", "futures-util", "headers", - "http 1.4.0", + "http 1.4.2", "http-body 1.0.1", "http-body-util", "mime", "multer", - "pin-project-lite 0.2.17", + "pin-project-lite", "serde", "tower", "tower-layer", @@ -1195,8 +1076,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57d123550fa8d071b7255cb0cc04dc302baa6c8c4a79f55701552684d8399bce" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -1208,13 +1089,13 @@ dependencies = [ "anyhow", "axum", "axum_typed_multipart_macros", - "bytes 1.11.1", + "bytes", "chrono", "futures-core", "futures-util", "tempfile", "thiserror 1.0.69", - "tokio 1.52.3", + "tokio", "uuid", ] @@ -1227,8 +1108,8 @@ dependencies = [ "darling 0.20.11", "heck 0.5.0", "proc-macro-error", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", "ubyte", ] @@ -1349,9 +1230,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.11.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" [[package]] name = "bitstream-io" @@ -1364,9 +1245,9 @@ dependencies = [ [[package]] name = "bitvec" -version = "1.0.1" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +checksum = "ddcec3d12c579d40898fe0a9a358a803c23e9c52ca3c425707f81c9436211837" dependencies = [ "funty", "radium", @@ -1396,9 +1277,9 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" dependencies = [ "hybrid-array", ] @@ -1427,7 +1308,7 @@ version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21" dependencies = [ - "async-channel 2.5.0", + "async-channel", "async-task", "futures-io", "futures-lite", @@ -1436,9 +1317,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "5.0.0" +version = "5.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" +checksum = "3a32acac15fe1967bc3986b2a6347dffc965602354ea6f450ad07e8bfd253583" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -1469,15 +1350,15 @@ dependencies = [ [[package]] name = "built" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4ad8f11f288f48ca24471bbd51ac257aaeaaa07adae295591266b792902ae64" +checksum = "5c0e531d93d39c34eef561e929e8a7f86d77a5af08aac4f6d6e39976c51858e9" [[package]] name = "bumpalo" -version = "3.20.2" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "bytemuck" @@ -1499,15 +1380,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] name = "bytes" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" - -[[package]] -name = "bytes" -version = "1.11.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593" [[package]] name = "bytes-utils" @@ -1515,7 +1390,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dafe3a8757b027e2be6e4e5601ed563c55989fcf1546e933c66c8eb3a058d35" dependencies = [ - "bytes 1.11.1", + "bytes", "either", ] @@ -1533,7 +1408,7 @@ dependencies = [ "instant", "once_cell", "thiserror 1.0.69", - "tokio 1.52.3", + "tokio", ] [[package]] @@ -1545,7 +1420,7 @@ dependencies = [ "cached_proc_macro_types", "darling 0.14.4", "proc-macro2", - "quote 1.0.45", + "quote 1.0.46", "syn 1.0.109", ] @@ -1575,9 +1450,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.62" +version = "1.2.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" +checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96" dependencies = [ "find-msvc-tools", "jobserver", @@ -1659,9 +1534,9 @@ dependencies = [ [[package]] name = "cmov" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f88a43d011fc4a6876cb7344703e297c71dda42494fee094d5f7c76bf13f746" +checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" [[package]] name = "cms" @@ -1698,11 +1573,11 @@ version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" dependencies = [ - "bytes 1.11.1", + "bytes", "futures-core", "memchr", - "pin-project-lite 0.2.17", - "tokio 1.52.3", + "pin-project-lite", + "tokio", "tokio-util", ] @@ -1866,30 +1741,13 @@ dependencies = [ "libc", ] -[[package]] -name = "crc" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675" -dependencies = [ - "crc-catalog", -] - -[[package]] -name = "crc-catalog" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853" - [[package]] name = "crc-fast" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd92aca2c6001b1bf5ba0ff84ee74ec8501b52bbef0cac80bf25a6c1d87a83d" +checksum = "e75b2483e97a5a7da73ac68a05b629f9c53cff58d8ed1c77866079e18b00dba5" dependencies = [ - "crc", "digest 0.10.7", - "rustversion", "spin 0.10.0", ] @@ -1988,9 +1846,9 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" dependencies = [ "hybrid-array", ] @@ -2014,15 +1872,15 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] name = "ct-codecs" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b10589d1a5e400d61f9f38f12f884cfd080ff345de8f17efda36fe0e4a02aa8" +checksum = "49fb0c6640b4507ebd99ff67677009e381ba5eee1d14df78de4a3d16eb123c39" [[package]] name = "ctr" @@ -2053,7 +1911,7 @@ dependencies = [ "openssl-probe 0.1.6", "openssl-sys", "schannel", - "socket2 0.6.3", + "socket2 0.6.4", "windows-sys 0.59.0", ] @@ -2096,8 +1954,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -2149,7 +2007,7 @@ dependencies = [ "fnv", "ident_case", "proc-macro2", - "quote 1.0.45", + "quote 1.0.46", "strsim 0.10.0", "syn 1.0.109", ] @@ -2163,7 +2021,7 @@ dependencies = [ "fnv", "ident_case", "proc-macro2", - "quote 1.0.45", + "quote 1.0.46", "strsim 0.10.0", "syn 1.0.109", ] @@ -2177,9 +2035,9 @@ dependencies = [ "fnv", "ident_case", "proc-macro2", - "quote 1.0.45", + "quote 1.0.46", "strsim 0.11.1", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -2190,9 +2048,9 @@ checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" dependencies = [ "ident_case", "proc-macro2", - "quote 1.0.45", + "quote 1.0.46", "strsim 0.11.1", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -2202,7 +2060,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" dependencies = [ "darling_core 0.13.4", - "quote 1.0.45", + "quote 1.0.46", "syn 1.0.109", ] @@ -2213,7 +2071,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" dependencies = [ "darling_core 0.14.4", - "quote 1.0.45", + "quote 1.0.46", "syn 1.0.109", ] @@ -2224,8 +2082,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core 0.20.11", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -2235,8 +2093,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" dependencies = [ "darling_core 0.23.0", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -2271,7 +2129,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72ff1266be84e4e04a81e2d1cbb998cb271b374fb73ce780245ef96c037c50cd" dependencies = [ "crossbeam-queue", - "tokio 1.52.3", + "tokio", ] [[package]] @@ -2349,7 +2207,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8aed3b3c608dc56cf36c45fe979d04eda51242e6703d8d0bb03426ef7c41db6a" dependencies = [ "proc-macro2", - "quote 1.0.45", + "quote 1.0.46", "syn 1.0.109", "synstructure 0.12.6", ] @@ -2361,8 +2219,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -2371,7 +2229,6 @@ version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" dependencies = [ - "powerfmt", "serde_core", ] @@ -2382,8 +2239,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d65d7ce8132b7c0e54497a4d9a55a1c2a0912a0d786cf894472ba818fba45762" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -2393,8 +2250,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d08b3a0bcc0d079199cd476b2cae8435016ec11d1c0986c6901c5ac223041534" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -2404,8 +2261,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -2425,9 +2282,9 @@ checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" dependencies = [ "convert_case", "proc-macro2", - "quote 1.0.45", + "quote 1.0.46", "rustc_version", - "syn 2.0.117", + "syn 2.0.118", "unicode-xid 0.2.6", ] @@ -2472,7 +2329,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71b28680d8be17a570a2334922518be6adc3f58ecc880cbb404eaeb8624fd867" dependencies = [ "devise_core", - "quote 1.0.45", + "quote 1.0.46", ] [[package]] @@ -2481,11 +2338,11 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b035a542cf7abf01f2e3c4d5a7acbaebfefe120ae4efc7bde3df98186e4b8af7" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "proc-macro2", "proc-macro2-diagnostics", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -2506,9 +2363,9 @@ version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ - "block-buffer 0.12.0", + "block-buffer 0.12.1", "const-oid 0.10.2", - "crypto-common 0.2.1", + "crypto-common 0.2.2", "ctutils", ] @@ -2518,19 +2375,19 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "objc2", ] [[package]] name = "displaydoc" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -2610,12 +2467,12 @@ dependencies = [ [[package]] name = "ed25519-compact" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5c0284a5d4b1a2fae017a9fe55fd7d01699711f1b572493f16593e173ea2801" +checksum = "5c24599140dc39d7a81e4476e7573d41bbc18e07c803900298e522a5fbcfbfb6" dependencies = [ "ct-codecs", - "getrandom 0.4.2", + "getrandom 0.4.3", ] [[package]] @@ -2640,9 +2497,9 @@ checksum = "12a0bb14ac04a9fcf170d0bbbef949b44cc492f4452bd20c095636956f653642" [[package]] name = "either" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" [[package]] name = "elliptic-curve" @@ -2690,18 +2547,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "enum-as-inner" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" -dependencies = [ - "heck 0.5.0", - "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", -] - [[package]] name = "enum-iterator" version = "1.5.0" @@ -2718,8 +2563,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "685adfa4d6f3d765a26bc5dbc936577de9abf756c1feeb3089b01dd395034842" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -2751,8 +2596,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -2777,7 +2622,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -2803,7 +2648,7 @@ checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" dependencies = [ "concurrent-queue", "parking", - "pin-project-lite 0.2.17", + "pin-project-lite", ] [[package]] @@ -2813,7 +2658,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" dependencies = [ "event-listener 5.4.1", - "pin-project-lite 0.2.17", + "pin-project-lite", ] [[package]] @@ -2980,12 +2825,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - [[package]] name = "foldhash" version = "0.2.0" @@ -3041,8 +2880,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -3074,7 +2913,7 @@ checksum = "4b8e3a1339ed45ad8fde94530c4bdcbd5f371a3c6bd3bf57682923792830aa37" dependencies = [ "arc-swap", "async-trait", - "bytes 1.11.1", + "bytes", "bytes-utils", "crossbeam-queue", "float-cmp", @@ -3085,7 +2924,7 @@ dependencies = [ "redis-protocol", "semver", "socket2 0.5.10", - "tokio 1.52.3", + "tokio", "tokio-stream", "tokio-util", "url", @@ -3172,7 +3011,7 @@ dependencies = [ "futures-core", "futures-io", "parking", - "pin-project-lite 0.2.17", + "pin-project-lite", ] [[package]] @@ -3183,7 +3022,7 @@ checksum = "45ec6fe3675af967e67c5536c0b9d44e34e6c52f86bedc4ea49c5317b8e94d06" dependencies = [ "futures-channel", "futures-task", - "tokio 1.52.3", + "tokio", ] [[package]] @@ -3193,8 +3032,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -3204,7 +3043,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f2f12607f92c69b12ed746fabf9ca4f5c482cba46679c1a75b874ed7c26adb" dependencies = [ "futures-io", - "rustls 0.23.40", + "rustls 0.23.41", "rustls-pki-types", ] @@ -3222,9 +3061,9 @@ checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] name = "futures-timer" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" +checksum = "af43fadb8a98512d547e37b4e92e0ced13e205c061b87b4623eff01d918d6968" [[package]] name = "futures-util" @@ -3239,7 +3078,7 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project-lite 0.2.17", + "pin-project-lite", "slab", ] @@ -3278,9 +3117,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "1.4.1" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dab9e9188e97a93276e1fe7b56401b851e2b45a46d045ca658100c1303ada649" +checksum = "c2e55f16dcf0e9c00efbe2e655ffe45fc98e7066b52bc92f8a79e64060a79351" dependencies = [ "rustversion", "typenum", @@ -3324,30 +3163,27 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", "js-sys", "libc", "r-efi 6.0.0", "rand_core 0.10.1", - "wasip2", - "wasip3", "wasm-bindgen", ] [[package]] name = "getset" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf0fc11e47561d47397154977bc219f4cf809b2974facc3ccb3b89e2436f912" +checksum = "6cf442baaabe4213ce7d1239afc26c039180b6456da2cededa316ae2c8a77a77" dependencies = [ - "proc-macro-error2", "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -3405,18 +3241,6 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" -[[package]] -name = "gloo-timers" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - [[package]] name = "group" version = "0.13.0" @@ -3434,7 +3258,7 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" dependencies = [ - "bytes 1.11.1", + "bytes", "fnv", "futures-core", "futures-sink", @@ -3442,26 +3266,26 @@ dependencies = [ "http 0.2.12", "indexmap 2.14.0", "slab", - "tokio 1.52.3", + "tokio", "tokio-util", "tracing", ] [[package]] name = "h2" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733" +checksum = "6cb093c84e8bd9b188d4c4a8cb6579fc016968d14c99882163cd3ff402a4f155" dependencies = [ "atomic-waker", - "bytes 1.11.1", + "bytes", "fnv", "futures-core", "futures-sink", - "http 1.4.0", + "http 1.4.2", "indexmap 2.14.0", "slab", - "tokio 1.52.3", + "tokio", "tokio-util", "tracing", ] @@ -3512,15 +3336,6 @@ version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -[[package]] -name = "hashbrown" -version = "0.15.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" -dependencies = [ - "foldhash 0.1.5", -] - [[package]] name = "hashbrown" version = "0.16.1" @@ -3529,7 +3344,7 @@ checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" dependencies = [ "allocator-api2", "equivalent", - "foldhash 0.2.0", + "foldhash", ] [[package]] @@ -3545,9 +3360,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb" dependencies = [ "base64 0.22.1", - "bytes 1.11.1", + "bytes", "headers-core", - "http 1.4.0", + "http 1.4.2", "httpdate", "mime", "sha1 0.10.6", @@ -3559,7 +3374,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" dependencies = [ - "http 1.4.0", + "http 1.4.2", ] [[package]] @@ -3607,39 +3422,14 @@ dependencies = [ "futures-channel", "futures-io", "futures-util", - "hickory-proto 0.26.1", + "hickory-proto", "idna 1.1.0", "ipnet", "jni 0.22.4", "rand 0.10.1", "thiserror 2.0.18", "tinyvec", - "tokio 1.52.3", - "tracing", - "url", -] - -[[package]] -name = "hickory-proto" -version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8a6fe56c0038198998a6f217ca4e7ef3a5e51f46163bd6dd60b5c71ca6c6502" -dependencies = [ - "async-trait", - "cfg-if", - "data-encoding", - "enum-as-inner", - "futures-channel", - "futures-io", - "futures-util", - "idna 1.1.0", - "ipnet", - "once_cell", - "rand 0.9.4", - "ring", - "thiserror 2.0.18", - "tinyvec", - "tokio 1.52.3", + "tokio", "tracing", "url", ] @@ -3664,27 +3454,6 @@ dependencies = [ "url", ] -[[package]] -name = "hickory-resolver" -version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc62a9a99b0bfb44d2ab95a7208ac952d31060efc16241c87eaf36406fecf87a" -dependencies = [ - "cfg-if", - "futures-util", - "hickory-proto 0.25.2", - "ipconfig", - "moka", - "once_cell", - "parking_lot", - "rand 0.9.4", - "resolv-conf", - "smallvec", - "thiserror 2.0.18", - "tokio 1.52.3", - "tracing", -] - [[package]] name = "hickory-resolver" version = "0.26.1" @@ -3694,7 +3463,7 @@ dependencies = [ "cfg-if", "futures-util", "hickory-net", - "hickory-proto 0.26.1", + "hickory-proto", "ipconfig", "ipnet", "jni 0.22.4", @@ -3707,7 +3476,7 @@ dependencies = [ "smallvec", "system-configuration 0.7.0", "thiserror 2.0.18", - "tokio 1.52.3", + "tokio", "tracing", ] @@ -3792,8 +3561,8 @@ dependencies = [ "mac", "markup5ever", "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -3802,18 +3571,18 @@ version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ - "bytes 1.11.1", + "bytes", "fnv", "itoa", ] [[package]] name = "http" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425" dependencies = [ - "bytes 1.11.1", + "bytes", "itoa", ] @@ -3823,9 +3592,9 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ - "bytes 1.11.1", + "bytes", "http 0.2.12", - "pin-project-lite 0.2.17", + "pin-project-lite", ] [[package]] @@ -3834,8 +3603,8 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ - "bytes 1.11.1", - "http 1.4.0", + "bytes", + "http 1.4.2", ] [[package]] @@ -3844,11 +3613,11 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ - "bytes 1.11.1", + "bytes", "futures-core", - "http 1.4.0", + "http 1.4.2", "http-body 1.0.1", - "pin-project-lite 0.2.17", + "pin-project-lite", ] [[package]] @@ -3887,7 +3656,7 @@ version = "0.14.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" dependencies = [ - "bytes 1.11.1", + "bytes", "futures-channel", "futures-core", "futures-util", @@ -3897,9 +3666,9 @@ dependencies = [ "httparse", "httpdate", "itoa", - "pin-project-lite 0.2.17", - "socket2 0.4.10", - "tokio 1.52.3", + "pin-project-lite", + "socket2 0.5.10", + "tokio", "tower-service", "tracing", "want", @@ -3907,23 +3676,23 @@ dependencies = [ [[package]] name = "hyper" -version = "1.9.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" +checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498" dependencies = [ "atomic-waker", - "bytes 1.11.1", + "bytes", "futures-channel", "futures-core", - "h2 0.4.14", - "http 1.4.0", + "h2 0.4.15", + "http 1.4.2", "http-body 1.0.1", "httparse", "httpdate", "itoa", - "pin-project-lite 0.2.17", + "pin-project-lite", "smallvec", - "tokio 1.52.3", + "tokio", "want", ] @@ -3939,7 +3708,7 @@ dependencies = [ "log", "rustls 0.21.12", "rustls-native-certs 0.6.3", - "tokio 1.52.3", + "tokio", "tokio-rustls 0.24.1", ] @@ -3950,12 +3719,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" dependencies = [ "futures-util", - "http 1.4.0", - "hyper 1.9.0", + "http 1.4.2", + "hyper 1.10.1", "hyper-util", "rustls 0.22.4", "rustls-pki-types", - "tokio 1.52.3", + "tokio", "tokio-rustls 0.25.0", "tower-service", "webpki-roots 0.26.11", @@ -3967,12 +3736,12 @@ version = "0.27.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" dependencies = [ - "http 1.4.0", - "hyper 1.9.0", + "http 1.4.2", + "hyper 1.10.1", "hyper-util", - "rustls 0.23.40", - "rustls-native-certs 0.8.3", - "tokio 1.52.3", + "rustls 0.23.41", + "rustls-native-certs 0.8.4", + "tokio", "tokio-rustls 0.26.4", "tower-service", ] @@ -3983,10 +3752,10 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ - "bytes 1.11.1", + "bytes", "hyper 0.14.32", "native-tls", - "tokio 1.52.3", + "tokio", "tokio-native-tls", ] @@ -3997,19 +3766,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ "base64 0.22.1", - "bytes 1.11.1", + "bytes", "futures-channel", "futures-util", - "http 1.4.0", + "http 1.4.2", "http-body 1.0.1", - "hyper 1.9.0", + "hyper 1.10.1", "ipnet", "libc", "percent-encoding", - "pin-project-lite 0.2.17", - "socket2 0.6.3", + "pin-project-lite", + "socket2 0.6.4", "system-configuration 0.7.0", - "tokio 1.52.3", + "tokio", "tower-service", "tracing", "windows-registry", @@ -4121,12 +3890,6 @@ dependencies = [ "zerovec", ] -[[package]] -name = "id-arena" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" - [[package]] name = "ident_case" version = "1.0.1" @@ -4232,9 +3995,9 @@ checksum = "edcd27d72f2f071c64249075f42e205ff93c9a4c5f6c6da53e79ed9f9832c285" [[package]] name = "imgref" -version = "1.12.1" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40fac9d56ed6437b198fddba683305e8e2d651aa42647f00f5ae542e7f5c94a2" +checksum = "89194689a993ab15268672e99e7b0e19da2da3268ac682e8f02d29d4d1434cd7" [[package]] name = "impl_ops" @@ -4306,8 +4069,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -4316,7 +4079,7 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d40460c0ce33d6ce4b0630ad68ff63d6661961c48b6dba35e5a4d81cfb48222" dependencies = [ - "socket2 0.6.3", + "socket2 0.6.4", "widestring", "windows-registry", "windows-result", @@ -4340,7 +4103,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ "hermit-abi 0.5.2", "libc", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -4349,7 +4112,7 @@ version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82d93e1769c5c2b13a8e0d8ca9b6466c60bafade047326f25e3bcb97a947d875" dependencies = [ - "async-channel 2.5.0", + "async-channel", "castaway", "crossbeam-utils", "curl", @@ -4377,7 +4140,7 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d4e5d712dd664b11e778d1cfc06c79ba2700d6bc1771e44fb7b6a4656b487d" dependencies = [ - "generic-array 1.4.1", + "generic-array 1.4.3", "schemars", "serde", "time", @@ -4456,10 +4219,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" dependencies = [ "proc-macro2", - "quote 1.0.45", + "quote 1.0.46", "rustc_version", "simd_cesu8", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -4486,8 +4249,8 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" dependencies = [ - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -4502,13 +4265,12 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.98" +version = "0.3.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08" +checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31" dependencies = [ "cfg-if", "futures-util", - "once_cell", "wasm-bindgen", ] @@ -4624,9 +4386,9 @@ dependencies = [ [[package]] name = "jxl-grid" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0e0ef92d5d60e76bf41098e57e985f523185e08fad54268da448637feca6989" +checksum = "01671307879a033bfa52e6e8784b941aca770b3f3a7d33830b455b6844f793fb" dependencies = [ "tracing", ] @@ -4663,9 +4425,9 @@ dependencies = [ [[package]] name = "jxl-modular" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da758b2f989aafd9eeb39489fe43d7be5a3a0d2ad61cf1bad705eb6990a6053c" +checksum = "2a2f045b24c738dd91d482be385512b512721ae08a671bd4b27bf1c47f215235" dependencies = [ "jxl-bitstream", "jxl-coding", @@ -4677,9 +4439,9 @@ dependencies = [ [[package]] name = "jxl-oxide" -version = "0.12.5" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee8ecd2678ed70c1eda42b811ccb2e25ab836edeb18e7f1178c1f917ed36b772" +checksum = "d36c662923f47586880211f3bc7c0d83fb3a9b410d278c7bde93450748abeef3" dependencies = [ "brotli-decompressor", "bytemuck", @@ -4707,9 +4469,9 @@ dependencies = [ [[package]] name = "jxl-render" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa0c3100918bd3c41bb0f8ce1f4f1664e48f3032ff8eeab0d6a2cfc3276f462d" +checksum = "d34386bfdb6a19b5a30cc9beb4d475d537422c31ae8c39bb69640fcce3fcaf19" dependencies = [ "bytemuck", "jxl-bitstream", @@ -4785,27 +4547,18 @@ dependencies = [ "smallvec", ] -[[package]] -name = "kv-log-macro" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" -dependencies = [ - "log", -] - [[package]] name = "lapin" -version = "4.7.4" +version = "4.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f296d806dbacc044135c9686a0d3e78b5122907d4d6604c72a825316139e9f2d" +checksum = "0fd20e01fd92597ca352ca7ceed3c589851ebad279dfcada48aa4d24fd3a7caa" dependencies = [ "amq-protocol", "async-rs", "async-trait", - "atomic-waker", "backon", "cfg-if", + "event-listener 5.4.1", "flume", "futures-core", "futures-io", @@ -4844,12 +4597,6 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "leb128fmt" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" - [[package]] name = "lebe" version = "0.5.3" @@ -4876,7 +4623,7 @@ dependencies = [ "once_cell", "quoted_printable", "socket2 0.4.10", - "tokio 1.52.3", + "tokio", ] [[package]] @@ -4887,9 +4634,9 @@ checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libfuzzer-sys" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12a681b7dd8ce12bff52488013ba614b869148d54dd79836ab85aafdd53f08d" +checksum = "a9fd2f41a1cba099f79a0b6b6c35656cf7c03351a7bae8ff0f28f25270f929d2" dependencies = [ "arbitrary", "cc", @@ -4935,9 +4682,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.28" +version = "1.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc3a226e576f50782b3305c5ccf458698f92798987f551c6a02efe8276721e22" +checksum = "85bc9657773828b90eeb625adff10eeac83cc21bbfd8e23a03eaa8a33c9e28d9" dependencies = [ "cc", "libc", @@ -4986,7 +4733,7 @@ checksum = "6479ff15fd0108f8ebd698b4458dce5091686b8c11e130e08e99a925f1cc1881" dependencies = [ "base64 0.21.7", "device-info", - "http 1.4.0", + "http 1.4.2", "jsonwebtoken", "livekit-protocol", "log", @@ -4996,7 +4743,7 @@ dependencies = [ "prost", "rand 0.9.4", "reqwest 0.12.28", - "rustls-native-certs 0.8.3", + "rustls-native-certs 0.8.4", "scopeguard", "serde", "serde_json", @@ -5025,7 +4772,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "532e84c6cdc5fe774f2b5d9912597b5f3bea561927a48296d03e24549d21c3f6" dependencies = [ - "tokio 1.52.3", + "tokio", "tokio-stream", ] @@ -5040,12 +4787,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.29" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" -dependencies = [ - "value-bag", -] +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" [[package]] name = "logos" @@ -5066,10 +4810,10 @@ dependencies = [ "fnv", "lazy_static", "proc-macro2", - "quote 1.0.45", + "quote 1.0.46", "regex-syntax", "rustc_version", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -5140,8 +4884,8 @@ checksum = "cc33f9f0351468d26fbc53d9ce00a096c8522ecb42f19b50f34f2c422f76d21d" dependencies = [ "macro_magic_core", "macro_magic_macros", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -5154,8 +4898,8 @@ dependencies = [ "derive-syn-parse", "macro_magic_core_macros", "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -5165,8 +4909,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b02abfe41815b5bd98dbd4260173db2c116dda171dc0fe7838cb206333b83308" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -5176,8 +4920,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73ea28ee64b88876bf45277ed9a5817c1817df061a74f2b988971a12570e5869" dependencies = [ "macro_magic_core", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -5247,15 +4991,15 @@ dependencies = [ [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" [[package]] name = "memmap2" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" +checksum = "d1219ed1b7f229ee7104d281dd01d6802fe28bb6e95d292942c4daacdeb798c0" dependencies = [ "libc", ] @@ -5294,9 +5038,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" dependencies = [ "libc", "wasi", @@ -5309,7 +5053,6 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "316a7d198b51958a0ab57248bf5f42d8409551203cb3c821d5925819a8d5415f" dependencies = [ - "async-std", "async-trait", "futures-channel", "futures-core", @@ -5318,7 +5061,7 @@ dependencies = [ "log", "metrics", "thiserror 1.0.69", - "tokio 1.52.3", + "tokio", "tracing", "tracing-subscriber", ] @@ -5373,12 +5116,12 @@ checksum = "224484c5d09285a7b8cb0a0c117e847ebd14cb6e4470ecf68cdb89c503b0edb9" [[package]] name = "mongodb" -version = "3.6.0" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ef2c933617431ad0246fb5b43c425ebdae18c7f7259c87de0726d93b0e7e91b" +checksum = "276ba0cd571553d1f6936c6f180964776ece6ab7507dc8765f8a9c9c49d8cd00" dependencies = [ "base64 0.22.1", - "bitflags 2.11.1", + "bitflags 2.13.0", "bson", "derive-where", "derive_more 2.1.1", @@ -5386,8 +5129,9 @@ dependencies = [ "futures-io", "futures-util", "hex", - "hickory-proto 0.25.2", - "hickory-resolver 0.25.2", + "hickory-net", + "hickory-proto", + "hickory-resolver", "hmac 0.12.1", "macro_magic", "md-5 0.10.6", @@ -5397,36 +5141,35 @@ dependencies = [ "percent-encoding", "rand 0.9.4", "rustc_version_runtime", - "rustls 0.23.40", - "rustversion", + "rustls 0.23.41", "serde", "serde_bytes", "serde_with", "sha1 0.10.6", "sha2 0.10.9", - "socket2 0.6.3", + "socket2 0.6.4", "stringprep", "strsim 0.11.1", "take_mut", "thiserror 2.0.18", - "tokio 1.52.3", + "tokio", "tokio-rustls 0.26.4", "tokio-util", "typed-builder", "uuid", - "webpki-roots 1.0.7", + "webpki-roots 1.0.8", ] [[package]] name = "mongodb-internal-macros" -version = "3.6.0" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5758dc828eb2d02ec30563cba365609d56ddd833190b192beaee2b475a7bb3" +checksum = "99ceb1a9a1018e470077ec94cf3a8c2d0e6da542b2c05ea95a59a0a627147375" dependencies = [ "macro_magic", "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -5445,15 +5188,15 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b" dependencies = [ - "bytes 1.11.1", + "bytes", "encoding_rs", "futures-util", - "http 1.4.0", + "http 1.4.2", "httparse", "memchr", "mime", "spin 0.9.8", - "tokio 1.52.3", + "tokio", "tokio-util", "version_check", ] @@ -5510,11 +5253,11 @@ checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" [[package]] name = "nix" -version = "0.30.1" +version = "0.31.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" +checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "cfg-if", "cfg_aliases", "libc", @@ -5569,7 +5312,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -5611,8 +5354,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -5683,8 +5426,8 @@ checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" dependencies = [ "proc-macro-crate", "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -5711,7 +5454,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "objc2", "objc2-foundation", ] @@ -5732,7 +5475,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "dispatch2", "objc2", ] @@ -5743,7 +5486,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "dispatch2", "objc2", "objc2-core-foundation", @@ -5776,7 +5519,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "objc2", "objc2-core-foundation", "objc2-core-graphics", @@ -5794,7 +5537,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "block2", "libc", "objc2", @@ -5807,7 +5550,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "objc2", "objc2-core-foundation", ] @@ -5818,7 +5561,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "objc2", "objc2-core-foundation", "objc2-foundation", @@ -5830,7 +5573,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "block2", "objc2", "objc2-cloud-kit", @@ -5883,12 +5626,6 @@ dependencies = [ "portable-atomic", ] -[[package]] -name = "oorandom" -version = "11.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" - [[package]] name = "opaque-debug" version = "0.3.1" @@ -5897,11 +5634,11 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.80" +version = "0.10.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a45fa2aa886c42762255da344f0a0d313e254066c46aad76f300c3d3da62d967" +checksum = "77823a27f0babb03091cb9ed9ef80af3b39dbc82f97e8fa530374b7dafd87a45" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "cfg-if", "foreign-types 0.3.2", "libc", @@ -5916,8 +5653,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -5934,9 +5671,9 @@ checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] name = "openssl-sys" -version = "0.9.116" +version = "0.9.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28a22dc7140cda5f096e5e7724a6962ca81a7f8bfd2979f9b18c11af56318c4" +checksum = "b47e7e6bb2c38cd930d25a23b40fa52e068c10e85f3e03a7f5ba5aaca5713695" dependencies = [ "cc", "libc", @@ -5956,9 +5693,9 @@ dependencies = [ [[package]] name = "os_info" -version = "3.14.0" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4022a17595a00d6a369236fdae483f0de7f0a339960a53118b818238e132224" +checksum = "9cf20a545b305cf1da722b236b5155c9bb35f1d5ceb28c048bd96ca842f41b5b" dependencies = [ "android_system_properties", "log", @@ -6098,7 +5835,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18f596653ba4ac51bdecbb4ef6773bc7f56042dc13927910de1684ad3d32aa12" dependencies = [ - "bytes 1.11.1", + "bytes", "chrono", "pbjson", "pbjson-build", @@ -6119,9 +5856,9 @@ dependencies = [ [[package]] name = "pdk-classy" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fa3e632c61a7f8ad1a77c4f52d9a85a89c577881f44e89b33e28163af38e515" +checksum = "2b272f9dc3cd8446c4be61715a2396d1c0dea022e45c701c8446fa7bc81a0448" dependencies = [ "bincode", "futures", @@ -6138,9 +5875,9 @@ dependencies = [ [[package]] name = "pdk-core" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60f2b1d1c8876b54d03d35a18fba1e5172ed8d7f1c379001c11b62c909fdf654" +checksum = "94e3a49e0045a651298424a582db6ef81978b3f619f914b485feb2a8d3cb18eb" dependencies = [ "anyhow", "log", @@ -6159,9 +5896,9 @@ dependencies = [ [[package]] name = "pdk-ip-filter-lib" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dab00d1dfe7b232fcb5424c3af23721993b439a51960f1f3152760228f492ec" +checksum = "0eab0326a148dc64b3ce0b444b9be79e77e2c32c8a11e98800cb897f46d077ec" dependencies = [ "anyhow", "ipnet", @@ -6171,20 +5908,20 @@ dependencies = [ [[package]] name = "pdk-macros" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da346bb3e02aad6b6bf31e6e38798c0f3cdf8bd0319fe97d44addc5a0ea5de92" +checksum = "c3123ab64f4cea8374fbb6d0697997a209fe16794e330caacb4914967530d10a" dependencies = [ "proc-macro2", - "quote 1.0.45", + "quote 1.0.46", "syn 1.0.109", ] [[package]] name = "pdk-pel" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c60996708c43b91581ea9e6fa324af7eae5a9b8146dd96cacf2868e9260b654" +checksum = "7af9cbea6ed98d843d106e95451ea907b5e411061e23783b86a37c5748f7be3a" dependencies = [ "base64 0.22.1", "getrandom 0.2.17", @@ -6195,19 +5932,18 @@ dependencies = [ [[package]] name = "pdk-proxy-wasm-stub" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469571b12631b71dce33890917bec59f58c53f9d3b05b748d5aa873c950e1702" +checksum = "9469584d6a62ac97a46cfd3e67a270dbac8af33e27169b4e87a1a7f2e10d321f" [[package]] name = "pdk-script" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8842ea2908eb9b94ed7daa522cc75fcd5fe3738a20d7ecde67cb7829dbf129e" +checksum = "db9968802349bd53285e846450a534ff91d9c9d51f9bd1da4e833eff17b906d9" dependencies = [ "log", "num-traits", - "oorandom", "pdk-classy", "pdk-pel", "roxmltree", @@ -6236,8 +5972,8 @@ checksum = "4bab5b985dc082b345f812b7df84e1bef27e7207b39e448439ba8bd69c93f147" dependencies = [ "proc-macro2", "proc-macro2-diagnostics", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -6314,8 +6050,8 @@ dependencies = [ "pest", "pest_meta", "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -6406,8 +6142,8 @@ dependencies = [ "phf_generator 0.11.3", "phf_shared 0.11.3", "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -6450,16 +6186,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] -[[package]] -name = "pin-project-lite" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" - [[package]] name = "pin-project-lite" version = "0.2.17" @@ -6581,7 +6311,7 @@ version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "crc32fast", "fdeflate", "flate2", @@ -6597,7 +6327,7 @@ dependencies = [ "cfg-if", "concurrent-queue", "hermit-abi 0.5.2", - "pin-project-lite 0.2.17", + "pin-project-lite", "rustix 1.1.4", "windows-sys 0.61.2", ] @@ -6678,7 +6408,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -6708,7 +6438,7 @@ checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", "proc-macro2", - "quote 1.0.45", + "quote 1.0.46", "syn 1.0.109", "version_check", ] @@ -6720,32 +6450,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ "proc-macro2", - "quote 1.0.45", + "quote 1.0.46", "version_check", ] -[[package]] -name = "proc-macro-error-attr2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" -dependencies = [ - "proc-macro2", - "quote 1.0.45", -] - -[[package]] -name = "proc-macro-error2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" -dependencies = [ - "proc-macro-error-attr2", - "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", -] - [[package]] name = "proc-macro2" version = "1.0.106" @@ -6762,8 +6470,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", "version_check", "yansi", ] @@ -6783,8 +6491,8 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4488a4a36b9a4ba6b9334a32a39971f77c1436ec82c38707bce707699cc3bbcb" dependencies = [ - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -6807,7 +6515,7 @@ version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" dependencies = [ - "bytes 1.11.1", + "bytes", "prost-derive", ] @@ -6817,8 +6525,8 @@ version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" dependencies = [ - "bytes 1.11.1", - "heck 0.4.1", + "bytes", + "heck 0.5.0", "itertools 0.12.1", "log", "multimap", @@ -6828,7 +6536,7 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 2.0.117", + "syn 2.0.118", "tempfile", ] @@ -6841,8 +6549,8 @@ dependencies = [ "anyhow", "itertools 0.12.1", "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -6907,9 +6615,9 @@ dependencies = [ [[package]] name = "proxy-wasm" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8d35d9e2bc5104e2e954b149aa1d5f9fa3bb27f73b45b2706020fed101db685" +checksum = "de8f6564bd52c2f4ff79fa5d1bd3bc10d8f822162af8d527e121e46703496aa0" dependencies = [ "hashbrown 0.16.1", "log", @@ -6950,38 +6658,38 @@ checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" [[package]] name = "quinn" -version = "0.11.9" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8" dependencies = [ - "bytes 1.11.1", + "bytes", "cfg_aliases", - "pin-project-lite 0.2.17", + "pin-project-lite", "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.23.40", - "socket2 0.6.3", + "rustls 0.23.41", + "socket2 0.6.4", "thiserror 2.0.18", - "tokio 1.52.3", + "tokio", "tracing", "web-time", ] [[package]] name = "quinn-proto" -version = "0.11.14" +version = "0.11.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" +checksum = "4fcb935c5bec503c2f0e306bdd3e58bb9029dcb14fa8d9ac76e3a5256ac0763e" dependencies = [ "aws-lc-rs", - "bytes 1.11.1", + "bytes", "getrandom 0.3.4", "lru-slab", "rand 0.9.4", "ring", "rustc-hash", - "rustls 0.23.40", + "rustls 0.23.41", "rustls-pki-types", "slab", "thiserror 2.0.18", @@ -6999,7 +6707,7 @@ dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.6.3", + "socket2 0.6.4", "tracing", "windows-sys 0.60.2", ] @@ -7012,9 +6720,9 @@ checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" [[package]] name = "quote" -version = "1.0.45" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" dependencies = [ "proc-macro2", ] @@ -7071,7 +6779,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" dependencies = [ "chacha20", - "getrandom 0.4.2", + "getrandom 0.4.3", "rand_core 0.10.1", ] @@ -7203,18 +6911,17 @@ name = "redis" version = "0.23.3" source = "git+https://github.com/revoltchat/redis-rs?rev=523b2937367e17bd0073722bf6e23d06042cb4e4#523b2937367e17bd0073722bf6e23d06042cb4e4" dependencies = [ - "async-std", "async-trait", - "bytes 1.11.1", + "bytes", "combine", "futures-util", "itoa", "percent-encoding", - "pin-project-lite 0.2.17", + "pin-project-lite", "ryu", "sha1_smol", "socket2 0.4.10", - "tokio 1.52.3", + "tokio", "tokio-util", "url", ] @@ -7241,7 +6948,7 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c31deddf734dc0a39d3112e73490e88b61a05e83e074d211f348404cee4d2c6" dependencies = [ - "bytes 1.11.1", + "bytes", "bytes-utils", "cookie-factory", "crc16", @@ -7255,7 +6962,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", ] [[package]] @@ -7274,8 +6981,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -7320,7 +7027,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ "base64 0.21.7", - "bytes 1.11.1", + "bytes", "encoding_rs", "futures-core", "futures-util", @@ -7336,14 +7043,14 @@ dependencies = [ "native-tls", "once_cell", "percent-encoding", - "pin-project-lite 0.2.17", + "pin-project-lite", "rustls-pemfile 1.0.4", "serde", "serde_json", "serde_urlencoded", "sync_wrapper 0.1.2", "system-configuration 0.5.1", - "tokio 1.52.3", + "tokio", "tokio-native-tls", "tower-service", "url", @@ -7360,27 +7067,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ "base64 0.22.1", - "bytes 1.11.1", + "bytes", "futures-core", - "http 1.4.0", + "http 1.4.2", "http-body 1.0.1", "http-body-util", - "hyper 1.9.0", + "hyper 1.10.1", "hyper-rustls 0.27.9", "hyper-util", "js-sys", "log", "percent-encoding", - "pin-project-lite 0.2.17", + "pin-project-lite", "quinn", - "rustls 0.23.40", - "rustls-native-certs 0.8.3", + "rustls 0.23.41", + "rustls-native-certs 0.8.4", "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", "sync_wrapper 1.0.2", - "tokio 1.52.3", + "tokio", "tokio-rustls 0.26.4", "tower", "tower-http 0.6.11", @@ -7393,35 +7100,35 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62e0021ea2c22aed41653bc7e1419abb2c97e038ff2c33d0e1309e49a97deec0" +checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3" dependencies = [ "base64 0.22.1", - "bytes 1.11.1", + "bytes", "encoding_rs", "futures-core", - "h2 0.4.14", - "http 1.4.0", + "h2 0.4.15", + "http 1.4.2", "http-body 1.0.1", "http-body-util", - "hyper 1.9.0", + "hyper 1.10.1", "hyper-rustls 0.27.9", "hyper-util", "js-sys", "log", "mime", "percent-encoding", - "pin-project-lite 0.2.17", + "pin-project-lite", "quinn", - "rustls 0.23.40", + "rustls 0.23.41", "rustls-pki-types", "rustls-platform-verifier", "serde", "serde_json", "serde_urlencoded", "sync_wrapper 1.0.2", - "tokio 1.52.3", + "tokio", "tokio-rustls 0.26.4", "tower", "tower-http 0.6.11", @@ -7485,7 +7192,7 @@ dependencies = [ "strum_macros", "tempfile", "thumbhash", - "tokio 1.52.3", + "tokio", "tower-http 0.5.2", "tracing", "tracing-subscriber", @@ -7500,8 +7207,7 @@ dependencies = [ name = "revolt-bonfire" version = "0.13.7" dependencies = [ - "async-channel 2.5.0", - "async-std", + "async-channel", "async-tungstenite", "bincode", "fred", @@ -7523,6 +7229,8 @@ dependencies = [ "sentry", "serde", "serde_json", + "tokio", + "tokio-util", "ulid", ] @@ -7532,14 +7240,13 @@ version = "0.13.7" dependencies = [ "indexmap 2.14.0", "lru", - "tokio 1.52.3", + "tokio", ] [[package]] name = "revolt-config" version = "0.13.7" dependencies = [ - "async-std", "cached", "config", "futures-locks", @@ -7549,6 +7256,7 @@ dependencies = [ "sentry", "sentry-anyhow", "serde", + "tokio", ] [[package]] @@ -7569,7 +7277,7 @@ dependencies = [ "revolt_optional_struct", "serde", "serde_json", - "tokio 1.52.3", + "tokio", ] [[package]] @@ -7578,7 +7286,6 @@ version = "0.13.7" dependencies = [ "async-lock 2.8.0", "async-recursion", - "async-std", "async-trait", "axum", "base32", @@ -7605,7 +7312,7 @@ dependencies = [ "rand 0.8.6", "redis-kiss", "regex", - "reqwest 0.13.3", + "reqwest 0.13.4", "revolt-coalesced", "revolt-config", "revolt-models", @@ -7622,6 +7329,7 @@ dependencies = [ "serde", "serde_json", "sha1 0.10.6", + "tokio", "totp-lite", "ulid", "unicode-segmentation", @@ -7634,8 +7342,7 @@ dependencies = [ name = "revolt-delta" version = "0.13.7" dependencies = [ - "async-channel 2.5.0", - "async-std", + "async-channel", "bitfield", "chrono", "dashmap", @@ -7655,7 +7362,7 @@ dependencies = [ "rand 0.8.6", "redis-kiss", "regex", - "reqwest 0.13.3", + "reqwest 0.13.4", "revolt-config", "revolt-database", "revolt-models", @@ -7671,6 +7378,7 @@ dependencies = [ "schemars", "serde", "serde_json", + "tokio", "ulid", "url", "validator", @@ -7697,7 +7405,7 @@ dependencies = [ "tempfile", "thiserror 2.0.18", "tiny-skia", - "tokio 1.52.3", + "tokio", "tracing", "typenum", "usvg", @@ -7712,7 +7420,7 @@ dependencies = [ "axum", "axum-extra", "lru_time_cache", - "reqwest 0.13.3", + "reqwest 0.13.4", "revolt-coalesced", "revolt-config", "revolt-database", @@ -7721,7 +7429,7 @@ dependencies = [ "revolt-result", "serde", "serde_json", - "tokio 1.52.3", + "tokio", "tower-http 0.5.2", "tracing", "utoipa", @@ -7741,7 +7449,7 @@ dependencies = [ "moka", "pdk-ip-filter-lib", "regex", - "reqwest 0.13.3", + "reqwest 0.13.4", "revolt-config", "revolt-files", "revolt-models", @@ -7750,7 +7458,7 @@ dependencies = [ "serde", "serde_json", "tempfile", - "tokio 1.52.3", + "tokio", "tracing", "tracing-subscriber", "url", @@ -7789,7 +7497,6 @@ dependencies = [ name = "revolt-permissions" version = "0.13.7" dependencies = [ - "async-std", "async-trait", "auto_ops", "bson", @@ -7798,18 +7505,19 @@ dependencies = [ "revolt-result", "schemars", "serde", + "tokio", ] [[package]] name = "revolt-presence" version = "0.13.7" dependencies = [ - "async-std", "log", "once_cell", "rand 0.8.6", "redis-kiss", "revolt-config", + "tokio", ] [[package]] @@ -7837,7 +7545,7 @@ dependencies = [ "revolt_optional_struct", "serde", "serde_json", - "tokio 1.52.3", + "tokio", "ulid", "web-push", ] @@ -7878,7 +7586,6 @@ dependencies = [ name = "revolt-voice-ingress" version = "0.13.7" dependencies = [ - "async-std", "chrono", "futures", "livekit-api", @@ -7909,9 +7616,9 @@ checksum = "edbe1f79cb41271d3cd8f932d75dddeba963c19dc93d1ee6cbe0391b495ab2f5" dependencies = [ "base64 0.21.7", "erased-serde", - "http 1.4.0", + "http 1.4.2", "http-body-util", - "hyper 1.9.0", + "hyper 1.10.1", "hyper-rustls 0.26.0", "hyper-util", "openssl", @@ -7923,7 +7630,7 @@ dependencies = [ "serde", "serde_json", "thiserror 1.0.69", - "tokio 1.52.3", + "tokio", ] [[package]] @@ -7978,7 +7685,7 @@ checksum = "cc6620569d8ac8f0a1690fcca13f488503807a60e96ebf729749b59aca1dbef9" dependencies = [ "darling 0.13.4", "proc-macro2", - "quote 1.0.45", + "quote 1.0.46", "rocket_http", "syn 1.0.109", ] @@ -8045,7 +7752,7 @@ dependencies = [ "async-trait", "atomic 0.5.3", "binascii", - "bytes 1.11.1", + "bytes", "either", "figment", "futures", @@ -8055,7 +7762,7 @@ dependencies = [ "multer", "num_cpus", "parking_lot", - "pin-project-lite 0.2.17", + "pin-project-lite", "rand 0.8.6", "ref-cast", "rocket_codegen", @@ -8065,7 +7772,7 @@ dependencies = [ "state", "tempfile", "time", - "tokio 1.52.3", + "tokio", "tokio-stream", "tokio-util", "ubyte", @@ -8083,9 +7790,9 @@ dependencies = [ "glob", "indexmap 2.14.0", "proc-macro2", - "quote 1.0.45", + "quote 1.0.46", "rocket_http", - "syn 2.0.117", + "syn 2.0.118", "unicode-xid 0.2.6", "version_check", ] @@ -8133,14 +7840,14 @@ dependencies = [ "memchr", "pear", "percent-encoding", - "pin-project-lite 0.2.17", + "pin-project-lite", "ref-cast", "serde", "smallvec", "stable-pattern", "state", "time", - "tokio 1.52.3", + "tokio", "uncased", ] @@ -8280,7 +7987,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "errno", "libc", "linux-raw-sys 0.4.15", @@ -8293,11 +8000,11 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "errno", "libc", "linux-raw-sys 0.12.1", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -8328,9 +8035,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.40" +version = "0.23.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" +checksum = "6b92b125634d9b795e7beca796cc790df15a7fb38323bf3196fda83292d06b1f" dependencies = [ "aws-lc-rs", "log", @@ -8344,14 +8051,14 @@ dependencies = [ [[package]] name = "rustls-connector" -version = "0.23.2" +version = "0.23.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "546c32c0a03187814b1e1239eec017778dc9b87d8241a2c5c1954c47ab8ac8fd" +checksum = "b7664e32b0ffbec386bdf1d7cbca51a89551a90d3278f135186cd6cb3cfa889c" dependencies = [ "futures-io", "futures-rustls", "log", - "rustls 0.23.40", + "rustls 0.23.41", "rustls-pki-types", "rustls-platform-verifier", "rustls-webpki 0.103.13", @@ -8371,9 +8078,9 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" +checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d" dependencies = [ "openssl-probe 0.2.1", "rustls-pki-types", @@ -8420,14 +8127,14 @@ dependencies = [ "jni 0.22.4", "log", "once_cell", - "rustls 0.23.40", - "rustls-native-certs 0.8.3", + "rustls 0.23.41", + "rustls-native-certs 0.8.4", "rustls-platform-verifier-android", "rustls-webpki 0.103.13", "security-framework 3.7.0", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -8481,7 +8188,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c85d1ccd519e61834798eb52c4e886e8c2d7d698dd3d6ce0b1b47eb8557f1181" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "bytemuck", "core_maths", "log", @@ -8547,9 +8254,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d" dependencies = [ "proc-macro2", - "quote 1.0.45", + "quote 1.0.46", "serde_derive_internals", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -8638,7 +8345,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "core-foundation 0.9.4", "core-foundation-sys", "libc", @@ -8651,7 +8358,7 @@ version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "core-foundation 0.10.1", "core-foundation-sys", "libc", @@ -8674,7 +8381,7 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4eb30575f3638fc8f6815f448d50cb1a2e255b0897985c8c59f4d37b72a07b06" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "cssparser", "derive_more 0.99.20", "fxhash", @@ -8708,7 +8415,7 @@ dependencies = [ "sentry-debug-images", "sentry-panic", "sentry-tracing", - "tokio 1.52.3", + "tokio", "ureq", ] @@ -8887,8 +8594,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -8898,15 +8605,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ "indexmap 2.14.0", "itoa", @@ -8950,9 +8657,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.20.0" +version = "3.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e72c1c2cb7b223fafb600a619537a871c2818583d619401b785e7c0b746ccde2" +checksum = "76a5c54c7310e7b8b9577c286d7e399ddd876c3e12b3ed917a8aabc4b96e9e8c" dependencies = [ "serde_core", "serde_with_macros", @@ -8960,14 +8667,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.20.0" +version = "3.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b90c488738ecb4fb0262f41f43bc40efc5868d9fb744319ddf5f5317f417bfac" +checksum = "84d57bc0c8b9a17920c178daa6bb924850d54a9c97ab45194bb8c17ad66bb660" dependencies = [ "darling 0.23.0", "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -9051,9 +8758,9 @@ dependencies = [ [[package]] name = "shlex" -version = "1.3.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] name = "signal-hook-registry" @@ -9107,7 +8814,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" dependencies = [ - "quote 1.0.45", + "quote 1.0.46", ] [[package]] @@ -9158,16 +8865,16 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "160b744a45e8261307bcfe03c98e2f8274502207d534c9a64b675c4db1b6bd58" dependencies = [ - "async-channel 2.5.0", + "async-channel", "futures-core", "futures-io", ] [[package]] name = "smallvec" -version = "1.15.1" +version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" [[package]] name = "socket2" @@ -9191,12 +8898,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -9289,7 +8996,7 @@ dependencies = [ "phf_generator 0.11.3", "phf_shared 0.11.3", "proc-macro2", - "quote 1.0.45", + "quote 1.0.46", ] [[package]] @@ -9323,9 +9030,9 @@ checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ "heck 0.5.0", "proc-macro2", - "quote 1.0.45", + "quote 1.0.46", "rustversion", - "syn 2.0.117", + "syn 2.0.118", ] [[package]] @@ -9362,18 +9069,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", - "quote 1.0.45", + "quote 1.0.46", "unicode-ident", ] [[package]] name = "syn" -version = "2.0.117" +version = "2.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" dependencies = [ "proc-macro2", - "quote 1.0.45", + "quote 1.0.46", "unicode-ident", ] @@ -9408,7 +9115,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ "proc-macro2", - "quote 1.0.45", + "quote 1.0.46", "syn 1.0.109", "unicode-xid 0.2.6", ] @@ -9420,8 +9127,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -9455,7 +9162,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "core-foundation 0.9.4", "system-configuration-sys 0.6.0", ] @@ -9500,9 +9207,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tcp-stream" -version = "0.34.10" +version = "0.34.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8da40490cac3733b85c67b831f64e2132fdaa0929f42a6d4cf458d339777473" +checksum = "300d0735de48a565461c2ea14cc75b80ee5b6be3b4f5aeabe3553e4c2df8d23d" dependencies = [ "async-rs", "cfg-if", @@ -9518,10 +9225,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand 2.4.1", - "getrandom 0.4.2", + "getrandom 0.4.3", "once_cell", "rustix 1.1.4", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -9569,8 +9276,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -9580,8 +9287,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -9615,12 +9322,11 @@ dependencies = [ [[package]] name = "time" -version = "0.3.47" +version = "0.3.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +checksum = "85c17d80feb7334b40c484e45ed1a5273dfd8bfda537c3be2e74a06a6686f327" dependencies = [ "deranged", - "itoa", "libc", "num-conv", "num_threads", @@ -9632,15 +9338,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" [[package]] name = "time-macros" -version = "0.2.27" +version = "0.2.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" +checksum = "dcef1a61bdb119096e153208ec5cbec23944ce8bca13be5c7f60c634f7403935" dependencies = [ "num-conv", "time-core", @@ -9706,30 +9412,19 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" -[[package]] -name = "tokio" -version = "0.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6703a273949a90131b290be1fe7b039d0fc884aa1935860dfcbe056f28cd8092" -dependencies = [ - "bytes 0.5.6", - "pin-project-lite 0.1.12", - "slab", -] - [[package]] name = "tokio" version = "1.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" dependencies = [ - "bytes 1.11.1", + "bytes", "libc", "mio", "parking_lot", - "pin-project-lite 0.2.17", + "pin-project-lite", "signal-hook-registry", - "socket2 0.6.3", + "socket2 0.6.4", "tokio-macros", "windows-sys 0.61.2", ] @@ -9741,8 +9436,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -9752,7 +9447,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ "native-tls", - "tokio 1.52.3", + "tokio", ] [[package]] @@ -9762,7 +9457,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ "rustls 0.21.12", - "tokio 1.52.3", + "tokio", ] [[package]] @@ -9773,7 +9468,7 @@ checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" dependencies = [ "rustls 0.22.4", "rustls-pki-types", - "tokio 1.52.3", + "tokio", ] [[package]] @@ -9782,8 +9477,8 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ - "rustls 0.23.40", - "tokio 1.52.3", + "rustls 0.23.41", + "tokio", ] [[package]] @@ -9793,8 +9488,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" dependencies = [ "futures-core", - "pin-project-lite 0.2.17", - "tokio 1.52.3", + "pin-project-lite", + "tokio", ] [[package]] @@ -9805,10 +9500,10 @@ checksum = "8f72a05e828585856dacd553fba484c242c46e391fb0e58917c942ee9202915c" dependencies = [ "futures-util", "log", - "rustls 0.23.40", - "rustls-native-certs 0.8.3", + "rustls 0.23.41", + "rustls-native-certs 0.8.4", "rustls-pki-types", - "tokio 1.52.3", + "tokio", "tokio-rustls 0.26.4", "tungstenite 0.29.0", ] @@ -9819,12 +9514,13 @@ version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" dependencies = [ - "bytes 1.11.1", + "bytes", "futures-core", "futures-io", "futures-sink", - "pin-project-lite 0.2.17", - "tokio 1.52.3", + "futures-util", + "pin-project-lite", + "tokio", ] [[package]] @@ -9908,9 +9604,9 @@ checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" dependencies = [ "futures-core", "futures-util", - "pin-project-lite 0.2.17", + "pin-project-lite", "sync_wrapper 1.0.2", - "tokio 1.52.3", + "tokio", "tower-layer", "tower-service", "tracing", @@ -9922,12 +9618,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ - "bitflags 2.11.1", - "bytes 1.11.1", - "http 1.4.0", + "bitflags 2.13.0", + "bytes", + "http 1.4.2", "http-body 1.0.1", "http-body-util", - "pin-project-lite 0.2.17", + "pin-project-lite", "tower-layer", "tower-service", ] @@ -9938,12 +9634,12 @@ version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" dependencies = [ - "bitflags 2.11.1", - "bytes 1.11.1", + "bitflags 2.13.0", + "bytes", "futures-util", - "http 1.4.0", + "http 1.4.2", "http-body 1.0.1", - "pin-project-lite 0.2.17", + "pin-project-lite", "tower", "tower-layer", "tower-service", @@ -9969,7 +9665,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "log", - "pin-project-lite 0.2.17", + "pin-project-lite", "tracing-attributes", "tracing-core", ] @@ -9981,8 +9677,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -10057,7 +9753,7 @@ checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0" dependencies = [ "base64 0.13.1", "byteorder", - "bytes 1.11.1", + "bytes", "http 0.2.12", "httparse", "log", @@ -10074,13 +9770,13 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c01152af293afb9c7c2a57e4b559c5620b421f6d133261c60dd2d0cdb38e6b8" dependencies = [ - "bytes 1.11.1", + "bytes", "data-encoding", - "http 1.4.0", + "http 1.4.2", "httparse", "log", "rand 0.9.4", - "rustls 0.23.40", + "rustls 0.23.41", "rustls-pki-types", "sha1 0.10.6", "thiserror 2.0.18", @@ -10103,15 +9799,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e48cea23f68d1f78eb7bc092881b6bb88d3d6b5b7e6234f6f9c911da1ffb221" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] name = "typenum" -version = "1.20.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] name = "ubyte" @@ -10220,9 +9916,9 @@ checksum = "383ad40bb927465ec0ce7720e033cb4ca06912855fc35db31b5755d0de75b1ee" [[package]] name = "unicode-segmentation" -version = "1.13.2" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" [[package]] name = "unicode-vo" @@ -10364,9 +10060,9 @@ checksum = "20c24e8ab68ff9ee746aad22d39b5535601e6416d1b0feeabf78be986a5c4392" dependencies = [ "proc-macro-error", "proc-macro2", - "quote 1.0.45", + "quote 1.0.46", "regex", - "syn 2.0.117", + "syn 2.0.118", "ulid", ] @@ -10384,11 +10080,11 @@ dependencies = [ [[package]] name = "uuid" -version = "1.23.1" +version = "1.23.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" +checksum = "144d6b123cef80b301b8f72a9e2ca4370ddec21950d0a103dd22c437006d2db7" dependencies = [ - "getrandom 0.4.2", + "getrandom 0.4.3", "js-sys", "serde_core", "wasm-bindgen", @@ -10431,7 +10127,7 @@ dependencies = [ "lazy_static", "proc-macro-error", "proc-macro2", - "quote 1.0.45", + "quote 1.0.46", "regex", "syn 1.0.109", "validator_types", @@ -10453,12 +10149,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" -[[package]] -name = "value-bag" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba6f5989077681266825251a52748b8c1d8a4ad098cc37e440103d0ea717fc0" - [[package]] name = "vcpkg" version = "0.2.15" @@ -10528,36 +10218,27 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.3+wasi-0.2.9" +version = "1.0.4+wasi-0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" dependencies = [ - "wit-bindgen 0.57.1", -] - -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" -dependencies = [ - "wit-bindgen 0.51.0", + "wit-bindgen", ] [[package]] name = "wasix" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1757e0d1f8456693c7e5c6c629bdb54884e032aa0bb53c155f6a39f94440d332" +checksum = "ae86f02046da16a333a9129d31451423e1657737ecdafed4193838a5f54c5cfe" dependencies = [ "wasi", ] [[package]] name = "wasm-bindgen" -version = "0.2.121" +version = "0.2.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790" +checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a" dependencies = [ "cfg-if", "once_cell", @@ -10568,9 +10249,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.71" +version = "0.4.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96492d0d3ffba25305a7dc88720d250b1401d7edca02cc3bcd50633b424673b8" +checksum = "503b14d284f2c8dac03b819967e155ea753f573586193b2b2c95990cb5d69280" dependencies = [ "js-sys", "wasm-bindgen", @@ -10578,70 +10259,36 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.121" +version = "0.2.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578" +checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d" dependencies = [ - "quote 1.0.45", + "quote 1.0.46", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.121" +version = "0.2.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2" +checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd" dependencies = [ "bumpalo", "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.121" +version = "0.2.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441" +checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f" dependencies = [ "unicode-ident", ] -[[package]] -name = "wasm-encoder" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" -dependencies = [ - "leb128fmt", - "wasmparser", -] - -[[package]] -name = "wasm-metadata" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap 2.14.0", - "wasm-encoder", - "wasmparser", -] - -[[package]] -name = "wasmparser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" -dependencies = [ - "bitflags 2.11.1", - "hashbrown 0.15.5", - "indexmap 2.14.0", - "semver", -] - [[package]] name = "web-push" version = "0.10.4" @@ -10666,9 +10313,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.98" +version = "0.3.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b572dff8bcf38bad0fa19729c89bb5748b2b9b1d8be70cf90df697e3a8f32aa" +checksum = "a6430a72df5eb332242960fe84b3002a241163998241eb596d4f739b9757061d" dependencies = [ "js-sys", "wasm-bindgen", @@ -10696,9 +10343,9 @@ dependencies = [ [[package]] name = "webpki-root-certs" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31141ce3fc3e300ae89b78c0dd67f9708061d1d2eda54b8209346fd6be9a92c" +checksum = "0d46a5a140e6f7afeccd8eae97eff335163939eac8b929834875168b29b3d267" dependencies = [ "rustls-pki-types", ] @@ -10709,14 +10356,14 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "webpki-roots 1.0.7", + "webpki-roots 1.0.8", ] [[package]] name = "webpki-roots" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52f5ee44c96cf55f1b349600768e3ece3a8f26010c05265ab73f945bb1a2eb9d" +checksum = "bf85cb06032201fa7c6f829d7db5a7e5aa45bcc0655327713065f6f0576731bf" dependencies = [ "rustls-pki-types", ] @@ -10767,7 +10414,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.61.2", ] [[package]] @@ -10805,8 +10452,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -10816,8 +10463,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -11180,100 +10827,12 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "wit-bindgen" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" -dependencies = [ - "wit-bindgen-rust-macro", -] - [[package]] name = "wit-bindgen" version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" -[[package]] -name = "wit-bindgen-core" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" -dependencies = [ - "anyhow", - "heck 0.5.0", - "wit-parser", -] - -[[package]] -name = "wit-bindgen-rust" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" -dependencies = [ - "anyhow", - "heck 0.5.0", - "indexmap 2.14.0", - "prettyplease", - "syn 2.0.117", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", -] - -[[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" -dependencies = [ - "anyhow", - "prettyplease", - "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", - "wit-bindgen-core", - "wit-bindgen-rust", -] - -[[package]] -name = "wit-component" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" -dependencies = [ - "anyhow", - "bitflags 2.11.1", - "indexmap 2.14.0", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder", - "wasm-metadata", - "wasmparser", - "wit-parser", -] - -[[package]] -name = "wit-parser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" -dependencies = [ - "anyhow", - "id-arena", - "indexmap 2.14.0", - "log", - "semver", - "serde", - "serde_derive", - "serde_json", - "unicode-xid 0.2.6", - "wasmparser", -] - [[package]] name = "writeable" version = "0.6.3" @@ -11355,9 +10914,9 @@ dependencies = [ [[package]] name = "yoke" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -11371,8 +10930,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", "synstructure 0.13.2", ] @@ -11398,29 +10957,29 @@ dependencies = [ "serde", "serde_json", "time", - "tokio 1.52.3", + "tokio", "tower-service", "url", ] [[package]] name = "zerocopy" -version = "0.8.48" +version = "0.8.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.48" +version = "0.8.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -11439,29 +10998,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", "synstructure 0.13.2", ] [[package]] name = "zeroize" -version = "1.8.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" dependencies = [ "zeroize_derive", ] [[package]] name = "zeroize_derive" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" +checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] @@ -11493,8 +11052,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", - "quote 1.0.45", - "syn 2.0.117", + "quote 1.0.46", + "syn 2.0.118", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 173740d4d..dcbdb01d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,11 +23,11 @@ async-trait = "0.1.89" tokio = "1.49.0" async-channel = "2.3.1" futures = "0.3.32" -async-std = "1.8.0" async-tungstenite = "0.17.0" futures-locks = "0.7.1" async-lock = "2.8.0" async-recursion = "1.0.4" +tokio-util = { version = "0.7.18" } # Error Handling anyhow = "1.0.100" @@ -89,7 +89,7 @@ log = "0.4.29" pretty_env_logger = "0.4.0" # Redis -redis-kiss = "0.1.4" +redis-kiss = { version = "0.1.4", default-features = false } fred = "8.0.1" # Serialisation @@ -160,8 +160,8 @@ opentelemetry-appender-tracing = "0.31.1" lapin = "4.7.1" # Voice -livekit-api = "0.4.4" -livekit-protocol = "0.7.4" +livekit-api = "=0.4.23" +livekit-protocol = "=0.7.7" livekit-runtime = "0.4.0" # Other Utilities diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index b2a8dffe1..91dc90c29 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -14,7 +14,7 @@ sentry = { workspace = true } lru = { workspace = true } ulid = { workspace = true } once_cell = { workspace = true } -redis-kiss = { workspace = true } +redis-kiss = { workspace = true, default-features = false, features = ["tokio-runtime"] } lru_time_cache = { workspace = true } async-channel = { workspace = true } @@ -30,8 +30,9 @@ serde = { workspace = true } # async futures = { workspace = true } -async-tungstenite = { workspace = true, features = ["async-std-runtime"] } -async-std = { workspace = true } +async-tungstenite = { workspace = true, features = ["tokio-runtime"] } +tokio = { workspace = true } +tokio-util = { workspace = true, features = ["compat"] } # core revolt-result = { workspace = true } diff --git a/crates/bonfire/src/events/state.rs b/crates/bonfire/src/events/state.rs index daa22269a..09bef49eb 100644 --- a/crates/bonfire/src/events/state.rs +++ b/crates/bonfire/src/events/state.rs @@ -2,7 +2,7 @@ use std::{ collections::{HashMap, HashSet}, num::NonZeroUsize, sync::Arc, time::Duration }; -use async_std::sync::{Mutex, RwLock}; +use tokio::sync::{Mutex, RwLock}; use lru::LruCache; use lru_time_cache::{LruCache as LruTimeCache, TimedEntry}; use revolt_database::{Channel, Member, Server, User}; diff --git a/crates/bonfire/src/main.rs b/crates/bonfire/src/main.rs index f4e8a3870..e592a7a33 100644 --- a/crates/bonfire/src/main.rs +++ b/crates/bonfire/src/main.rs @@ -1,6 +1,6 @@ use std::env; -use async_std::net::TcpListener; +use tokio::net::TcpListener; use revolt_presence::clear_region; #[macro_use] @@ -12,7 +12,7 @@ pub mod events; mod database; mod websocket; -#[async_std::main] +#[tokio::main] async fn main() { // Configure requirements for Bonfire. revolt_config::configure!(events); @@ -33,7 +33,7 @@ async fn main() { // Start accepting new connections and spawn a client for each connection. while let Ok((stream, addr)) = listener.accept().await { - async_std::task::spawn(async move { + tokio::task::spawn(async move { info!("User connected from {addr:?}"); websocket::client(database::get_db(), stream, addr).await; info!("User disconnected from {addr:?}"); diff --git a/crates/bonfire/src/websocket.rs b/crates/bonfire/src/websocket.rs index 718c5c525..172cf74a0 100644 --- a/crates/bonfire/src/websocket.rs +++ b/crates/bonfire/src/websocket.rs @@ -21,11 +21,12 @@ use revolt_database::{ }; use revolt_presence::{create_session, delete_session}; -use async_std::{ +use tokio::{ net::TcpStream, sync::{Mutex, RwLock}, task::spawn, }; +use tokio_util::compat::{TokioAsyncReadCompatExt, Compat}; use revolt_result::create_error; use sentry::Level; @@ -33,8 +34,8 @@ use crate::config::{ProtocolConfiguration, WebsocketHandshakeCallback}; use crate::events::state::{State, SubscriptionStateChange}; use revolt_models::v0; -type WsReader = SplitStream>; -type WsWriter = SplitSink, async_tungstenite::tungstenite::Message>; +type WsReader = SplitStream>>; +type WsWriter = SplitSink>, async_tungstenite::tungstenite::Message>; /// Start a new WebSocket client worker given access to the database, /// the relevant TCP stream and the remote address of the client. @@ -44,7 +45,7 @@ pub async fn client(db: &'static Database, stream: TcpStream, addr: SocketAddr) // e.g. wss://example.com?format=json&version=1 let (sender, receiver) = oneshot::channel(); let Ok(ws) = async_tungstenite::accept_hdr_async_with_config( - stream, + stream.compat(), WebsocketHandshakeCallback::from(sender), None, ) diff --git a/crates/core/config/Cargo.toml b/crates/core/config/Cargo.toml index 7cda04472..59d2f6af3 100644 --- a/crates/core/config/Cargo.toml +++ b/crates/core/config/Cargo.toml @@ -13,7 +13,7 @@ repository = "https://github.com/stoatchat/stoatchat" anyhow = ["dep:sentry-anyhow"] report-macros = ["revolt-result"] sentry = ["dep:sentry"] -test = ["async-std"] +test = ["tokio"] default = ["sentry"] [dependencies] @@ -26,7 +26,7 @@ serde = { workspace = true } # Async futures-locks = { workspace = true } -async-std = { workspace = true, features = ["attributes"], optional = true } +tokio = { workspace = true, optional = true } # Logging log = { workspace = true } diff --git a/crates/core/config/src/lib.rs b/crates/core/config/src/lib.rs index 257dfa509..937892080 100644 --- a/crates/core/config/src/lib.rs +++ b/crates/core/config/src/lib.rs @@ -586,7 +586,7 @@ macro_rules! configure { mod tests { use crate::init; - #[async_std::test] + #[tokio::test] async fn it_works() { init().await; } diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index a8f8b18ab..38d831746 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -15,7 +15,7 @@ mongodb = ["dep:mongodb", "bson"] # ... Other tasks = ["isahc", "linkify", "url-escape"] -async-std-runtime = ["async-std"] +tokio-runtime = ["tokio"] rocket-impl = [ "rocket", "schemars", @@ -27,7 +27,7 @@ redis-is-patched = ["revolt-presence/redis-is-patched"] voice = ["livekit-api", "livekit-protocol", "livekit-runtime"] # Default Features -default = ["mongodb", "async-std-runtime", "tasks"] +default = ["mongodb", "tokio-runtime", "tasks"] [dependencies] # Core @@ -64,7 +64,7 @@ serde = { workspace = true } iso8601-timestamp = { workspace = true, features = ["serde", "bson"] } # Events -redis-kiss = { workspace = true } +redis-kiss = { workspace = true, default-features = false, features = ["tokio-runtime"] } # Database bson = { workspace = true, optional = true } @@ -81,7 +81,7 @@ async-trait = { workspace = true } async-recursion = { workspace = true } # Async -async-std = { workspace = true, features = ["attributes"], optional = true } +tokio = { workspace = true, optional = true } # Axum Impl axum = { workspace = true, optional = true } diff --git a/crates/core/database/src/lib.rs b/crates/core/database/src/lib.rs index 778206dce..0ab9b6ce9 100644 --- a/crates/core/database/src/lib.rs +++ b/crates/core/database/src/lib.rs @@ -25,8 +25,8 @@ pub use mongodb; #[macro_use] extern crate bson; -#[cfg(not(feature = "async-std-runtime"))] -compile_error!("async-std-runtime feature must be enabled."); +#[cfg(not(feature = "tokio-runtime"))] +compile_error!("tokio-runtime feature must be enabled."); #[macro_export] #[cfg(debug_assertions)] diff --git a/crates/core/database/src/models/admin_migrations/model.rs b/crates/core/database/src/models/admin_migrations/model.rs index 2c65c8116..5d113b1fa 100644 --- a/crates/core/database/src/models/admin_migrations/model.rs +++ b/crates/core/database/src/models/admin_migrations/model.rs @@ -11,7 +11,7 @@ auto_derived!( #[cfg(test)] mod tests { - #[async_std::test] + #[tokio::test] async fn migrate() { database_test!(|db| async move { // Initialise the database diff --git a/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs b/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs index 01d6b3e76..ab3053f5a 100644 --- a/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs +++ b/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs @@ -452,7 +452,7 @@ pub async fn run_migrations(db: &MongoDb, revision: i32) -> i32 { warn!("This is a destructive operation and will wipe existing permission data (excl. defaults for SendMessage)."); warn!("Taking a backup is advised."); warn!("Continuing in 10 seconds..."); - async_std::task::sleep(Duration::from_secs(10)).await; + tokio::time::sleep(Duration::from_secs(10)).await; let servers = db.col::("servers"); let mut cursor = servers.find(doc! {}).await.unwrap(); diff --git a/crates/core/database/src/models/bots/model.rs b/crates/core/database/src/models/bots/model.rs index 24c56bb1b..8d7a8d3df 100644 --- a/crates/core/database/src/models/bots/model.rs +++ b/crates/core/database/src/models/bots/model.rs @@ -164,7 +164,7 @@ impl Bot { mod tests { use crate::{Bot, FieldsBot, PartialBot, User}; - #[async_std::test] + #[tokio::test] async fn crud() { database_test!(|db| async move { let owner = User::create(&db, "Owner".to_string(), None, None) diff --git a/crates/core/database/src/models/channel_webhooks/model.rs b/crates/core/database/src/models/channel_webhooks/model.rs index cdf94db43..c13895528 100644 --- a/crates/core/database/src/models/channel_webhooks/model.rs +++ b/crates/core/database/src/models/channel_webhooks/model.rs @@ -128,7 +128,7 @@ impl Webhook { mod tests { use crate::{FieldsWebhook, PartialWebhook, Webhook}; - #[async_std::test] + #[tokio::test] async fn crud() { database_test!(|db| async move { let webhook_id = "webhook"; diff --git a/crates/core/database/src/models/channels/model.rs b/crates/core/database/src/models/channels/model.rs index b11b3f5d7..9712f5aae 100644 --- a/crates/core/database/src/models/channels/model.rs +++ b/crates/core/database/src/models/channels/model.rs @@ -787,7 +787,7 @@ mod tests { use crate::{fixture, util::permissions::DatabasePermissionQuery}; - #[async_std::test] + #[tokio::test] async fn permissions_group_channel() { database_test!(|db| async move { fixture!(db, "group_with_members", @@ -813,7 +813,7 @@ mod tests { }); } - #[async_std::test] + #[tokio::test] async fn permissions_text_channel() { database_test!(|db| async move { fixture!(db, "server_with_roles", diff --git a/crates/core/database/src/models/server_members/model.rs b/crates/core/database/src/models/server_members/model.rs index 2b8d3761d..18db53963 100644 --- a/crates/core/database/src/models/server_members/model.rs +++ b/crates/core/database/src/models/server_members/model.rs @@ -320,7 +320,7 @@ mod tests { use crate::{Member, PartialMember, RemovalIntention, Server, User}; - #[async_std::test] + #[tokio::test] async fn muted_member_rejoin() { database_test!(|db| async move { match db { diff --git a/crates/core/database/src/models/servers/model.rs b/crates/core/database/src/models/servers/model.rs index 50c45c59e..bf74c4102 100644 --- a/crates/core/database/src/models/servers/model.rs +++ b/crates/core/database/src/models/servers/model.rs @@ -420,7 +420,7 @@ mod tests { use crate::{fixture, util::permissions::DatabasePermissionQuery}; - #[async_std::test] + #[tokio::test] async fn permissions() { database_test!(|db| async move { fixture!(db, "server_with_roles", diff --git a/crates/core/database/src/models/users/model.rs b/crates/core/database/src/models/users/model.rs index cb2d3dfe3..a279e094d 100644 --- a/crates/core/database/src/models/users/model.rs +++ b/crates/core/database/src/models/users/model.rs @@ -926,7 +926,7 @@ mod tests { assert!(User::validate_username(username_https).is_err()); } - #[async_std::test] + #[tokio::test] async fn username_sanitisation_clean() { let username_clean = "Test"; @@ -936,7 +936,7 @@ mod tests { assert_eq!(username_clean, username_clean_sanitised.unwrap()); } - #[async_std::test] + #[tokio::test] async fn username_sanitisation_homoglyphs() { let username_homoglyphs = "𝔽𝕌Ňℕy"; @@ -947,7 +947,7 @@ mod tests { assert_eq!("funny", username_homoglyphs_sanitised); } - #[async_std::test] + #[tokio::test] async fn username_sanitisation_padding() { let username_padding = "a"; @@ -956,7 +956,7 @@ mod tests { assert_eq!("a_", username); } - #[async_std::test] + #[tokio::test] async fn create_user() { use revolt_result::Result; diff --git a/crates/core/database/src/tasks/ack.rs b/crates/core/database/src/tasks/ack.rs index 24e3805ee..558da47f7 100644 --- a/crates/core/database/src/tasks/ack.rs +++ b/crates/core/database/src/tasks/ack.rs @@ -305,6 +305,6 @@ pub async fn worker(db: Database, amqp: AMQP) { } // Sleep for an arbitrary amount of time. - async_std::task::sleep(Duration::from_secs(1)).await; + tokio::time::sleep(Duration::from_secs(1)).await; } } diff --git a/crates/core/database/src/tasks/last_message_id.rs b/crates/core/database/src/tasks/last_message_id.rs index 94c14c171..7314c2d0a 100644 --- a/crates/core/database/src/tasks/last_message_id.rs +++ b/crates/core/database/src/tasks/last_message_id.rs @@ -82,6 +82,6 @@ pub async fn worker(db: Database) { } // Sleep for an arbitrary amount of time. - async_std::task::sleep(Duration::from_secs(1)).await; + tokio::time::sleep(Duration::from_secs(1)).await; } } diff --git a/crates/core/database/src/tasks/mod.rs b/crates/core/database/src/tasks/mod.rs index d7e3df61d..69f57792d 100644 --- a/crates/core/database/src/tasks/mod.rs +++ b/crates/core/database/src/tasks/mod.rs @@ -2,7 +2,7 @@ use crate::{Database, AMQP}; -use async_std::task; +use tokio::task; use std::time::Instant; const WORKER_COUNT: usize = 5; diff --git a/crates/core/database/src/tasks/process_embeds.rs b/crates/core/database/src/tasks/process_embeds.rs index d9d61d75a..35b519546 100644 --- a/crates/core/database/src/tasks/process_embeds.rs +++ b/crates/core/database/src/tasks/process_embeds.rs @@ -7,11 +7,11 @@ use revolt_config::config; use revolt_result::Result; use async_lock::Semaphore; -use async_std::task::spawn; use deadqueue::limited::Queue; use once_cell::sync::Lazy; use revolt_models::v0::Embed; use std::{collections::HashSet, sync::Arc}; +use tokio::task::spawn; use isahc::prelude::*; @@ -159,6 +159,7 @@ pub async fn generate( .await .into_iter() .flatten() + .flatten() .collect::>(); // Prevent database update when no embeds are found. diff --git a/crates/core/database/src/util/idempotency.rs b/crates/core/database/src/util/idempotency.rs index 769dc1dd8..2de8ff158 100644 --- a/crates/core/database/src/util/idempotency.rs +++ b/crates/core/database/src/util/idempotency.rs @@ -5,7 +5,7 @@ use revolt_result::{create_error, Result}; #[cfg(feature = "rocket-impl")] use revolt_result::Error; -use async_std::sync::Mutex; +use tokio::sync::Mutex; use once_cell::sync::Lazy; use serde::{Deserialize, Serialize}; diff --git a/crates/core/permissions/Cargo.toml b/crates/core/permissions/Cargo.toml index 03ed629d6..b9e4eb403 100644 --- a/crates/core/permissions/Cargo.toml +++ b/crates/core/permissions/Cargo.toml @@ -18,7 +18,7 @@ try-from-primitive = ["dep:num_enum"] [dev-dependencies] # Async -async-std = { workspace = true, features = ["attributes"] } +tokio = { workspace = true } [dependencies] # Core diff --git a/crates/core/permissions/src/test.rs b/crates/core/permissions/src/test.rs index 93e1dea2c..f9225b0c4 100644 --- a/crates/core/permissions/src/test.rs +++ b/crates/core/permissions/src/test.rs @@ -4,7 +4,7 @@ use crate::{ DEFAULT_PERMISSION_SERVER, DEFAULT_PERMISSION_VIEW_ONLY, }; -#[async_std::test] +#[tokio::test] async fn validate_user_permissions() { /// Scenario in which we are friends with a user /// and we have a DM channel open with them @@ -102,7 +102,7 @@ async fn validate_user_permissions() { } } -#[async_std::test] +#[tokio::test] async fn validate_group_permissions() { /// Scenario in which we are in a group channel with only talking permission struct Scenario {} @@ -202,7 +202,7 @@ async fn validate_group_permissions() { } } -#[async_std::test] +#[tokio::test] async fn validate_server_permissions() { /// Scenario in which we are in a server channel where: /// - the server grants reading history and sending messages by default @@ -314,7 +314,7 @@ async fn validate_server_permissions() { } } -#[async_std::test] +#[tokio::test] async fn validate_timed_out_member() { /// Scenario in which we are in a server that we have been timed out from struct Scenario {} diff --git a/crates/core/presence/Cargo.toml b/crates/core/presence/Cargo.toml index 7868342d3..b0f7f1730 100644 --- a/crates/core/presence/Cargo.toml +++ b/crates/core/presence/Cargo.toml @@ -14,7 +14,7 @@ redis-is-patched = [] [dev-dependencies] # Async -async-std = { workspace = true, features = ["attributes"] } +tokio = { workspace = true } # Config for loading Redis URI revolt-config = { workspace = true } @@ -26,4 +26,4 @@ rand = { workspace = true } once_cell = { workspace = true } # Redis -redis-kiss = { workspace = true } +redis-kiss = { workspace = true, default-features = false, features = ["tokio-runtime"] } diff --git a/crates/core/presence/src/lib.rs b/crates/core/presence/src/lib.rs index 4c5ffda52..124eacc3a 100644 --- a/crates/core/presence/src/lib.rs +++ b/crates/core/presence/src/lib.rs @@ -195,7 +195,7 @@ mod tests { use crate::{clear_region, create_session, delete_session, filter_online, is_online}; use rand::Rng; - #[async_std::test] + #[tokio::test] async fn it_works() { revolt_config::config().await; diff --git a/crates/daemons/crond/Cargo.toml b/crates/daemons/crond/Cargo.toml index 5d0879ec4..75dc2c4e3 100644 --- a/crates/daemons/crond/Cargo.toml +++ b/crates/daemons/crond/Cargo.toml @@ -18,7 +18,7 @@ tokio = { workspace = true } futures = { workspace = true } # Redis -redis-kiss = { workspace = true } +redis-kiss = { workspace = true, default-features = false, features = ["tokio-runtime"] } # RabbitMQ lapin = { workspace = true } diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index bc7d3e432..1942bfb90 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -20,7 +20,7 @@ fcm_v1 = { workspace = true } web-push = { workspace = true } isahc = { workspace = true, features = ["json"], optional = true } revolt_a2 = { workspace = true, features = ["ring"] } -redis-kiss = { workspace = true } +redis-kiss = { workspace = true, default-features = false, features = ["tokio-runtime"] } tokio = { workspace = true } async-trait = { workspace = true } ulid = { workspace = true } diff --git a/crates/daemons/voice-ingress/Cargo.toml b/crates/daemons/voice-ingress/Cargo.toml index e28e71205..2c554b1fb 100644 --- a/crates/daemons/voice-ingress/Cargo.toml +++ b/crates/daemons/voice-ingress/Cargo.toml @@ -13,7 +13,7 @@ log = { workspace = true } sentry = { workspace = true } lru = { workspace = true } ulid = { workspace = true } -redis-kiss = { workspace = true } +redis-kiss = { workspace = true, default-features = false, features = ["tokio-runtime"] } chrono = { workspace = true } # Serde @@ -27,11 +27,6 @@ rocket_empty = { workspace = true } # Async futures = { workspace = true } -async-std = { workspace = true, features = [ - "tokio1", - "tokio02", - "attributes", -] } # Core revolt-result = { workspace = true, features = ["rocket"] } diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index 1bf3fb9e7..d9adb9837 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -11,7 +11,7 @@ publish = false [dependencies] # Test rand = { workspace = true } -redis-kiss = { workspace = true } +redis-kiss = { workspace = true, default-features = false, features = ["tokio-runtime"] } # Utility lru = { workspace = true } @@ -42,11 +42,7 @@ futures = { workspace = true } chrono = { workspace = true } async-channel = { workspace = true } reqwest = { workspace = true, features = ["json"] } -async-std = { workspace = true, features = [ - "tokio1", - "tokio02", - "attributes", -] } +tokio = { workspace = true } # internal util lettre = { workspace = true } diff --git a/crates/delta/src/routes/account/create_account.rs b/crates/delta/src/routes/account/create_account.rs index 019a6adcc..90f3f9d44 100644 --- a/crates/delta/src/routes/account/create_account.rs +++ b/crates/delta/src/routes/account/create_account.rs @@ -2,7 +2,7 @@ //! POST /account/create use std::time::Duration; -use async_std::task::sleep; +use tokio::time::sleep; use revolt_config::config; use revolt_database::{ util::{ diff --git a/crates/delta/src/routes/account/resend_verification.rs b/crates/delta/src/routes/account/resend_verification.rs index e418c8011..008407a37 100644 --- a/crates/delta/src/routes/account/resend_verification.rs +++ b/crates/delta/src/routes/account/resend_verification.rs @@ -2,7 +2,7 @@ //! POST /account/reverify use std::time::Duration; -use async_std::task::sleep; +use tokio::time::sleep; use rocket::{serde::json::Json, State}; use rocket_empty::EmptyResponse; use revolt_result::Result; diff --git a/crates/delta/src/routes/account/send_password_reset.rs b/crates/delta/src/routes/account/send_password_reset.rs index 862acd928..86a6fd218 100644 --- a/crates/delta/src/routes/account/send_password_reset.rs +++ b/crates/delta/src/routes/account/send_password_reset.rs @@ -2,7 +2,7 @@ //! POST /account/reset_password use std::time::Duration; -use async_std::task::sleep; +use tokio::time::sleep; use rocket::serde::json::Json; use rocket::State; use rocket_empty::EmptyResponse; diff --git a/crates/delta/src/routes/session/login.rs b/crates/delta/src/routes/session/login.rs index 7dc4571eb..46fca91ed 100644 --- a/crates/delta/src/routes/session/login.rs +++ b/crates/delta/src/routes/session/login.rs @@ -3,7 +3,7 @@ use std::ops::Add; use std::time::Duration; -use async_std::task::sleep; +use tokio::time::sleep; use iso8601_timestamp::Timestamp; use revolt_database::{ util::{email::normalise_email, password::assert_safe}, From 7c2098c6115be5832ba92ab29bc202810f7bd259 Mon Sep 17 00:00:00 2001 From: "stoat-release[bot]" <245062572+stoat-release[bot]@users.noreply.github.com> Date: Wed, 24 Jun 2026 10:46:38 -0700 Subject: [PATCH 206/211] chore(deps): update dependency github:git-town/git-town to v22.7.1 (#823) Co-authored-by: stoat-release[bot] <245062572+stoat-release[bot]@users.noreply.github.com> --- .mise/config.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mise/config.toml b/.mise/config.toml index f5238e777..331ba7971 100644 --- a/.mise/config.toml +++ b/.mise/config.toml @@ -7,7 +7,7 @@ gh = "2.25.0" rust = "1.92.0" "cargo:cargo-nextest" = "0.9.122" -"github:git-town/git-town" = "22.4.0" +"github:git-town/git-town" = "22.7.1" [settings] experimental = true From 6ece5cde3b94d547d6eb87997698da6e55dc6dad Mon Sep 17 00:00:00 2001 From: "stoat-release[bot]" <245062572+stoat-release[bot]@users.noreply.github.com> Date: Wed, 24 Jun 2026 10:47:21 -0700 Subject: [PATCH 207/211] chore(deps): update dependency gh to v2.95.0 (#822) Co-authored-by: stoat-release[bot] <245062572+stoat-release[bot]@users.noreply.github.com> --- .mise/config.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mise/config.toml b/.mise/config.toml index 331ba7971..7cee11fcf 100644 --- a/.mise/config.toml +++ b/.mise/config.toml @@ -2,7 +2,7 @@ node = "25.4.0" pnpm = "10.28.1" -gh = "2.25.0" +gh = "2.95.0" rust = "1.92.0" "cargo:cargo-nextest" = "0.9.122" From 23ba7d8fd865f94928718d6162dc0a16001dbb8e Mon Sep 17 00:00:00 2001 From: "stoat-release[bot]" <245062572+stoat-release[bot]@users.noreply.github.com> Date: Wed, 24 Jun 2026 10:54:14 -0700 Subject: [PATCH 208/211] chore(deps): update mwader/static-ffmpeg docker tag to v7.1.1 (#827) Co-authored-by: stoat-release[bot] <245062572+stoat-release[bot]@users.noreply.github.com> --- crates/services/autumn/Dockerfile | 4 ++-- crates/services/january/Dockerfile | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/services/autumn/Dockerfile b/crates/services/autumn/Dockerfile index 7d139122e..940703fed 100644 --- a/crates/services/autumn/Dockerfile +++ b/crates/services/autumn/Dockerfile @@ -5,8 +5,8 @@ FROM debian:12 AS debian # Bundle Stage FROM gcr.io/distroless/cc-debian12:nonroot COPY --from=builder /home/rust/src/target/release/revolt-autumn ./ -COPY --from=mwader/static-ffmpeg:7.0.2 /ffmpeg /usr/local/bin/ -COPY --from=mwader/static-ffmpeg:7.0.2 /ffprobe /usr/local/bin/ +COPY --from=mwader/static-ffmpeg:7.1.1 /ffmpeg /usr/local/bin/ +COPY --from=mwader/static-ffmpeg:7.1.1 /ffprobe /usr/local/bin/ COPY --from=debian /usr/bin/uname /usr/bin/uname EXPOSE 14704 diff --git a/crates/services/january/Dockerfile b/crates/services/january/Dockerfile index f1a0fc3cd..35d812ea9 100644 --- a/crates/services/january/Dockerfile +++ b/crates/services/january/Dockerfile @@ -5,8 +5,8 @@ FROM debian:12 AS debian # Bundle Stage FROM gcr.io/distroless/cc-debian12:nonroot COPY --from=builder /home/rust/src/target/release/revolt-january ./ -COPY --from=mwader/static-ffmpeg:7.0.2 /ffmpeg /usr/local/bin/ -COPY --from=mwader/static-ffmpeg:7.0.2 /ffprobe /usr/local/bin/ +COPY --from=mwader/static-ffmpeg:7.1.1 /ffmpeg /usr/local/bin/ +COPY --from=mwader/static-ffmpeg:7.1.1 /ffprobe /usr/local/bin/ COPY --from=debian /usr/bin/uname /usr/bin/uname EXPOSE 14705 From 9217c6e49b6629cd077e74d0d2bdb5318cc94b68 Mon Sep 17 00:00:00 2001 From: Zomatree Date: Thu, 25 Jun 2026 13:38:39 +0100 Subject: [PATCH 209/211] ci: fix concurrency group (#837) Signed-off-by: Zomatree --- .github/workflows/docker.yaml | 2 +- .github/workflows/rust.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 75aefeb63..69df98360 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -12,7 +12,7 @@ permissions: packages: write concurrency: - group: ${{ github.head_ref || github.ref }} + group: docker-test-${{ github.head_ref || github.ref }} cancel-in-progress: true jobs: diff --git a/.github/workflows/rust.yaml b/.github/workflows/rust.yaml index 3b7a78d22..99f218ee5 100644 --- a/.github/workflows/rust.yaml +++ b/.github/workflows/rust.yaml @@ -6,7 +6,7 @@ on: pull_request: concurrency: - group: ${{ github.head_ref || github.ref }} + group: rust-build-test-${{ github.head_ref || github.ref }} cancel-in-progress: true env: From 164be6a2da05c8b31909e227d9e410656e884cb2 Mon Sep 17 00:00:00 2001 From: Zomatree Date: Thu, 25 Jun 2026 18:57:12 +0100 Subject: [PATCH 210/211] Revert "chore(deps): update dependency gh to v2.95.0" (#840) Signed-off-by: Zomatree --- .mise/config.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mise/config.toml b/.mise/config.toml index 7cee11fcf..331ba7971 100644 --- a/.mise/config.toml +++ b/.mise/config.toml @@ -2,7 +2,7 @@ node = "25.4.0" pnpm = "10.28.1" -gh = "2.95.0" +gh = "2.25.0" rust = "1.92.0" "cargo:cargo-nextest" = "0.9.122" From a22378c35c2c6c84f8897ce897b9c4df420871d9 Mon Sep 17 00:00:00 2001 From: Zomatree Date: Sat, 27 Jun 2026 04:24:00 +0100 Subject: [PATCH 211/211] fix(docs): update react version (#842) Signed-off-by: Zomatree --- docs/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/package.json b/docs/package.json index 1c9f52156..f1c29cc9b 100644 --- a/docs/package.json +++ b/docs/package.json @@ -22,8 +22,8 @@ "@scalar/docusaurus": "^0.7.21", "clsx": "^2.0.0", "prism-react-renderer": "^2.3.0", - "react": "^19.0.0", - "react-dom": "^19.0.0" + "react": "^19.2.7", + "react-dom": "^19.2.7" }, "devDependencies": { "@docusaurus/module-type-aliases": "3.9.2",