From 11fdb0c1dcd07871d0df8512e4c0e222c320a3f9 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Tue, 1 Aug 2023 20:45:58 +0100 Subject: [PATCH] feat(core): implement emoji model closes #270 --- crates/core/database/src/drivers/reference.rs | 6 +- crates/core/database/src/events/client.rs | 13 +- crates/core/database/src/models/emojis/mod.rs | 5 + .../core/database/src/models/emojis/model.rs | 87 + crates/core/database/src/models/emojis/ops.rs | 24 + .../database/src/models/emojis/ops/mongodb.rs | 70 + .../src/models/emojis/ops/reference.rs | 67 + .../src/models/emojis/unicode_emoji.txt | 1850 +++++++++++++++++ crates/core/database/src/models/mod.rs | 3 + crates/core/database/src/util/bridge/v0.rs | 22 + crates/core/models/src/v0/emojis.rs | 33 + crates/core/models/src/v0/mod.rs | 4 + crates/core/models/src/v0/user_settings.rs | 6 + 13 files changed, 2180 insertions(+), 10 deletions(-) create mode 100644 crates/core/database/src/models/emojis/mod.rs create mode 100644 crates/core/database/src/models/emojis/model.rs create mode 100644 crates/core/database/src/models/emojis/ops.rs create mode 100644 crates/core/database/src/models/emojis/ops/mongodb.rs create mode 100644 crates/core/database/src/models/emojis/ops/reference.rs create mode 100644 crates/core/database/src/models/emojis/unicode_emoji.txt create mode 100644 crates/core/models/src/v0/emojis.rs create mode 100644 crates/core/models/src/v0/user_settings.rs diff --git a/crates/core/database/src/drivers/reference.rs b/crates/core/database/src/drivers/reference.rs index a9ec6b48..ee2f5fc2 100644 --- a/crates/core/database/src/drivers/reference.rs +++ b/crates/core/database/src/drivers/reference.rs @@ -3,8 +3,8 @@ use std::{collections::HashMap, sync::Arc}; use futures::lock::Mutex; use crate::{ - Bot, Channel, ChannelCompositeKey, ChannelUnread, File, Invite, Member, MemberCompositeKey, - Server, User, UserSettings, Webhook, + Bot, Channel, ChannelCompositeKey, ChannelUnread, Emoji, File, Invite, Member, + MemberCompositeKey, Server, User, UserSettings, Webhook, }; database_derived!( @@ -16,6 +16,7 @@ database_derived!( pub channel_invites: Arc>>, pub channel_unreads: Arc>>, pub channel_webhooks: Arc>>, + pub emojis: Arc>>, pub user_settings: Arc>>, pub users: Arc>>, pub server_members: Arc>>, @@ -24,7 +25,6 @@ database_derived!( pub server_bans: Arc>>, pub safety_reports: Arc>>, pub safety_snapshots: Arc>>, - pub emoji: Arc>>, pub messages: Arc>>, } ); diff --git a/crates/core/database/src/events/client.rs b/crates/core/database/src/events/client.rs index b19d3ef7..49c4fc79 100644 --- a/crates/core/database/src/events/client.rs +++ b/crates/core/database/src/events/client.rs @@ -2,7 +2,8 @@ use authifier::AuthifierEvent; use serde::{Deserialize, Serialize}; use revolt_models::v0::{ - Channel, FieldsChannel, FieldsWebhook, PartialChannel, PartialWebhook, Webhook, + Channel, Emoji, FieldsChannel, FieldsWebhook, PartialChannel, PartialWebhook, UserSettings, + Webhook, }; use revolt_result::Error; @@ -158,12 +159,11 @@ pub enum EventV1 { user: User, // ! this field can be deprecated status: RelationshipStatus, - }, - + },*/ /// Settings updated remotely UserSettingsUpdate { id: String, update: UserSettings }, - /// User has been platform banned or deleted their account + /*/// User has been platform banned or deleted their account /// /// Clients should remove the following associated data: /// - Messages @@ -172,15 +172,14 @@ 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), /// Delete emoji EmojiDelete { id: String }, - /// New report + /*/// New report ReportCreate(Report), */ /// New channel ChannelCreate(Channel), diff --git a/crates/core/database/src/models/emojis/mod.rs b/crates/core/database/src/models/emojis/mod.rs new file mode 100644 index 00000000..4d801b73 --- /dev/null +++ b/crates/core/database/src/models/emojis/mod.rs @@ -0,0 +1,5 @@ +mod model; +mod ops; + +pub use model::*; +pub use ops::*; diff --git a/crates/core/database/src/models/emojis/model.rs b/crates/core/database/src/models/emojis/model.rs new file mode 100644 index 00000000..8294d7c7 --- /dev/null +++ b/crates/core/database/src/models/emojis/model.rs @@ -0,0 +1,87 @@ +use std::collections::HashSet; +use std::str::FromStr; + +use once_cell::sync::Lazy; +use revolt_result::Result; +use ulid::Ulid; + +use crate::events::client::EventV1; +use crate::Database; + +static PERMISSIBLE_EMOJIS: Lazy> = Lazy::new(|| { + include_str!("unicode_emoji.txt") + .split('\n') + .map(|x| x.into()) + .collect() +}); + +auto_derived!( + /// Emoji + pub struct Emoji { + /// Unique Id + #[serde(rename = "_id")] + pub id: String, + /// What owns this emoji + pub parent: EmojiParent, + /// Uploader user id + pub creator_id: String, + /// Emoji name + pub name: String, + /// Whether the emoji is animated + #[serde(skip_serializing_if = "crate::if_false", default)] + pub animated: bool, + /// Whether the emoji is marked as nsfw + #[serde(skip_serializing_if = "crate::if_false", default)] + pub nsfw: bool, + } + + /// Parent Id of the emoji + #[serde(tag = "type")] + pub enum EmojiParent { + Server { id: String }, + Detached, + } +); + +#[allow(clippy::disallowed_methods)] +impl Emoji { + /// Get parent id + fn parent(&self) -> &str { + match &self.parent { + EmojiParent::Server { id } => id, + EmojiParent::Detached => "", + } + } + + /// Create an emoji + pub async fn create(&self, db: &Database) -> Result<()> { + db.insert_emoji(self).await?; + + EventV1::EmojiCreate(self.clone().into()) + .p(self.parent().to_string()) + .await; + + Ok(()) + } + + /// Delete an emoji + pub async fn delete(self, db: &Database) -> Result<()> { + EventV1::EmojiDelete { + id: self.id.to_string(), + } + .p(self.parent().to_string()) + .await; + + db.detach_emoji(&self).await + } + + /// 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() { + db.fetch_emoji(emoji).await?; + Ok(true) + } else { + Ok(PERMISSIBLE_EMOJIS.contains(emoji)) + } + } +} diff --git a/crates/core/database/src/models/emojis/ops.rs b/crates/core/database/src/models/emojis/ops.rs new file mode 100644 index 00000000..c0b51228 --- /dev/null +++ b/crates/core/database/src/models/emojis/ops.rs @@ -0,0 +1,24 @@ +use revolt_result::Result; + +use crate::Emoji; + +mod mongodb; +mod reference; + +#[async_trait] +pub trait AbstractEmojis: Sync + Send { + /// Insert emoji into database. + async fn insert_emoji(&self, emoji: &Emoji) -> Result<()>; + + /// Fetch an emoji by its id + async fn fetch_emoji(&self, id: &str) -> Result; + + /// Fetch emoji by their parent id + async fn fetch_emoji_by_parent_id(&self, parent_id: &str) -> Result>; + + /// Fetch emoji by their parent ids + async fn fetch_emoji_by_parent_ids(&self, parent_ids: &[String]) -> 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 new file mode 100644 index 00000000..882cc8ec --- /dev/null +++ b/crates/core/database/src/models/emojis/ops/mongodb.rs @@ -0,0 +1,70 @@ +use bson::Document; +use revolt_result::Result; + +use crate::Emoji; +use crate::MongoDb; + +use super::AbstractEmojis; + +static COL: &str = "emojis"; + +#[async_trait] +impl AbstractEmojis for MongoDb { + /// Insert emoji into database. + async fn insert_emoji(&self, emoji: &Emoji) -> Result<()> { + query!(self, insert_one, COL, &emoji).map(|_| ()) + } + + /// Fetch an emoji by its id + async fn fetch_emoji(&self, id: &str) -> Result { + query!(self, find_one_by_id, COL, id)?.ok_or_else(|| create_error!(NotFound)) + } + + /// Fetch emoji by their parent id + async fn fetch_emoji_by_parent_id(&self, parent_id: &str) -> Result> { + query!( + self, + find_one, + COL, + doc! { + "parent.id": parent_id + } + )? + .ok_or_else(|| create_error!(NotFound)) + } + + /// Fetch emoji by their parent ids + async fn fetch_emoji_by_parent_ids(&self, parent_ids: &[String]) -> Result> { + query!( + self, + find, + COL, + doc! { + "parent.id": { + "$in": parent_ids + } + } + ) + } + + /// Detach an emoji by its id + async fn detach_emoji(&self, emoji: &Emoji) -> Result<()> { + self.col::(COL) + .update_one( + doc! { + "_id": &emoji.id + }, + doc! { + "$set": { + "parent": { + "type": "Detached" + } + } + }, + None, + ) + .await + .map(|_| ()) + .map_err(|_| create_database_error!("update_one", COL)) + } +} diff --git a/crates/core/database/src/models/emojis/ops/reference.rs b/crates/core/database/src/models/emojis/ops/reference.rs new file mode 100644 index 00000000..2f0c2a2d --- /dev/null +++ b/crates/core/database/src/models/emojis/ops/reference.rs @@ -0,0 +1,67 @@ +use revolt_result::Result; + +use crate::Emoji; +use crate::EmojiParent; +use crate::ReferenceDb; + +use super::AbstractEmojis; + +#[async_trait] +impl AbstractEmojis for ReferenceDb { + /// Insert emoji into database. + async fn insert_emoji(&self, emoji: &Emoji) -> Result<()> { + let mut emojis = self.emojis.lock().await; + if emojis.contains_key(&emoji.id) { + Err(create_database_error!("insert", "emoji")) + } else { + emojis.insert(emoji.id.to_string(), emoji.clone()); + Ok(()) + } + } + + /// Fetch an emoji by its id + async fn fetch_emoji(&self, id: &str) -> Result { + let emojis = self.emojis.lock().await; + emojis + .get(id) + .cloned() + .ok_or_else(|| create_error!(NotFound)) + } + + /// Fetch emoji by their parent id + async fn fetch_emoji_by_parent_id(&self, parent_id: &str) -> Result> { + let emojis = self.emojis.lock().await; + Ok(emojis + .values() + .filter(|emoji| match &emoji.parent { + EmojiParent::Server { id } => id == parent_id, + _ => false, + }) + .cloned() + .collect()) + } + + /// Fetch emoji by their parent ids + async fn fetch_emoji_by_parent_ids(&self, parent_ids: &[String]) -> Result> { + let emojis = self.emojis.lock().await; + Ok(emojis + .values() + .filter(|emoji| match &emoji.parent { + EmojiParent::Server { id } => parent_ids.contains(id), + _ => false, + }) + .cloned() + .collect()) + } + + /// Detach an emoji by its id + async fn detach_emoji(&self, emoji: &Emoji) -> Result<()> { + let mut emojis = self.emojis.lock().await; + if let Some(bot) = emojis.get_mut(&emoji.id) { + bot.parent = EmojiParent::Detached; + Ok(()) + } else { + Err(create_error!(NotFound)) + } + } +} diff --git a/crates/core/database/src/models/emojis/unicode_emoji.txt b/crates/core/database/src/models/emojis/unicode_emoji.txt new file mode 100644 index 00000000..bc8036e3 --- /dev/null +++ b/crates/core/database/src/models/emojis/unicode_emoji.txt @@ -0,0 +1,1850 @@ +๐Ÿ’ฏ +๐Ÿ”ข +๐Ÿ˜€ +๐Ÿ˜ƒ +๐Ÿ˜„ +๐Ÿ˜ +๐Ÿ˜† +๐Ÿ˜† +๐Ÿ˜… +๐Ÿคฃ +๐Ÿ˜‚ +๐Ÿ™‚ +๐Ÿ™ƒ +๐Ÿ˜‰ +๐Ÿ˜Š +๐Ÿ˜‡ +๐Ÿฅฐ +๐Ÿ˜ +๐Ÿคฉ +๐Ÿ˜˜ +๐Ÿ˜— +โ˜บ๏ธ +๐Ÿ˜š +๐Ÿ˜™ +๐Ÿฅฒ +๐Ÿ˜‹ +๐Ÿ˜› +๐Ÿ˜œ +๐Ÿคช +๐Ÿ˜ +๐Ÿค‘ +๐Ÿค— +๐Ÿคญ +๐Ÿคซ +๐Ÿค” +๐Ÿค +๐Ÿคจ +๐Ÿ˜ +๐Ÿ˜‘ +๐Ÿ˜ถ +๐Ÿ˜ +๐Ÿ˜’ +๐Ÿ™„ +๐Ÿ˜ฌ +๐Ÿคฅ +๐Ÿ˜Œ +๐Ÿ˜” +๐Ÿ˜ช +๐Ÿคค +๐Ÿ˜ด +๐Ÿ˜ท +๐Ÿค’ +๐Ÿค• +๐Ÿคข +๐Ÿคฎ +๐Ÿคง +๐Ÿฅต +๐Ÿฅถ +๐Ÿฅด +๐Ÿ˜ต +๐Ÿคฏ +๐Ÿค  +๐Ÿฅณ +๐Ÿฅธ +๐Ÿ˜Ž +๐Ÿค“ +๐Ÿง +๐Ÿ˜• +๐Ÿ˜Ÿ +๐Ÿ™ +โ˜น๏ธ +๐Ÿ˜ฎ +๐Ÿ˜ฏ +๐Ÿ˜ฒ +๐Ÿ˜ณ +๐Ÿฅบ +๐Ÿ˜ฆ +๐Ÿ˜ง +๐Ÿ˜จ +๐Ÿ˜ฐ +๐Ÿ˜ฅ +๐Ÿ˜ข +๐Ÿ˜ญ +๐Ÿ˜ฑ +๐Ÿ˜– +๐Ÿ˜ฃ +๐Ÿ˜ž +๐Ÿ˜“ +๐Ÿ˜ฉ +๐Ÿ˜ซ +๐Ÿฅฑ +๐Ÿ˜ค +๐Ÿ˜ก +๐Ÿ˜ก +๐Ÿ˜  +๐Ÿคฌ +๐Ÿ˜ˆ +๐Ÿ‘ฟ +๐Ÿ’€ +โ˜ ๏ธ +๐Ÿ’ฉ +๐Ÿ’ฉ +๐Ÿ’ฉ +๐Ÿคก +๐Ÿ‘น +๐Ÿ‘บ +๐Ÿ‘ป +๐Ÿ‘ฝ +๐Ÿ‘พ +๐Ÿค– +๐Ÿ˜บ +๐Ÿ˜ธ +๐Ÿ˜น +๐Ÿ˜ป +๐Ÿ˜ผ +๐Ÿ˜ฝ +๐Ÿ™€ +๐Ÿ˜ฟ +๐Ÿ˜พ +๐Ÿ™ˆ +๐Ÿ™‰ +๐Ÿ™Š +๐Ÿ’‹ +๐Ÿ’Œ +๐Ÿ’˜ +๐Ÿ’ +๐Ÿ’– +๐Ÿ’— +๐Ÿ’“ +๐Ÿ’ž +๐Ÿ’• +๐Ÿ’Ÿ +โฃ๏ธ +๐Ÿ’” +โค๏ธ +๐Ÿงก +๐Ÿ’› +๐Ÿ’š +๐Ÿ’™ +๐Ÿ’œ +๐ŸคŽ +๐Ÿ–ค +๐Ÿค +๐Ÿ’ข +๐Ÿ’ฅ +๐Ÿ’ฅ +๐Ÿ’ซ +๐Ÿ’ฆ +๐Ÿ’จ +๐Ÿ•ณ๏ธ +๐Ÿ’ฃ +๐Ÿ’ฌ +๐Ÿ‘๏ธโ€๐Ÿ—จ๏ธ +๐Ÿ—จ๏ธ +๐Ÿ—ฏ๏ธ +๐Ÿ’ญ +๐Ÿ’ค +๐Ÿ‘‹ +๐Ÿคš +๐Ÿ–๏ธ +โœ‹ +โœ‹ +๐Ÿ–– +๐Ÿ‘Œ +๐ŸคŒ +๐Ÿค +โœŒ๏ธ +๐Ÿคž +๐ŸคŸ +๐Ÿค˜ +๐Ÿค™ +๐Ÿ‘ˆ +๐Ÿ‘‰ +๐Ÿ‘† +๐Ÿ–• +๐Ÿ–• +๐Ÿ‘‡ +โ˜๏ธ +๐Ÿ‘ +๐Ÿ‘ +๐Ÿ‘Ž +๐Ÿ‘Ž +โœŠ +โœŠ +๐Ÿ‘Š +๐Ÿ‘Š +๐Ÿ‘Š +๐Ÿค› +๐Ÿคœ +๐Ÿ‘ +๐Ÿ™Œ +๐Ÿ‘ +๐Ÿคฒ +๐Ÿค +๐Ÿ™ +โœ๏ธ +๐Ÿ’… +๐Ÿคณ +๐Ÿ’ช +๐Ÿฆพ +๐Ÿฆฟ +๐Ÿฆต +๐Ÿฆถ +๐Ÿ‘‚ +๐Ÿฆป +๐Ÿ‘ƒ +๐Ÿง  +๐Ÿซ€ +๐Ÿซ +๐Ÿฆท +๐Ÿฆด +๐Ÿ‘€ +๐Ÿ‘๏ธ +๐Ÿ‘… +๐Ÿ‘„ +๐Ÿ‘ถ +๐Ÿง’ +๐Ÿ‘ฆ +๐Ÿ‘ง +๐Ÿง‘ +๐Ÿ‘ฑ +๐Ÿ‘จ +๐Ÿง” +๐Ÿ‘จโ€๐Ÿฆฐ +๐Ÿ‘จโ€๐Ÿฆฑ +๐Ÿ‘จโ€๐Ÿฆณ +๐Ÿ‘จโ€๐Ÿฆฒ +๐Ÿ‘ฉ +๐Ÿ‘ฉโ€๐Ÿฆฐ +๐Ÿง‘โ€๐Ÿฆฐ +๐Ÿ‘ฉโ€๐Ÿฆฑ +๐Ÿง‘โ€๐Ÿฆฑ +๐Ÿ‘ฉโ€๐Ÿฆณ +๐Ÿง‘โ€๐Ÿฆณ +๐Ÿ‘ฉโ€๐Ÿฆฒ +๐Ÿง‘โ€๐Ÿฆฒ +๐Ÿ‘ฑโ€โ™€๏ธ +๐Ÿ‘ฑโ€โ™€๏ธ +๐Ÿ‘ฑโ€โ™‚๏ธ +๐Ÿง“ +๐Ÿ‘ด +๐Ÿ‘ต +๐Ÿ™ +๐Ÿ™โ€โ™‚๏ธ +๐Ÿ™โ€โ™€๏ธ +๐Ÿ™Ž +๐Ÿ™Žโ€โ™‚๏ธ +๐Ÿ™Žโ€โ™€๏ธ +๐Ÿ™… +๐Ÿ™…โ€โ™‚๏ธ +๐Ÿ™…โ€โ™‚๏ธ +๐Ÿ™…โ€โ™€๏ธ +๐Ÿ™…โ€โ™€๏ธ +๐Ÿ™† +๐Ÿ™†โ€โ™‚๏ธ +๐Ÿ™†โ€โ™€๏ธ +๐Ÿ’ +๐Ÿ’ +๐Ÿ’โ€โ™‚๏ธ +๐Ÿ’โ€โ™‚๏ธ +๐Ÿ’โ€โ™€๏ธ +๐Ÿ’โ€โ™€๏ธ +๐Ÿ™‹ +๐Ÿ™‹โ€โ™‚๏ธ +๐Ÿ™‹โ€โ™€๏ธ +๐Ÿง +๐Ÿงโ€โ™‚๏ธ +๐Ÿงโ€โ™€๏ธ +๐Ÿ™‡ +๐Ÿ™‡โ€โ™‚๏ธ +๐Ÿ™‡โ€โ™€๏ธ +๐Ÿคฆ +๐Ÿคฆโ€โ™‚๏ธ +๐Ÿคฆโ€โ™€๏ธ +๐Ÿคท +๐Ÿคทโ€โ™‚๏ธ +๐Ÿคทโ€โ™€๏ธ +๐Ÿง‘โ€โš•๏ธ +๐Ÿ‘จโ€โš•๏ธ +๐Ÿ‘ฉโ€โš•๏ธ +๐Ÿง‘โ€๐ŸŽ“ +๐Ÿ‘จโ€๐ŸŽ“ +๐Ÿ‘ฉโ€๐ŸŽ“ +๐Ÿง‘โ€๐Ÿซ +๐Ÿ‘จโ€๐Ÿซ +๐Ÿ‘ฉโ€๐Ÿซ +๐Ÿง‘โ€โš–๏ธ +๐Ÿ‘จโ€โš–๏ธ +๐Ÿ‘ฉโ€โš–๏ธ +๐Ÿง‘โ€๐ŸŒพ +๐Ÿ‘จโ€๐ŸŒพ +๐Ÿ‘ฉโ€๐ŸŒพ +๐Ÿง‘โ€๐Ÿณ +๐Ÿ‘จโ€๐Ÿณ +๐Ÿ‘ฉโ€๐Ÿณ +๐Ÿง‘โ€๐Ÿ”ง +๐Ÿ‘จโ€๐Ÿ”ง +๐Ÿ‘ฉโ€๐Ÿ”ง +๐Ÿง‘โ€๐Ÿญ +๐Ÿ‘จโ€๐Ÿญ +๐Ÿ‘ฉโ€๐Ÿญ +๐Ÿง‘โ€๐Ÿ’ผ +๐Ÿ‘จโ€๐Ÿ’ผ +๐Ÿ‘ฉโ€๐Ÿ’ผ +๐Ÿง‘โ€๐Ÿ”ฌ +๐Ÿ‘จโ€๐Ÿ”ฌ +๐Ÿ‘ฉโ€๐Ÿ”ฌ +๐Ÿง‘โ€๐Ÿ’ป +๐Ÿ‘จโ€๐Ÿ’ป +๐Ÿ‘ฉโ€๐Ÿ’ป +๐Ÿง‘โ€๐ŸŽค +๐Ÿ‘จโ€๐ŸŽค +๐Ÿ‘ฉโ€๐ŸŽค +๐Ÿง‘โ€๐ŸŽจ +๐Ÿ‘จโ€๐ŸŽจ +๐Ÿ‘ฉโ€๐ŸŽจ +๐Ÿง‘โ€โœˆ๏ธ +๐Ÿ‘จโ€โœˆ๏ธ +๐Ÿ‘ฉโ€โœˆ๏ธ +๐Ÿง‘โ€๐Ÿš€ +๐Ÿ‘จโ€๐Ÿš€ +๐Ÿ‘ฉโ€๐Ÿš€ +๐Ÿง‘โ€๐Ÿš’ +๐Ÿ‘จโ€๐Ÿš’ +๐Ÿ‘ฉโ€๐Ÿš’ +๐Ÿ‘ฎ +๐Ÿ‘ฎ +๐Ÿ‘ฎโ€โ™‚๏ธ +๐Ÿ‘ฎโ€โ™€๏ธ +๐Ÿ•ต๏ธ +๐Ÿ•ต๏ธโ€โ™‚๏ธ +๐Ÿ•ต๏ธโ€โ™€๏ธ +๐Ÿ’‚ +๐Ÿ’‚โ€โ™‚๏ธ +๐Ÿ’‚โ€โ™€๏ธ +๐Ÿฅท +๐Ÿ‘ท +๐Ÿ‘ทโ€โ™‚๏ธ +๐Ÿ‘ทโ€โ™€๏ธ +๐Ÿคด +๐Ÿ‘ธ +๐Ÿ‘ณ +๐Ÿ‘ณโ€โ™‚๏ธ +๐Ÿ‘ณโ€โ™€๏ธ +๐Ÿ‘ฒ +๐Ÿง• +๐Ÿคต +๐Ÿคตโ€โ™‚๏ธ +๐Ÿคตโ€โ™€๏ธ +๐Ÿ‘ฐ +๐Ÿ‘ฐโ€โ™‚๏ธ +๐Ÿ‘ฐโ€โ™€๏ธ +๐Ÿ‘ฐโ€โ™€๏ธ +๐Ÿคฐ +๐Ÿคฑ +๐Ÿ‘ฉโ€๐Ÿผ +๐Ÿ‘จโ€๐Ÿผ +๐Ÿง‘โ€๐Ÿผ +๐Ÿ‘ผ +๐ŸŽ… +๐Ÿคถ +๐Ÿง‘โ€๐ŸŽ„ +๐Ÿฆธ +๐Ÿฆธโ€โ™‚๏ธ +๐Ÿฆธโ€โ™€๏ธ +๐Ÿฆน +๐Ÿฆนโ€โ™‚๏ธ +๐Ÿฆนโ€โ™€๏ธ +๐Ÿง™ +๐Ÿง™โ€โ™‚๏ธ +๐Ÿง™โ€โ™€๏ธ +๐Ÿงš +๐Ÿงšโ€โ™‚๏ธ +๐Ÿงšโ€โ™€๏ธ +๐Ÿง› +๐Ÿง›โ€โ™‚๏ธ +๐Ÿง›โ€โ™€๏ธ +๐Ÿงœ +๐Ÿงœโ€โ™‚๏ธ +๐Ÿงœโ€โ™€๏ธ +๐Ÿง +๐Ÿงโ€โ™‚๏ธ +๐Ÿงโ€โ™€๏ธ +๐Ÿงž +๐Ÿงžโ€โ™‚๏ธ +๐Ÿงžโ€โ™€๏ธ +๐ŸงŸ +๐ŸงŸโ€โ™‚๏ธ +๐ŸงŸโ€โ™€๏ธ +๐Ÿ’† +๐Ÿ’†โ€โ™‚๏ธ +๐Ÿ’†โ€โ™€๏ธ +๐Ÿ’‡ +๐Ÿ’‡โ€โ™‚๏ธ +๐Ÿ’‡โ€โ™€๏ธ +๐Ÿšถ +๐Ÿšถโ€โ™‚๏ธ +๐Ÿšถโ€โ™€๏ธ +๐Ÿง +๐Ÿงโ€โ™‚๏ธ +๐Ÿงโ€โ™€๏ธ +๐ŸงŽ +๐ŸงŽโ€โ™‚๏ธ +๐ŸงŽโ€โ™€๏ธ +๐Ÿง‘โ€๐Ÿฆฏ +๐Ÿ‘จโ€๐Ÿฆฏ +๐Ÿ‘ฉโ€๐Ÿฆฏ +๐Ÿง‘โ€๐Ÿฆผ +๐Ÿ‘จโ€๐Ÿฆผ +๐Ÿ‘ฉโ€๐Ÿฆผ +๐Ÿง‘โ€๐Ÿฆฝ +๐Ÿ‘จโ€๐Ÿฆฝ +๐Ÿ‘ฉโ€๐Ÿฆฝ +๐Ÿƒ +๐Ÿƒ +๐Ÿƒโ€โ™‚๏ธ +๐Ÿƒโ€โ™€๏ธ +๐Ÿ’ƒ +๐Ÿ’ƒ +๐Ÿ•บ +๐Ÿ•ด๏ธ +๐Ÿ‘ฏ +๐Ÿ‘ฏโ€โ™‚๏ธ +๐Ÿ‘ฏโ€โ™€๏ธ +๐Ÿง– +๐Ÿง–โ€โ™‚๏ธ +๐Ÿง–โ€โ™€๏ธ +๐Ÿง— +๐Ÿง—โ€โ™‚๏ธ +๐Ÿง—โ€โ™€๏ธ +๐Ÿคบ +๐Ÿ‡ +โ›ท๏ธ +๐Ÿ‚ +๐ŸŒ๏ธ +๐ŸŒ๏ธโ€โ™‚๏ธ +๐ŸŒ๏ธโ€โ™€๏ธ +๐Ÿ„ +๐Ÿ„โ€โ™‚๏ธ +๐Ÿ„โ€โ™€๏ธ +๐Ÿšฃ +๐Ÿšฃโ€โ™‚๏ธ +๐Ÿšฃโ€โ™€๏ธ +๐ŸŠ +๐ŸŠโ€โ™‚๏ธ +๐ŸŠโ€โ™€๏ธ +โ›น๏ธ +โ›น๏ธโ€โ™‚๏ธ +โ›น๏ธโ€โ™‚๏ธ +โ›น๏ธโ€โ™€๏ธ +โ›น๏ธโ€โ™€๏ธ +๐Ÿ‹๏ธ +๐Ÿ‹๏ธโ€โ™‚๏ธ +๐Ÿ‹๏ธโ€โ™€๏ธ +๐Ÿšด +๐Ÿšดโ€โ™‚๏ธ +๐Ÿšดโ€โ™€๏ธ +๐Ÿšต +๐Ÿšตโ€โ™‚๏ธ +๐Ÿšตโ€โ™€๏ธ +๐Ÿคธ +๐Ÿคธโ€โ™‚๏ธ +๐Ÿคธโ€โ™€๏ธ +๐Ÿคผ +๐Ÿคผโ€โ™‚๏ธ +๐Ÿคผโ€โ™€๏ธ +๐Ÿคฝ +๐Ÿคฝโ€โ™‚๏ธ +๐Ÿคฝโ€โ™€๏ธ +๐Ÿคพ +๐Ÿคพโ€โ™‚๏ธ +๐Ÿคพโ€โ™€๏ธ +๐Ÿคน +๐Ÿคนโ€โ™‚๏ธ +๐Ÿคนโ€โ™€๏ธ +๐Ÿง˜ +๐Ÿง˜โ€โ™‚๏ธ +๐Ÿง˜โ€โ™€๏ธ +๐Ÿ›€ +๐Ÿ›Œ +๐Ÿง‘โ€๐Ÿคโ€๐Ÿง‘ +๐Ÿ‘ญ +๐Ÿ‘ซ +๐Ÿ‘ฌ +๐Ÿ’ +๐Ÿ‘ฉโ€โค๏ธโ€๐Ÿ’‹โ€๐Ÿ‘จ +๐Ÿ‘จโ€โค๏ธโ€๐Ÿ’‹โ€๐Ÿ‘จ +๐Ÿ‘ฉโ€โค๏ธโ€๐Ÿ’‹โ€๐Ÿ‘ฉ +๐Ÿ’‘ +๐Ÿ‘ฉโ€โค๏ธโ€๐Ÿ‘จ +๐Ÿ‘จโ€โค๏ธโ€๐Ÿ‘จ +๐Ÿ‘ฉโ€โค๏ธโ€๐Ÿ‘ฉ +๐Ÿ‘ช +๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆ +๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ง +๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ +๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ +๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง +๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘ฆ +๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘ง +๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ฆ +๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ +๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง +๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆ +๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘ง +๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ +๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ +๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง +๐Ÿ‘จโ€๐Ÿ‘ฆ +๐Ÿ‘จโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ +๐Ÿ‘จโ€๐Ÿ‘ง +๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ฆ +๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง +๐Ÿ‘ฉโ€๐Ÿ‘ฆ +๐Ÿ‘ฉโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ +๐Ÿ‘ฉโ€๐Ÿ‘ง +๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ +๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง +๐Ÿ—ฃ๏ธ +๐Ÿ‘ค +๐Ÿ‘ฅ +๐Ÿซ‚ +๐Ÿ‘ฃ +๐Ÿต +๐Ÿ’ +๐Ÿฆ +๐Ÿฆง +๐Ÿถ +๐Ÿ• +๐Ÿฆฎ +๐Ÿ•โ€๐Ÿฆบ +๐Ÿฉ +๐Ÿบ +๐ŸฆŠ +๐Ÿฆ +๐Ÿฑ +๐Ÿˆ +๐Ÿˆโ€โฌ› +๐Ÿฆ +๐Ÿฏ +๐Ÿ… +๐Ÿ† +๐Ÿด +๐ŸŽ +๐Ÿฆ„ +๐Ÿฆ“ +๐ŸฆŒ +๐Ÿฆฌ +๐Ÿฎ +๐Ÿ‚ +๐Ÿƒ +๐Ÿ„ +๐Ÿท +๐Ÿ– +๐Ÿ— +๐Ÿฝ +๐Ÿ +๐Ÿ‘ +๐Ÿ +๐Ÿช +๐Ÿซ +๐Ÿฆ™ +๐Ÿฆ’ +๐Ÿ˜ +๐Ÿฆฃ +๐Ÿฆ +๐Ÿฆ› +๐Ÿญ +๐Ÿ +๐Ÿ€ +๐Ÿน +๐Ÿฐ +๐Ÿ‡ +๐Ÿฟ๏ธ +๐Ÿฆซ +๐Ÿฆ” +๐Ÿฆ‡ +๐Ÿป +๐Ÿปโ€โ„๏ธ +๐Ÿจ +๐Ÿผ +๐Ÿฆฅ +๐Ÿฆฆ +๐Ÿฆจ +๐Ÿฆ˜ +๐Ÿฆก +๐Ÿพ +๐Ÿพ +๐Ÿฆƒ +๐Ÿ” +๐Ÿ“ +๐Ÿฃ +๐Ÿค +๐Ÿฅ +๐Ÿฆ +๐Ÿง +๐Ÿ•Š๏ธ +๐Ÿฆ… +๐Ÿฆ† +๐Ÿฆข +๐Ÿฆ‰ +๐Ÿฆค +๐Ÿชถ +๐Ÿฆฉ +๐Ÿฆš +๐Ÿฆœ +๐Ÿธ +๐ŸŠ +๐Ÿข +๐ŸฆŽ +๐Ÿ +๐Ÿฒ +๐Ÿ‰ +๐Ÿฆ• +๐Ÿฆ– +๐Ÿณ +๐Ÿ‹ +๐Ÿฌ +๐Ÿฌ +๐Ÿฆญ +๐ŸŸ +๐Ÿ  +๐Ÿก +๐Ÿฆˆ +๐Ÿ™ +๐Ÿš +๐ŸŒ +๐Ÿฆ‹ +๐Ÿ› +๐Ÿœ +๐Ÿ +๐Ÿ +๐Ÿชฒ +๐Ÿž +๐Ÿฆ— +๐Ÿชณ +๐Ÿ•ท๏ธ +๐Ÿ•ธ๏ธ +๐Ÿฆ‚ +๐ŸฆŸ +๐Ÿชฐ +๐Ÿชฑ +๐Ÿฆ  +๐Ÿ’ +๐ŸŒธ +๐Ÿ’ฎ +๐Ÿต๏ธ +๐ŸŒน +๐Ÿฅ€ +๐ŸŒบ +๐ŸŒป +๐ŸŒผ +๐ŸŒท +๐ŸŒฑ +๐Ÿชด +๐ŸŒฒ +๐ŸŒณ +๐ŸŒด +๐ŸŒต +๐ŸŒพ +๐ŸŒฟ +โ˜˜๏ธ +๐Ÿ€ +๐Ÿ +๐Ÿ‚ +๐Ÿƒ +๐Ÿ‡ +๐Ÿˆ +๐Ÿ‰ +๐ŸŠ +๐ŸŠ +๐ŸŠ +๐Ÿ‹ +๐ŸŒ +๐ŸŒ +๐Ÿ +๐Ÿฅญ +๐ŸŽ +๐Ÿ +๐Ÿ +๐Ÿ‘ +๐Ÿ’ +๐Ÿ“ +๐Ÿซ +๐Ÿฅ +๐Ÿ… +๐Ÿซ’ +๐Ÿฅฅ +๐Ÿฅ‘ +๐Ÿ† +๐Ÿฅ” +๐Ÿฅ• +๐ŸŒฝ +๐ŸŒถ๏ธ +๐Ÿซ‘ +๐Ÿฅ’ +๐Ÿฅฌ +๐Ÿฅฆ +๐Ÿง„ +๐Ÿง… +๐Ÿ„ +๐Ÿฅœ +๐ŸŒฐ +๐Ÿž +๐Ÿฅ +๐Ÿฅ– +๐Ÿซ“ +๐Ÿฅจ +๐Ÿฅฏ +๐Ÿฅž +๐Ÿง‡ +๐Ÿง€ +๐Ÿ– +๐Ÿ— +๐Ÿฅฉ +๐Ÿฅ“ +๐Ÿ” +๐ŸŸ +๐Ÿ• +๐ŸŒญ +๐Ÿฅช +๐ŸŒฎ +๐ŸŒฏ +๐Ÿซ” +๐Ÿฅ™ +๐Ÿง† +๐Ÿฅš +๐Ÿณ +๐Ÿฅ˜ +๐Ÿฒ +๐Ÿซ• +๐Ÿฅฃ +๐Ÿฅ— +๐Ÿฟ +๐Ÿงˆ +๐Ÿง‚ +๐Ÿฅซ +๐Ÿฑ +๐Ÿ˜ +๐Ÿ™ +๐Ÿš +๐Ÿ› +๐Ÿœ +๐Ÿ +๐Ÿ  +๐Ÿข +๐Ÿฃ +๐Ÿค +๐Ÿฅ +๐Ÿฅฎ +๐Ÿก +๐ŸฅŸ +๐Ÿฅ  +๐Ÿฅก +๐Ÿฆ€ +๐Ÿฆž +๐Ÿฆ +๐Ÿฆ‘ +๐Ÿฆช +๐Ÿฆ +๐Ÿง +๐Ÿจ +๐Ÿฉ +๐Ÿช +๐ŸŽ‚ +๐Ÿฐ +๐Ÿง +๐Ÿฅง +๐Ÿซ +๐Ÿฌ +๐Ÿญ +๐Ÿฎ +๐Ÿฏ +๐Ÿผ +๐Ÿฅ› +โ˜• +๐Ÿซ– +๐Ÿต +๐Ÿถ +๐Ÿพ +๐Ÿท +๐Ÿธ +๐Ÿน +๐Ÿบ +๐Ÿป +๐Ÿฅ‚ +๐Ÿฅƒ +๐Ÿฅค +๐Ÿง‹ +๐Ÿงƒ +๐Ÿง‰ +๐ŸงŠ +๐Ÿฅข +๐Ÿฝ๏ธ +๐Ÿด +๐Ÿฅ„ +๐Ÿ”ช +๐Ÿ”ช +๐Ÿบ +๐ŸŒ +๐ŸŒŽ +๐ŸŒ +๐ŸŒ +๐Ÿ—บ๏ธ +๐Ÿ—พ +๐Ÿงญ +๐Ÿ”๏ธ +โ›ฐ๏ธ +๐ŸŒ‹ +๐Ÿ—ป +๐Ÿ•๏ธ +๐Ÿ–๏ธ +๐Ÿœ๏ธ +๐Ÿ๏ธ +๐Ÿž๏ธ +๐ŸŸ๏ธ +๐Ÿ›๏ธ +๐Ÿ—๏ธ +๐Ÿงฑ +๐Ÿชจ +๐Ÿชต +๐Ÿ›– +๐Ÿ˜๏ธ +๐Ÿš๏ธ +๐Ÿ  +๐Ÿก +๐Ÿข +๐Ÿฃ +๐Ÿค +๐Ÿฅ +๐Ÿฆ +๐Ÿจ +๐Ÿฉ +๐Ÿช +๐Ÿซ +๐Ÿฌ +๐Ÿญ +๐Ÿฏ +๐Ÿฐ +๐Ÿ’’ +๐Ÿ—ผ +๐Ÿ—ฝ +โ›ช +๐Ÿ•Œ +๐Ÿ›• +๐Ÿ• +โ›ฉ๏ธ +๐Ÿ•‹ +โ›ฒ +โ›บ +๐ŸŒ +๐ŸŒƒ +๐Ÿ™๏ธ +๐ŸŒ„ +๐ŸŒ… +๐ŸŒ† +๐ŸŒ‡ +๐ŸŒ‰ +โ™จ๏ธ +๐ŸŽ  +๐ŸŽก +๐ŸŽข +๐Ÿ’ˆ +๐ŸŽช +๐Ÿš‚ +๐Ÿšƒ +๐Ÿš„ +๐Ÿš… +๐Ÿš† +๐Ÿš‡ +๐Ÿšˆ +๐Ÿš‰ +๐ŸšŠ +๐Ÿš +๐Ÿšž +๐Ÿš‹ +๐ŸšŒ +๐Ÿš +๐ŸšŽ +๐ŸšŽ +๐Ÿš +๐Ÿš‘ +๐Ÿš’ +๐Ÿš“ +๐Ÿš” +๐Ÿš• +๐Ÿš– +๐Ÿš— +๐Ÿš— +๐Ÿš˜ +๐Ÿš™ +๐Ÿ›ป +๐Ÿšš +๐Ÿš› +๐Ÿšœ +๐ŸŽ๏ธ +๐Ÿ๏ธ +๐Ÿ›ต +๐Ÿฆฝ +๐Ÿฆผ +๐Ÿ›บ +๐Ÿšฒ +๐Ÿ›ด +๐Ÿ›น +๐Ÿ›ผ +๐Ÿš +๐Ÿ›ฃ๏ธ +๐Ÿ›ค๏ธ +๐Ÿ›ข๏ธ +โ›ฝ +๐Ÿšจ +๐Ÿšฅ +๐Ÿšฆ +๐Ÿ›‘ +๐Ÿšง +โš“ +โ›ต +โ›ต +๐Ÿ›ถ +๐Ÿšค +๐Ÿ›ณ๏ธ +โ›ด๏ธ +๐Ÿ›ฅ๏ธ +๐Ÿšข +โœˆ๏ธ +๐Ÿ›ฉ๏ธ +๐Ÿ›ซ +๐Ÿ›ฌ +๐Ÿช‚ +๐Ÿ’บ +๐Ÿš +๐ŸšŸ +๐Ÿš  +๐Ÿšก +๐Ÿ›ฐ๏ธ +๐Ÿš€ +๐Ÿ›ธ +๐Ÿ›Ž๏ธ +๐Ÿงณ +โŒ› +โณ +โŒš +โฐ +โฑ๏ธ +โฒ๏ธ +๐Ÿ•ฐ๏ธ +๐Ÿ•› +๐Ÿ•ง +๐Ÿ• +๐Ÿ•œ +๐Ÿ•‘ +๐Ÿ• +๐Ÿ•’ +๐Ÿ•ž +๐Ÿ•“ +๐Ÿ•Ÿ +๐Ÿ•” +๐Ÿ•  +๐Ÿ•• +๐Ÿ•ก +๐Ÿ•– +๐Ÿ•ข +๐Ÿ•— +๐Ÿ•ฃ +๐Ÿ•˜ +๐Ÿ•ค +๐Ÿ•™ +๐Ÿ•ฅ +๐Ÿ•š +๐Ÿ•ฆ +๐ŸŒ‘ +๐ŸŒ’ +๐ŸŒ“ +๐ŸŒ” +๐ŸŒ” +๐ŸŒ• +๐ŸŒ– +๐ŸŒ— +๐ŸŒ˜ +๐ŸŒ™ +๐ŸŒš +๐ŸŒ› +๐ŸŒœ +๐ŸŒก๏ธ +โ˜€๏ธ +๐ŸŒ +๐ŸŒž +๐Ÿช +โญ +๐ŸŒŸ +๐ŸŒ  +๐ŸŒŒ +โ˜๏ธ +โ›… +โ›ˆ๏ธ +๐ŸŒค๏ธ +๐ŸŒฅ๏ธ +๐ŸŒฆ๏ธ +๐ŸŒง๏ธ +๐ŸŒจ๏ธ +๐ŸŒฉ๏ธ +๐ŸŒช๏ธ +๐ŸŒซ๏ธ +๐ŸŒฌ๏ธ +๐ŸŒ€ +๐ŸŒˆ +๐ŸŒ‚ +โ˜‚๏ธ +โ˜” +โ›ฑ๏ธ +โšก +โ„๏ธ +โ˜ƒ๏ธ +โ›„ +โ˜„๏ธ +๐Ÿ”ฅ +๐Ÿ’ง +๐ŸŒŠ +๐ŸŽƒ +๐ŸŽ„ +๐ŸŽ† +๐ŸŽ‡ +๐Ÿงจ +โœจ +๐ŸŽˆ +๐ŸŽ‰ +๐ŸŽŠ +๐ŸŽ‹ +๐ŸŽ +๐ŸŽŽ +๐ŸŽ +๐ŸŽ +๐ŸŽ‘ +๐Ÿงง +๐ŸŽ€ +๐ŸŽ +๐ŸŽ—๏ธ +๐ŸŽŸ๏ธ +๐ŸŽซ +๐ŸŽ–๏ธ +๐Ÿ† +๐Ÿ… +๐Ÿฅ‡ +๐Ÿฅˆ +๐Ÿฅ‰ +โšฝ +โšพ +๐ŸฅŽ +๐Ÿ€ +๐Ÿ +๐Ÿˆ +๐Ÿ‰ +๐ŸŽพ +๐Ÿฅ +๐ŸŽณ +๐Ÿ +๐Ÿ‘ +๐Ÿ’ +๐Ÿฅ +๐Ÿ“ +๐Ÿธ +๐ŸฅŠ +๐Ÿฅ‹ +๐Ÿฅ… +โ›ณ +โ›ธ๏ธ +๐ŸŽฃ +๐Ÿคฟ +๐ŸŽฝ +๐ŸŽฟ +๐Ÿ›ท +๐ŸฅŒ +๐ŸŽฏ +๐Ÿช€ +๐Ÿช +๐ŸŽฑ +๐Ÿ”ฎ +๐Ÿช„ +๐Ÿงฟ +๐ŸŽฎ +๐Ÿ•น๏ธ +๐ŸŽฐ +๐ŸŽฒ +๐Ÿงฉ +๐Ÿงธ +๐Ÿช… +๐Ÿช† +โ™ ๏ธ +โ™ฅ๏ธ +โ™ฆ๏ธ +โ™ฃ๏ธ +โ™Ÿ๏ธ +๐Ÿƒ +๐Ÿ€„ +๐ŸŽด +๐ŸŽญ +๐Ÿ–ผ๏ธ +๐ŸŽจ +๐Ÿงต +๐Ÿชก +๐Ÿงถ +๐Ÿชข +๐Ÿ‘“ +๐Ÿ•ถ๏ธ +๐Ÿฅฝ +๐Ÿฅผ +๐Ÿฆบ +๐Ÿ‘” +๐Ÿ‘• +๐Ÿ‘• +๐Ÿ‘– +๐Ÿงฃ +๐Ÿงค +๐Ÿงฅ +๐Ÿงฆ +๐Ÿ‘— +๐Ÿ‘˜ +๐Ÿฅป +๐Ÿฉฑ +๐Ÿฉฒ +๐Ÿฉณ +๐Ÿ‘™ +๐Ÿ‘š +๐Ÿ‘› +๐Ÿ‘œ +๐Ÿ‘ +๐Ÿ›๏ธ +๐ŸŽ’ +๐Ÿฉด +๐Ÿ‘ž +๐Ÿ‘ž +๐Ÿ‘Ÿ +๐Ÿฅพ +๐Ÿฅฟ +๐Ÿ‘  +๐Ÿ‘ก +๐Ÿฉฐ +๐Ÿ‘ข +๐Ÿ‘‘ +๐Ÿ‘’ +๐ŸŽฉ +๐ŸŽ“ +๐Ÿงข +๐Ÿช– +โ›‘๏ธ +๐Ÿ“ฟ +๐Ÿ’„ +๐Ÿ’ +๐Ÿ’Ž +๐Ÿ”‡ +๐Ÿ”ˆ +๐Ÿ”‰ +๐Ÿ”Š +๐Ÿ“ข +๐Ÿ“ฃ +๐Ÿ“ฏ +๐Ÿ”” +๐Ÿ”• +๐ŸŽผ +๐ŸŽต +๐ŸŽถ +๐ŸŽ™๏ธ +๐ŸŽš๏ธ +๐ŸŽ›๏ธ +๐ŸŽค +๐ŸŽง +๐Ÿ“ป +๐ŸŽท +๐Ÿช— +๐ŸŽธ +๐ŸŽน +๐ŸŽบ +๐ŸŽป +๐Ÿช• +๐Ÿฅ +๐Ÿช˜ +๐Ÿ“ฑ +๐Ÿ“ฒ +โ˜Ž๏ธ +โ˜Ž๏ธ +๐Ÿ“ž +๐Ÿ“Ÿ +๐Ÿ“  +๐Ÿ”‹ +๐Ÿ”Œ +๐Ÿ’ป +๐Ÿ–ฅ๏ธ +๐Ÿ–จ๏ธ +โŒจ๏ธ +๐Ÿ–ฑ๏ธ +๐Ÿ–ฒ๏ธ +๐Ÿ’ฝ +๐Ÿ’พ +๐Ÿ’ฟ +๐Ÿ“€ +๐Ÿงฎ +๐ŸŽฅ +๐ŸŽž๏ธ +๐Ÿ“ฝ๏ธ +๐ŸŽฌ +๐Ÿ“บ +๐Ÿ“ท +๐Ÿ“ธ +๐Ÿ“น +๐Ÿ“ผ +๐Ÿ” +๐Ÿ”Ž +๐Ÿ•ฏ๏ธ +๐Ÿ’ก +๐Ÿ”ฆ +๐Ÿฎ +๐Ÿฎ +๐Ÿช” +๐Ÿ“” +๐Ÿ“• +๐Ÿ“– +๐Ÿ“– +๐Ÿ“— +๐Ÿ“˜ +๐Ÿ“™ +๐Ÿ“š +๐Ÿ““ +๐Ÿ“’ +๐Ÿ“ƒ +๐Ÿ“œ +๐Ÿ“„ +๐Ÿ“ฐ +๐Ÿ—ž๏ธ +๐Ÿ“‘ +๐Ÿ”– +๐Ÿท๏ธ +๐Ÿ’ฐ +๐Ÿช™ +๐Ÿ’ด +๐Ÿ’ต +๐Ÿ’ถ +๐Ÿ’ท +๐Ÿ’ธ +๐Ÿ’ณ +๐Ÿงพ +๐Ÿ’น +โœ‰๏ธ +๐Ÿ“ง +๐Ÿ“ง +๐Ÿ“จ +๐Ÿ“ฉ +๐Ÿ“ค +๐Ÿ“ฅ +๐Ÿ“ฆ +๐Ÿ“ซ +๐Ÿ“ช +๐Ÿ“ฌ +๐Ÿ“ญ +๐Ÿ“ฎ +๐Ÿ—ณ๏ธ +โœ๏ธ +โœ’๏ธ +๐Ÿ–‹๏ธ +๐Ÿ–Š๏ธ +๐Ÿ–Œ๏ธ +๐Ÿ–๏ธ +๐Ÿ“ +๐Ÿ“ +๐Ÿ’ผ +๐Ÿ“ +๐Ÿ“‚ +๐Ÿ—‚๏ธ +๐Ÿ“… +๐Ÿ“† +๐Ÿ—’๏ธ +๐Ÿ—“๏ธ +๐Ÿ“‡ +๐Ÿ“ˆ +๐Ÿ“‰ +๐Ÿ“Š +๐Ÿ“‹ +๐Ÿ“Œ +๐Ÿ“ +๐Ÿ“Ž +๐Ÿ–‡๏ธ +๐Ÿ“ +๐Ÿ“ +โœ‚๏ธ +๐Ÿ—ƒ๏ธ +๐Ÿ—„๏ธ +๐Ÿ—‘๏ธ +๐Ÿ”’ +๐Ÿ”“ +๐Ÿ” +๐Ÿ” +๐Ÿ”‘ +๐Ÿ—๏ธ +๐Ÿ”จ +๐Ÿช“ +โ›๏ธ +โš’๏ธ +๐Ÿ› ๏ธ +๐Ÿ—ก๏ธ +โš”๏ธ +๐Ÿ”ซ +๐Ÿชƒ +๐Ÿน +๐Ÿ›ก๏ธ +๐Ÿชš +๐Ÿ”ง +๐Ÿช› +๐Ÿ”ฉ +โš™๏ธ +๐Ÿ—œ๏ธ +โš–๏ธ +๐Ÿฆฏ +๐Ÿ”— +โ›“๏ธ +๐Ÿช +๐Ÿงฐ +๐Ÿงฒ +๐Ÿชœ +โš—๏ธ +๐Ÿงช +๐Ÿงซ +๐Ÿงฌ +๐Ÿ”ฌ +๐Ÿ”ญ +๐Ÿ“ก +๐Ÿ’‰ +๐Ÿฉธ +๐Ÿ’Š +๐Ÿฉน +๐Ÿฉบ +๐Ÿšช +๐Ÿ›— +๐Ÿชž +๐ŸชŸ +๐Ÿ›๏ธ +๐Ÿ›‹๏ธ +๐Ÿช‘ +๐Ÿšฝ +๐Ÿช  +๐Ÿšฟ +๐Ÿ› +๐Ÿชค +๐Ÿช’ +๐Ÿงด +๐Ÿงท +๐Ÿงน +๐Ÿงบ +๐Ÿงป +๐Ÿชฃ +๐Ÿงผ +๐Ÿชฅ +๐Ÿงฝ +๐Ÿงฏ +๐Ÿ›’ +๐Ÿšฌ +โšฐ๏ธ +๐Ÿชฆ +โšฑ๏ธ +๐Ÿ—ฟ +๐Ÿชง +๐Ÿง +๐Ÿšฎ +๐Ÿšฐ +โ™ฟ +๐Ÿšน +๐Ÿšบ +๐Ÿšป +๐Ÿšผ +๐Ÿšพ +๐Ÿ›‚ +๐Ÿ›ƒ +๐Ÿ›„ +๐Ÿ›… +โš ๏ธ +๐Ÿšธ +โ›” +๐Ÿšซ +๐Ÿšณ +๐Ÿšญ +๐Ÿšฏ +๐Ÿšฑ +๐Ÿšท +๐Ÿ“ต +๐Ÿ”ž +โ˜ข๏ธ +โ˜ฃ๏ธ +โฌ†๏ธ +โ†—๏ธ +โžก๏ธ +โ†˜๏ธ +โฌ‡๏ธ +โ†™๏ธ +โฌ…๏ธ +โ†–๏ธ +โ†•๏ธ +โ†”๏ธ +โ†ฉ๏ธ +โ†ช๏ธ +โคด๏ธ +โคต๏ธ +๐Ÿ”ƒ +๐Ÿ”„ +๐Ÿ”™ +๐Ÿ”š +๐Ÿ”› +๐Ÿ”œ +๐Ÿ” +๐Ÿ› +โš›๏ธ +๐Ÿ•‰๏ธ +โœก๏ธ +โ˜ธ๏ธ +โ˜ฏ๏ธ +โœ๏ธ +โ˜ฆ๏ธ +โ˜ช๏ธ +โ˜ฎ๏ธ +๐Ÿ•Ž +๐Ÿ”ฏ +โ™ˆ +โ™‰ +โ™Š +โ™‹ +โ™Œ +โ™ +โ™Ž +โ™ +โ™ +โ™‘ +โ™’ +โ™“ +โ›Ž +๐Ÿ”€ +๐Ÿ” +๐Ÿ”‚ +โ–ถ๏ธ +โฉ +โญ๏ธ +โฏ๏ธ +โ—€๏ธ +โช +โฎ๏ธ +๐Ÿ”ผ +โซ +๐Ÿ”ฝ +โฌ +โธ๏ธ +โน๏ธ +โบ๏ธ +โ๏ธ +๐ŸŽฆ +๐Ÿ”… +๐Ÿ”† +๐Ÿ“ถ +๐Ÿ“ณ +๐Ÿ“ด +โ™€๏ธ +โ™‚๏ธ +โšง๏ธ +โœ–๏ธ +โž• +โž– +โž— +โ™พ๏ธ +โ€ผ๏ธ +โ‰๏ธ +โ“ +โ” +โ• +โ— +โ— +ใ€ฐ๏ธ +๐Ÿ’ฑ +๐Ÿ’ฒ +โš•๏ธ +โ™ป๏ธ +โšœ๏ธ +๐Ÿ”ฑ +๐Ÿ“› +๐Ÿ”ฐ +โญ• +โœ… +โ˜‘๏ธ +โœ”๏ธ +โŒ +โŽ +โžฐ +โžฟ +ใ€ฝ๏ธ +โœณ๏ธ +โœด๏ธ +โ‡๏ธ +ยฉ๏ธ +ยฎ๏ธ +โ„ข๏ธ +#๏ธโƒฃ +*๏ธโƒฃ +0๏ธโƒฃ +1๏ธโƒฃ +2๏ธโƒฃ +3๏ธโƒฃ +4๏ธโƒฃ +5๏ธโƒฃ +6๏ธโƒฃ +7๏ธโƒฃ +8๏ธโƒฃ +9๏ธโƒฃ +๐Ÿ”Ÿ +๐Ÿ”  +๐Ÿ”ก +๐Ÿ”ฃ +๐Ÿ”ค +๐Ÿ…ฐ๏ธ +๐Ÿ†Ž +๐Ÿ…ฑ๏ธ +๐Ÿ†‘ +๐Ÿ†’ +๐Ÿ†“ +โ„น๏ธ +๐Ÿ†” +โ“‚๏ธ +๐Ÿ†• +๐Ÿ†– +๐Ÿ…พ๏ธ +๐Ÿ†— +๐Ÿ…ฟ๏ธ +๐Ÿ†˜ +๐Ÿ†™ +๐Ÿ†š +๐Ÿˆ +๐Ÿˆ‚๏ธ +๐Ÿˆท๏ธ +๐Ÿˆถ +๐Ÿˆฏ +๐Ÿ‰ +๐Ÿˆน +๐Ÿˆš +๐Ÿˆฒ +๐Ÿ‰‘ +๐Ÿˆธ +๐Ÿˆด +๐Ÿˆณ +ใŠ—๏ธ +ใŠ™๏ธ +๐Ÿˆบ +๐Ÿˆต +๐Ÿ”ด +๐ŸŸ  +๐ŸŸก +๐ŸŸข +๐Ÿ”ต +๐ŸŸฃ +๐ŸŸค +โšซ +โšช +๐ŸŸฅ +๐ŸŸง +๐ŸŸจ +๐ŸŸฉ +๐ŸŸฆ +๐ŸŸช +๐ŸŸซ +โฌ› +โฌœ +โ—ผ๏ธ +โ—ป๏ธ +โ—พ +โ—ฝ +โ–ช๏ธ +โ–ซ๏ธ +๐Ÿ”ถ +๐Ÿ”ท +๐Ÿ”ธ +๐Ÿ”น +๐Ÿ”บ +๐Ÿ”ป +๐Ÿ’  +๐Ÿ”˜ +๐Ÿ”ณ +๐Ÿ”ฒ +๐Ÿ +๐Ÿšฉ +๐ŸŽŒ +๐Ÿด +๐Ÿณ๏ธ +๐Ÿณ๏ธโ€๐ŸŒˆ +๐Ÿณ๏ธโ€โšง๏ธ +๐Ÿดโ€โ˜ ๏ธ +๐Ÿ‡ฆ๐Ÿ‡จ +๐Ÿ‡ฆ๐Ÿ‡ฉ +๐Ÿ‡ฆ๐Ÿ‡ช +๐Ÿ‡ฆ๐Ÿ‡ซ +๐Ÿ‡ฆ๐Ÿ‡ฌ +๐Ÿ‡ฆ๐Ÿ‡ฎ +๐Ÿ‡ฆ๐Ÿ‡ฑ +๐Ÿ‡ฆ๐Ÿ‡ฒ +๐Ÿ‡ฆ๐Ÿ‡ด +๐Ÿ‡ฆ๐Ÿ‡ถ +๐Ÿ‡ฆ๐Ÿ‡ท +๐Ÿ‡ฆ๐Ÿ‡ธ +๐Ÿ‡ฆ๐Ÿ‡น +๐Ÿ‡ฆ๐Ÿ‡บ +๐Ÿ‡ฆ๐Ÿ‡ผ +๐Ÿ‡ฆ๐Ÿ‡ฝ +๐Ÿ‡ฆ๐Ÿ‡ฟ +๐Ÿ‡ง๐Ÿ‡ฆ +๐Ÿ‡ง๐Ÿ‡ง +๐Ÿ‡ง๐Ÿ‡ฉ +๐Ÿ‡ง๐Ÿ‡ช +๐Ÿ‡ง๐Ÿ‡ซ +๐Ÿ‡ง๐Ÿ‡ฌ +๐Ÿ‡ง๐Ÿ‡ญ +๐Ÿ‡ง๐Ÿ‡ฎ +๐Ÿ‡ง๐Ÿ‡ฏ +๐Ÿ‡ง๐Ÿ‡ฑ +๐Ÿ‡ง๐Ÿ‡ฒ +๐Ÿ‡ง๐Ÿ‡ณ +๐Ÿ‡ง๐Ÿ‡ด +๐Ÿ‡ง๐Ÿ‡ถ +๐Ÿ‡ง๐Ÿ‡ท +๐Ÿ‡ง๐Ÿ‡ธ +๐Ÿ‡ง๐Ÿ‡น +๐Ÿ‡ง๐Ÿ‡ป +๐Ÿ‡ง๐Ÿ‡ผ +๐Ÿ‡ง๐Ÿ‡พ +๐Ÿ‡ง๐Ÿ‡ฟ +๐Ÿ‡จ๐Ÿ‡ฆ +๐Ÿ‡จ๐Ÿ‡จ +๐Ÿ‡จ๐Ÿ‡ฉ +๐Ÿ‡จ๐Ÿ‡ซ +๐Ÿ‡จ๐Ÿ‡ฌ +๐Ÿ‡จ๐Ÿ‡ญ +๐Ÿ‡จ๐Ÿ‡ฎ +๐Ÿ‡จ๐Ÿ‡ฐ +๐Ÿ‡จ๐Ÿ‡ฑ +๐Ÿ‡จ๐Ÿ‡ฒ +๐Ÿ‡จ๐Ÿ‡ณ +๐Ÿ‡จ๐Ÿ‡ด +๐Ÿ‡จ๐Ÿ‡ต +๐Ÿ‡จ๐Ÿ‡ท +๐Ÿ‡จ๐Ÿ‡บ +๐Ÿ‡จ๐Ÿ‡ป +๐Ÿ‡จ๐Ÿ‡ผ +๐Ÿ‡จ๐Ÿ‡ฝ +๐Ÿ‡จ๐Ÿ‡พ +๐Ÿ‡จ๐Ÿ‡ฟ +๐Ÿ‡ฉ๐Ÿ‡ช +๐Ÿ‡ฉ๐Ÿ‡ฌ +๐Ÿ‡ฉ๐Ÿ‡ฏ +๐Ÿ‡ฉ๐Ÿ‡ฐ +๐Ÿ‡ฉ๐Ÿ‡ฒ +๐Ÿ‡ฉ๐Ÿ‡ด +๐Ÿ‡ฉ๐Ÿ‡ฟ +๐Ÿ‡ช๐Ÿ‡ฆ +๐Ÿ‡ช๐Ÿ‡จ +๐Ÿ‡ช๐Ÿ‡ช +๐Ÿ‡ช๐Ÿ‡ฌ +๐Ÿ‡ช๐Ÿ‡ญ +๐Ÿ‡ช๐Ÿ‡ท +๐Ÿ‡ช๐Ÿ‡ธ +๐Ÿ‡ช๐Ÿ‡น +๐Ÿ‡ช๐Ÿ‡บ +๐Ÿ‡ช๐Ÿ‡บ +๐Ÿ‡ซ๐Ÿ‡ฎ +๐Ÿ‡ซ๐Ÿ‡ฏ +๐Ÿ‡ซ๐Ÿ‡ฐ +๐Ÿ‡ซ๐Ÿ‡ฒ +๐Ÿ‡ซ๐Ÿ‡ด +๐Ÿ‡ซ๐Ÿ‡ท +๐Ÿ‡ฌ๐Ÿ‡ฆ +๐Ÿ‡ฌ๐Ÿ‡ง +๐Ÿ‡ฌ๐Ÿ‡ง +๐Ÿ‡ฌ๐Ÿ‡ฉ +๐Ÿ‡ฌ๐Ÿ‡ช +๐Ÿ‡ฌ๐Ÿ‡ซ +๐Ÿ‡ฌ๐Ÿ‡ฌ +๐Ÿ‡ฌ๐Ÿ‡ญ +๐Ÿ‡ฌ๐Ÿ‡ฎ +๐Ÿ‡ฌ๐Ÿ‡ฑ +๐Ÿ‡ฌ๐Ÿ‡ฒ +๐Ÿ‡ฌ๐Ÿ‡ณ +๐Ÿ‡ฌ๐Ÿ‡ต +๐Ÿ‡ฌ๐Ÿ‡ถ +๐Ÿ‡ฌ๐Ÿ‡ท +๐Ÿ‡ฌ๐Ÿ‡ธ +๐Ÿ‡ฌ๐Ÿ‡น +๐Ÿ‡ฌ๐Ÿ‡บ +๐Ÿ‡ฌ๐Ÿ‡ผ +๐Ÿ‡ฌ๐Ÿ‡พ +๐Ÿ‡ญ๐Ÿ‡ฐ +๐Ÿ‡ญ๐Ÿ‡ฒ +๐Ÿ‡ญ๐Ÿ‡ณ +๐Ÿ‡ญ๐Ÿ‡ท +๐Ÿ‡ญ๐Ÿ‡น +๐Ÿ‡ญ๐Ÿ‡บ +๐Ÿ‡ฎ๐Ÿ‡จ +๐Ÿ‡ฎ๐Ÿ‡ฉ +๐Ÿ‡ฎ๐Ÿ‡ช +๐Ÿ‡ฎ๐Ÿ‡ฑ +๐Ÿ‡ฎ๐Ÿ‡ฒ +๐Ÿ‡ฎ๐Ÿ‡ณ +๐Ÿ‡ฎ๐Ÿ‡ด +๐Ÿ‡ฎ๐Ÿ‡ถ +๐Ÿ‡ฎ๐Ÿ‡ท +๐Ÿ‡ฎ๐Ÿ‡ธ +๐Ÿ‡ฎ๐Ÿ‡น +๐Ÿ‡ฏ๐Ÿ‡ช +๐Ÿ‡ฏ๐Ÿ‡ฒ +๐Ÿ‡ฏ๐Ÿ‡ด +๐Ÿ‡ฏ๐Ÿ‡ต +๐Ÿ‡ฐ๐Ÿ‡ช +๐Ÿ‡ฐ๐Ÿ‡ฌ +๐Ÿ‡ฐ๐Ÿ‡ญ +๐Ÿ‡ฐ๐Ÿ‡ฎ +๐Ÿ‡ฐ๐Ÿ‡ฒ +๐Ÿ‡ฐ๐Ÿ‡ณ +๐Ÿ‡ฐ๐Ÿ‡ต +๐Ÿ‡ฐ๐Ÿ‡ท +๐Ÿ‡ฐ๐Ÿ‡ผ +๐Ÿ‡ฐ๐Ÿ‡พ +๐Ÿ‡ฐ๐Ÿ‡ฟ +๐Ÿ‡ฑ๐Ÿ‡ฆ +๐Ÿ‡ฑ๐Ÿ‡ง +๐Ÿ‡ฑ๐Ÿ‡จ +๐Ÿ‡ฑ๐Ÿ‡ฎ +๐Ÿ‡ฑ๐Ÿ‡ฐ +๐Ÿ‡ฑ๐Ÿ‡ท +๐Ÿ‡ฑ๐Ÿ‡ธ +๐Ÿ‡ฑ๐Ÿ‡น +๐Ÿ‡ฑ๐Ÿ‡บ +๐Ÿ‡ฑ๐Ÿ‡ป +๐Ÿ‡ฑ๐Ÿ‡พ +๐Ÿ‡ฒ๐Ÿ‡ฆ +๐Ÿ‡ฒ๐Ÿ‡จ +๐Ÿ‡ฒ๐Ÿ‡ฉ +๐Ÿ‡ฒ๐Ÿ‡ช +๐Ÿ‡ฒ๐Ÿ‡ซ +๐Ÿ‡ฒ๐Ÿ‡ฌ +๐Ÿ‡ฒ๐Ÿ‡ญ +๐Ÿ‡ฒ๐Ÿ‡ฐ +๐Ÿ‡ฒ๐Ÿ‡ฑ +๐Ÿ‡ฒ๐Ÿ‡ฒ +๐Ÿ‡ฒ๐Ÿ‡ณ +๐Ÿ‡ฒ๐Ÿ‡ด +๐Ÿ‡ฒ๐Ÿ‡ต +๐Ÿ‡ฒ๐Ÿ‡ถ +๐Ÿ‡ฒ๐Ÿ‡ท +๐Ÿ‡ฒ๐Ÿ‡ธ +๐Ÿ‡ฒ๐Ÿ‡น +๐Ÿ‡ฒ๐Ÿ‡บ +๐Ÿ‡ฒ๐Ÿ‡ป +๐Ÿ‡ฒ๐Ÿ‡ผ +๐Ÿ‡ฒ๐Ÿ‡ฝ +๐Ÿ‡ฒ๐Ÿ‡พ +๐Ÿ‡ฒ๐Ÿ‡ฟ +๐Ÿ‡ณ๐Ÿ‡ฆ +๐Ÿ‡ณ๐Ÿ‡จ +๐Ÿ‡ณ๐Ÿ‡ช +๐Ÿ‡ณ๐Ÿ‡ซ +๐Ÿ‡ณ๐Ÿ‡ฌ +๐Ÿ‡ณ๐Ÿ‡ฎ +๐Ÿ‡ณ๐Ÿ‡ฑ +๐Ÿ‡ณ๐Ÿ‡ด +๐Ÿ‡ณ๐Ÿ‡ต +๐Ÿ‡ณ๐Ÿ‡ท +๐Ÿ‡ณ๐Ÿ‡บ +๐Ÿ‡ณ๐Ÿ‡ฟ +๐Ÿ‡ด๐Ÿ‡ฒ +๐Ÿ‡ต๐Ÿ‡ฆ +๐Ÿ‡ต๐Ÿ‡ช +๐Ÿ‡ต๐Ÿ‡ซ +๐Ÿ‡ต๐Ÿ‡ฌ +๐Ÿ‡ต๐Ÿ‡ญ +๐Ÿ‡ต๐Ÿ‡ฐ +๐Ÿ‡ต๐Ÿ‡ฑ +๐Ÿ‡ต๐Ÿ‡ฒ +๐Ÿ‡ต๐Ÿ‡ณ +๐Ÿ‡ต๐Ÿ‡ท +๐Ÿ‡ต๐Ÿ‡ธ +๐Ÿ‡ต๐Ÿ‡น +๐Ÿ‡ต๐Ÿ‡ผ +๐Ÿ‡ต๐Ÿ‡พ +๐Ÿ‡ถ๐Ÿ‡ฆ +๐Ÿ‡ท๐Ÿ‡ช +๐Ÿ‡ท๐Ÿ‡ด +๐Ÿ‡ท๐Ÿ‡ธ +๐Ÿ‡ท๐Ÿ‡บ +๐Ÿ‡ท๐Ÿ‡ผ +๐Ÿ‡ธ๐Ÿ‡ฆ +๐Ÿ‡ธ๐Ÿ‡ง +๐Ÿ‡ธ๐Ÿ‡จ +๐Ÿ‡ธ๐Ÿ‡ฉ +๐Ÿ‡ธ๐Ÿ‡ช +๐Ÿ‡ธ๐Ÿ‡ฌ +๐Ÿ‡ธ๐Ÿ‡ญ +๐Ÿ‡ธ๐Ÿ‡ฎ +๐Ÿ‡ธ๐Ÿ‡ฏ +๐Ÿ‡ธ๐Ÿ‡ฐ +๐Ÿ‡ธ๐Ÿ‡ฑ +๐Ÿ‡ธ๐Ÿ‡ฒ +๐Ÿ‡ธ๐Ÿ‡ณ +๐Ÿ‡ธ๐Ÿ‡ด +๐Ÿ‡ธ๐Ÿ‡ท +๐Ÿ‡ธ๐Ÿ‡ธ +๐Ÿ‡ธ๐Ÿ‡น +๐Ÿ‡ธ๐Ÿ‡ป +๐Ÿ‡ธ๐Ÿ‡ฝ +๐Ÿ‡ธ๐Ÿ‡พ +๐Ÿ‡ธ๐Ÿ‡ฟ +๐Ÿ‡น๐Ÿ‡ฆ +๐Ÿ‡น๐Ÿ‡จ +๐Ÿ‡น๐Ÿ‡ฉ +๐Ÿ‡น๐Ÿ‡ซ +๐Ÿ‡น๐Ÿ‡ฌ +๐Ÿ‡น๐Ÿ‡ญ +๐Ÿ‡น๐Ÿ‡ฏ +๐Ÿ‡น๐Ÿ‡ฐ +๐Ÿ‡น๐Ÿ‡ฑ +๐Ÿ‡น๐Ÿ‡ฒ +๐Ÿ‡น๐Ÿ‡ณ +๐Ÿ‡น๐Ÿ‡ด +๐Ÿ‡น๐Ÿ‡ท +๐Ÿ‡น๐Ÿ‡น +๐Ÿ‡น๐Ÿ‡ป +๐Ÿ‡น๐Ÿ‡ผ +๐Ÿ‡น๐Ÿ‡ฟ +๐Ÿ‡บ๐Ÿ‡ฆ +๐Ÿ‡บ๐Ÿ‡ฌ +๐Ÿ‡บ๐Ÿ‡ฒ +๐Ÿ‡บ๐Ÿ‡ณ +๐Ÿ‡บ๐Ÿ‡ธ +๐Ÿ‡บ๐Ÿ‡พ +๐Ÿ‡บ๐Ÿ‡ฟ +๐Ÿ‡ป๐Ÿ‡ฆ +๐Ÿ‡ป๐Ÿ‡จ +๐Ÿ‡ป๐Ÿ‡ช +๐Ÿ‡ป๐Ÿ‡ฌ +๐Ÿ‡ป๐Ÿ‡ฎ +๐Ÿ‡ป๐Ÿ‡ณ +๐Ÿ‡ป๐Ÿ‡บ +๐Ÿ‡ผ๐Ÿ‡ซ +๐Ÿ‡ผ๐Ÿ‡ธ +๐Ÿ‡ฝ๐Ÿ‡ฐ +๐Ÿ‡พ๐Ÿ‡ช +๐Ÿ‡พ๐Ÿ‡น +๐Ÿ‡ฟ๐Ÿ‡ฆ +๐Ÿ‡ฟ๐Ÿ‡ฒ +๐Ÿ‡ฟ๐Ÿ‡ผ +๐Ÿด๓ ง๓ ข๓ ฅ๓ ฎ๓ ง๓ ฟ +๐Ÿด๓ ง๓ ข๓ ณ๓ ฃ๓ ด๓ ฟ +๐Ÿด๓ ง๓ ข๓ ท๓ ฌ๓ ณ๓ ฟ \ 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 8f39f4c9..463bb2e1 100644 --- a/crates/core/database/src/models/mod.rs +++ b/crates/core/database/src/models/mod.rs @@ -4,6 +4,7 @@ mod channel_invites; mod channel_unreads; mod channel_webhooks; mod channels; +mod emojis; mod files; mod ratelimit_events; mod server_members; @@ -17,6 +18,7 @@ pub use channel_invites::*; pub use channel_unreads::*; pub use channel_webhooks::*; pub use channels::*; +pub use emojis::*; pub use files::*; pub use ratelimit_events::*; pub use server_members::*; @@ -35,6 +37,7 @@ pub trait AbstractDatabase: + channel_invites::AbstractChannelInvites + channel_unreads::AbstractChannelUnreads + channel_webhooks::AbstractWebhooks + + emojis::AbstractEmojis + files::AbstractAttachments + ratelimit_events::AbstractRatelimitEvents + server_members::AbstractServerMembers diff --git a/crates/core/database/src/util/bridge/v0.rs b/crates/core/database/src/util/bridge/v0.rs index 3c159447..bc7e052f 100644 --- a/crates/core/database/src/util/bridge/v0.rs +++ b/crates/core/database/src/util/bridge/v0.rs @@ -235,6 +235,28 @@ impl From for FieldsChannel { } } +impl From for Emoji { + fn from(value: crate::Emoji) -> Self { + Emoji { + id: value.id, + parent: value.parent.into(), + creator_id: value.creator_id, + name: value.name, + animated: value.animated, + nsfw: value.nsfw, + } + } +} + +impl From for EmojiParent { + fn from(value: crate::EmojiParent) -> Self { + match value { + crate::EmojiParent::Detached => EmojiParent::Detached, + crate::EmojiParent::Server { id } => EmojiParent::Server { id }, + } + } +} + impl From for File { fn from(value: crate::File) -> Self { File { diff --git a/crates/core/models/src/v0/emojis.rs b/crates/core/models/src/v0/emojis.rs new file mode 100644 index 00000000..cf610bde --- /dev/null +++ b/crates/core/models/src/v0/emojis.rs @@ -0,0 +1,33 @@ +auto_derived!( + /// Emoji + pub struct Emoji { + /// Unique Id + #[cfg_attr(feature = "serde", serde(rename = "_id"))] + pub id: String, + /// What owns this emoji + pub parent: EmojiParent, + /// Uploader user id + pub creator_id: String, + /// Emoji name + pub name: String, + /// Whether the emoji is animated + #[cfg_attr( + feature = "serde", + serde(skip_serializing_if = "crate::if_false", default) + )] + pub animated: bool, + /// Whether the emoji is marked as nsfw + #[cfg_attr( + feature = "serde", + serde(skip_serializing_if = "crate::if_false", default) + )] + pub nsfw: bool, + } + + /// Parent Id of the emoji + #[serde(tag = "type")] + pub enum EmojiParent { + Server { id: String }, + Detached, + } +); diff --git a/crates/core/models/src/v0/mod.rs b/crates/core/models/src/v0/mod.rs index 1a945a43..917d2d0f 100644 --- a/crates/core/models/src/v0/mod.rs +++ b/crates/core/models/src/v0/mod.rs @@ -3,9 +3,11 @@ mod channel_invites; mod channel_unreads; mod channel_webhooks; mod channels; +mod emojis; mod files; mod server_members; mod servers; +mod user_settings; mod users; pub use bots::*; @@ -13,7 +15,9 @@ pub use channel_invites::*; pub use channel_unreads::*; pub use channel_webhooks::*; pub use channels::*; +pub use emojis::*; pub use files::*; pub use server_members::*; pub use servers::*; +pub use user_settings::*; pub use users::*; diff --git a/crates/core/models/src/v0/user_settings.rs b/crates/core/models/src/v0/user_settings.rs new file mode 100644 index 00000000..72e86c49 --- /dev/null +++ b/crates/core/models/src/v0/user_settings.rs @@ -0,0 +1,6 @@ +use std::collections::HashMap; + +/// HashMap of user settings +/// Each key is mapped to a tuple consisting of the +/// revision timestamp and serialised data (in JSON format) +pub type UserSettings = HashMap;