Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
No results found
Show changes
Commits on Source (248)
Showing
with 2547 additions and 369 deletions
...@@ -3,3 +3,4 @@ node_modules ...@@ -3,3 +3,4 @@ node_modules
dist dist
dist-ssr dist-ssr
*.local *.local
*.log
image: node:14-buster
variables:
GIT_SUBMODULE_STRATEGY: recursive
cache:
paths:
- node_modules
# Fetch dependencies and setup project for compilation.
install:
stage: prepare
script:
- yarn
# Type check the project
typecheck:
stage: test
needs:
- install
dependencies:
- install
script:
- yarn typecheck
# Lint the project and check prettier output.
lint:
stage: test
allow_failure: true
needs:
- install
dependencies:
- install
script:
- yarn lint
- yarn --check 'src/**/*.{js,jsx,ts,tsx}'
stages:
- prepare
- test
tabWidth: 4
\ No newline at end of file
module.exports = {
tabWidth: 4,
trailingComma: "all",
jsxBracketSameLine: true,
importOrder: [
"preact|classnames|.scss$",
"/(lib)",
"/(redux|mobx)",
"/(context)",
"/(ui|common)|.svg$",
"^[./]",
],
importOrderSeparation: true,
};
{
"recommendations": ["esbenp.prettier-vscode", "dbaeumer.vscode-eslint"]
}
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
}
\ No newline at end of file
...@@ -630,7 +630,7 @@ state the exclusion of warranty; and each file should have at least ...@@ -630,7 +630,7 @@ state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found. the "copyright" line and a pointer to where the full notice is found.
Revite Revite
Copyright (C) 2021 REVOLT Copyright (C) 2021 Revolt Communications
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published it under the terms of the GNU Affero General Public License as published
......
Subproject commit 2a9ef2c8025dd71a20fddca7c94cb7af30978c4b Subproject commit 09955e9d30c19c1a180fd3aacdb85961641da2bc
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<title>REVOLT</title> <title>Revolt</title>
<meta name="apple-mobile-web-app-title" content="Revolt"> <meta name="apple-mobile-web-app-title" content="Revolt" />
<!--<link rel="icon" type="image/svg+xml" href="/src/favicon.svg" />--> <meta
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" /> name="viewport"
<meta name="apple-mobile-web-app-capable" content="yes"> content="width=device-width, initial-scale=1.0, user-scalable=no"
/>
<meta name="apple-mobile-web-app-capable" content="yes" />
<!--App Icons--> <!--App Icons-->
<link rel="apple-touch-icon" href="public/assets/icons/apple-touch.png"> <link
<link rel="icon" type="image/png" href="/src/assets/logo_round.png" /> rel="apple-touch-icon"
href="public/assets/icons/apple-touch.png"
/>
<link rel="icon" type="image/png" href="/src/assets/logo_round.png" />
<!--Splash Screens for iOS Devices--> <!--Splash Screens for iOS Devices-->
<link href="public/assets/splashscreens/iphone5_splash.png" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image" /> <link
<link href="public/assets/splashscreens/iphone6_splash.png" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image" /> href="public/assets/splashscreens/iphone5_splash.png"
<link href="public/assets/splashscreens/iphoneplus_splash.png" media="(device-width: 621px) and (device-height: 1104px) and (-webkit-device-pixel-ratio: 3)" rel="apple-touch-startup-image" /> media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2)"
<link href="public/assets/splashscreens/iphonex_splash.png" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3)" rel="apple-touch-startup-image" /> rel="apple-touch-startup-image"
<link href="public/assets/splashscreens/iphonexr_splash.png" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image" /> />
<link href="public/assets/splashscreens/iphonexsmax_splash.png" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3)" rel="apple-touch-startup-image" /> <link
<link href="public/assets/splashscreens/ipad_splash.png" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image" /> href="public/assets/splashscreens/iphone6_splash.png"
<link href="public/assets/splashscreens/ipadpro1_splash.png" media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image" /> media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2)"
<link href="public/assets/splashscreens/ipadpro3_splash.png" media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image" /> rel="apple-touch-startup-image"
<link href="public/assets/splashscreens/ipadpro2_splash.png" media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image" /> />
</head> <link
<body> href="public/assets/splashscreens/iphoneplus_splash.png"
<div id="app"></div> media="(device-width: 621px) and (device-height: 1104px) and (-webkit-device-pixel-ratio: 3)"
<script type="module" src="/src/main.tsx"></script> rel="apple-touch-startup-image"
</body> />
<style> <link
html { href="public/assets/splashscreens/iphonex_splash.png"
background-color: #191919; media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3)"
} rel="apple-touch-startup-image"
</style> />
</html> <link
\ No newline at end of file href="public/assets/splashscreens/iphonexr_splash.png"
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2)"
rel="apple-touch-startup-image"
/>
<link
href="public/assets/splashscreens/iphonexsmax_splash.png"
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3)"
rel="apple-touch-startup-image"
/>
<link
href="public/assets/splashscreens/ipad_splash.png"
media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2)"
rel="apple-touch-startup-image"
/>
<link
href="public/assets/splashscreens/ipadpro1_splash.png"
media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2)"
rel="apple-touch-startup-image"
/>
<link
href="public/assets/splashscreens/ipadpro3_splash.png"
media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2)"
rel="apple-touch-startup-image"
/>
<link
href="public/assets/splashscreens/ipadpro2_splash.png"
media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2)"
rel="apple-touch-startup-image"
/>
</head>
<body ontouchstart="">
<div id="app"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
<style>
html {
background-color: #191919;
}
</style>
</html>
{ {
"version": "0.0.0", "version": "0.0.0",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "rimraf build && vite build", "build": "rimraf build && vite build",
"preview": "vite preview", "preview": "vite preview",
"lint": "eslint 'src/**/*.{js,jsx,ts,tsx}'", "lint": "eslint 'src/**/*.{js,jsx,ts,tsx}'",
"fmt": "prettier --write 'src/**/*.{js,jsx,ts,tsx}'", "fmt": "prettier --write 'src/**/*.{js,jsx,ts,tsx}'",
"typecheck": "tsc --noEmit" "typecheck": "tsc --noEmit"
}, },
"eslintConfig": { "eslintConfig": {
"parser": "@typescript-eslint/parser", "parser": "@typescript-eslint/parser",
"extends": [ "extends": [
"preact", "preact",
"plugin:@typescript-eslint/recommended" "plugin:@typescript-eslint/recommended"
], ],
"ignorePatterns": [ "ignorePatterns": [
"build/" "build/"
], ],
"rules": { "rules": {
"@typescript-eslint/explicit-module-boundary-types": "off" "radix": "off",
} "no-spaced-func": "off",
}, "react/no-danger": "off",
"dependencies": { "@typescript-eslint/explicit-module-boundary-types": "off",
"preact": "^10.5.13" "@typescript-eslint/no-non-null-assertion": "off",
}, "@typescript-eslint/no-unused-vars": [
"devDependencies": { "warn",
"@fontsource/atkinson-hyperlegible": "^4.4.5", {
"@fontsource/bree-serif": "^4.4.5", "varsIgnorePattern": "^_"
"@fontsource/comic-neue": "^4.4.5", }
"@fontsource/fira-code": "^4.4.5", ],
"@fontsource/inter": "^4.4.5", "no-unused-vars": [
"@fontsource/lato": "^4.4.5", "warn",
"@fontsource/montserrat": "^4.4.5", {
"@fontsource/noto-sans": "^4.4.5", "varsIgnorePattern": "^_"
"@fontsource/open-sans": "^4.4.5", }
"@fontsource/poppins": "^4.4.5", ]
"@fontsource/raleway": "^4.4.5", }
"@fontsource/roboto": "^4.4.5", },
"@fontsource/roboto-mono": "^4.4.5", "dependencies": {
"@fontsource/source-code-pro": "^4.4.5", "vite": "npm:@insertish/vite@2.4.0-beta.3-dynamic-import-css-3c1466b"
"@fontsource/space-mono": "^4.4.5", },
"@fontsource/ubuntu": "^4.4.5", "devDependencies": {
"@fontsource/ubuntu-mono": "^4.4.5", "@fontsource/atkinson-hyperlegible": "^4.4.5",
"@hcaptcha/react-hcaptcha": "^0.3.6", "@fontsource/bree-serif": "^4.4.5",
"@preact/preset-vite": "^2.0.0", "@fontsource/comic-neue": "^4.4.5",
"@rollup/plugin-replace": "^2.4.2", "@fontsource/fira-code": "^4.4.5",
"@styled-icons/boxicons-logos": "^10.34.0", "@fontsource/inter": "^4.4.5",
"@styled-icons/boxicons-regular": "^10.34.0", "@fontsource/lato": "^4.4.5",
"@styled-icons/boxicons-solid": "^10.34.0", "@fontsource/montserrat": "^4.4.5",
"@styled-icons/simple-icons": "^10.33.0", "@fontsource/noto-sans": "^4.4.5",
"@tippyjs/react": "^4.2.5", "@fontsource/open-sans": "^4.4.5",
"@traptitech/markdown-it-katex": "^3.4.3", "@fontsource/poppins": "^4.4.5",
"@traptitech/markdown-it-spoiler": "^1.1.6", "@fontsource/raleway": "^4.4.5",
"@types/lodash.defaultsdeep": "^4.6.6", "@fontsource/roboto": "^4.4.5",
"@types/lodash.isequal": "^4.5.5", "@fontsource/roboto-mono": "^4.4.5",
"@types/markdown-it": "^12.0.2", "@fontsource/source-code-pro": "^4.4.5",
"@types/node": "^15.12.4", "@fontsource/space-mono": "^4.4.5",
"@types/preact-i18n": "^2.3.0", "@fontsource/ubuntu": "^4.4.5",
"@types/prismjs": "^1.16.5", "@fontsource/ubuntu-mono": "^4.4.5",
"@types/react-helmet": "^6.1.1", "@hcaptcha/react-hcaptcha": "^0.3.6",
"@types/react-router-dom": "^5.1.7", "@preact/preset-vite": "^2.0.0",
"@types/react-scroll": "^1.8.2", "@rollup/plugin-replace": "^2.4.2",
"@types/styled-components": "^5.1.10", "@styled-icons/boxicons-logos": "^10.34.0",
"@types/twemoji": "^12.1.1", "@styled-icons/boxicons-regular": "^10.34.0",
"@typescript-eslint/eslint-plugin": "^4.27.0", "@styled-icons/boxicons-solid": "^10.37.0",
"@typescript-eslint/parser": "^4.27.0", "@styled-icons/simple-icons": "^10.33.0",
"classnames": "^2.3.1", "@tippyjs/react": "^4.2.5",
"dayjs": "^1.10.5", "@traptitech/markdown-it-katex": "^3.4.3",
"detect-browser": "^5.2.0", "@traptitech/markdown-it-spoiler": "^1.1.6",
"eslint": "^7.28.0", "@trivago/prettier-plugin-sort-imports": "^2.0.2",
"eslint-config-preact": "^1.1.4", "@types/lodash.defaultsdeep": "^4.6.6",
"eventemitter3": "^4.0.7", "@types/lodash.isequal": "^4.5.5",
"highlight.js": "^11.0.1", "@types/markdown-it": "^12.0.2",
"idb": "^6.1.2", "@types/node": "^15.12.4",
"localforage": "^1.9.0", "@types/preact-i18n": "^2.3.0",
"lodash.defaultsdeep": "^4.6.1", "@types/prismjs": "^1.16.5",
"lodash.isequal": "^4.5.0", "@types/react-helmet": "^6.1.1",
"markdown-it": "^12.0.6", "@types/react-router-dom": "^5.1.7",
"markdown-it-emoji": "^2.0.0", "@types/react-scroll": "^1.8.2",
"markdown-it-sub": "^1.0.0", "@types/styled-components": "^5.1.10",
"markdown-it-sup": "^1.0.0", "@types/twemoji": "^12.1.1",
"mediasoup-client": "^3.6.33", "@typescript-eslint/eslint-plugin": "^4.27.0",
"preact-context-menu": "^0.1.5", "@typescript-eslint/parser": "^4.27.0",
"preact-i18n": "^2.4.0-preactx", "classnames": "^2.3.1",
"prettier": "^2.3.1", "dayjs": "^1.10.6",
"prismjs": "^1.23.0", "detect-browser": "^5.2.0",
"react-device-detect": "^1.17.0", "eslint": "^7.28.0",
"react-helmet": "^6.1.0", "eslint-config-preact": "^1.1.4",
"react-hook-form": "6.3.0", "eventemitter3": "^4.0.7",
"react-overlapping-panels": "1.2.1", "highlight.js": "^11.0.1",
"react-redux": "^7.2.4", "localforage": "^1.9.0",
"react-router-dom": "^5.2.0", "lodash.defaultsdeep": "^4.6.1",
"react-scroll": "^1.8.2", "lodash.isequal": "^4.5.0",
"redux": "^4.1.0", "markdown-it": "^12.0.6",
"revolt.js": "4.3.3-alpha.7", "markdown-it-emoji": "^2.0.0",
"rimraf": "^3.0.2", "markdown-it-sub": "^1.0.0",
"sass": "^1.35.1", "markdown-it-sup": "^1.0.0",
"shade-blend-color": "^1.0.0", "mediasoup-client": "npm:@insertish/mediasoup-client@3.6.36-esnext",
"styled-components": "^5.3.0", "mobx": "^6.3.2",
"typescript": "^4.3.2", "mobx-react-lite": "^3.2.0",
"ulid": "^2.3.0", "preact": "^10.5.14",
"use-resize-observer": "^7.0.0", "preact-context-menu": "^0.1.5",
"vite": "npm:@insertish/vite@2.2.4-dynamic-import-css-f428476", "preact-i18n": "^2.4.0-preactx",
"vite-plugin-pwa": "^0.8.1", "prettier": "^2.3.1",
"workbox-precaching": "^6.1.5" "prismjs": "^1.23.0",
} "react-device-detect": "^1.17.0",
"react-helmet": "^6.1.0",
"react-hook-form": "6.3.0",
"react-overlapping-panels": "1.2.2",
"react-redux": "^7.2.4",
"react-router-dom": "^5.2.0",
"react-scroll": "^1.8.2",
"redux": "^4.1.0",
"revolt-api": "0.5.1-alpha.10-patch.0",
"revolt.js": "5.0.0-alpha.18",
"rimraf": "^3.0.2",
"sass": "^1.35.1",
"shade-blend-color": "^1.0.0",
"styled-components": "^5.3.0",
"typescript": "^4.3.2",
"ulid": "^2.3.0",
"use-resize-observer": "^7.0.0",
"vite-plugin-pwa": "^0.8.1",
"workbox-precaching": "^6.1.5"
},
"name": "client",
"main": "index.js",
"repository": "https://gitlab.insrt.uk/revolt/revite.git",
"author": "Paul <paulmakles@gmail.com>",
"license": "MIT"
} }
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "chat.revolt.app.twa",
"sha256_cert_fingerprints": [
"6E:62:C1:BF:5A:2D:11:31:A3:22:91:8D:22:2B:2C:49:D3:70:F3:A1:45:DF:11:6A:97:DC:4C:A9:3B:C3:AA:FB"
]
}
}]
\ No newline at end of file
public/assets/icons/masking-512x512.png

4.66 KiB

<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M30.9299 18.0767C30.9299 20.7484 29.4776 22.3521 26.3783 22.3521H21.2468V13.8981H26.3792C29.4776 13.8981 30.9299 15.5498 30.9299 18.0767ZM8 7L12.9681 13.9144V41.1006H21.2477V28.2293H23.2331L30.3031 41.1035H39.648L31.8041 27.5976C33.9941 27.0629 35.9365 25.7938 37.3097 24.0006C38.683 22.2073 39.4048 19.9973 39.3556 17.7364C39.3556 11.8093 35.192 7 26.8636 7H8Z" fill="white"/>
</svg>
export const emojiDictionary={"100":"💯","1234":"🔢","grinning":"😀","smiley":"😃","smile":"😄","grin":"😁","laughing":"😆","satisfied":"😆","sweat_smile":"😅","rofl":"🤣","joy":"😂","slightly_smiling_face":"🙂","upside_down_face":"🙃","wink":"😉","blush":"😊","innocent":"😇","smiling_face_with_three_hearts":"🥰","heart_eyes":"😍","star_struck":"🤩","kissing_heart":"😘","kissing":"😗","relaxed":"☺️","kissing_closed_eyes":"😚","kissing_smiling_eyes":"😙","smiling_face_with_tear":"🥲","yum":"😋","stuck_out_tongue":"😛","stuck_out_tongue_winking_eye":"😜","zany_face":"🤪","stuck_out_tongue_closed_eyes":"😝","money_mouth_face":"🤑","hugs":"🤗","hand_over_mouth":"🤭","shushing_face":"🤫","thinking":"🤔","zipper_mouth_face":"🤐","raised_eyebrow":"🤨","neutral_face":"😐","expressionless":"😑","no_mouth":"😶","smirk":"😏","unamused":"😒","roll_eyes":"🙄","grimacing":"😬","lying_face":"🤥","relieved":"😌","pensive":"😔","sleepy":"😪","drooling_face":"🤤","sleeping":"😴","mask":"😷","face_with_thermometer":"🤒","face_with_head_bandage":"🤕","nauseated_face":"🤢","vomiting_face":"🤮","sneezing_face":"🤧","hot_face":"🥵","cold_face":"🥶","woozy_face":"🥴","dizzy_face":"😵","exploding_head":"🤯","cowboy_hat_face":"🤠","partying_face":"🥳","disguised_face":"🥸","sunglasses":"😎","nerd_face":"🤓","monocle_face":"🧐","confused":"😕","worried":"😟","slightly_frowning_face":"🙁","frowning_face":"☹️","open_mouth":"😮","hushed":"😯","astonished":"😲","flushed":"😳","pleading_face":"🥺","frowning":"😦","anguished":"😧","fearful":"😨","cold_sweat":"😰","disappointed_relieved":"😥","cry":"😢","sob":"😭","scream":"😱","confounded":"😖","persevere":"😣","disappointed":"😞","sweat":"😓","weary":"😩","tired_face":"😫","yawning_face":"🥱","triumph":"😤","rage":"😡","pout":"😡","angry":"😠","cursing_face":"🤬","smiling_imp":"😈","imp":"👿","skull":"💀","skull_and_crossbones":"☠️","hankey":"💩","poop":"💩","shit":"💩","clown_face":"🤡","japanese_ogre":"👹","japanese_goblin":"👺","ghost":"👻","alien":"👽","space_invader":"👾","robot":"🤖","smiley_cat":"😺","smile_cat":"😸","joy_cat":"😹","heart_eyes_cat":"😻","smirk_cat":"😼","kissing_cat":"😽","scream_cat":"🙀","crying_cat_face":"😿","pouting_cat":"😾","see_no_evil":"🙈","hear_no_evil":"🙉","speak_no_evil":"🙊","kiss":"💋","love_letter":"💌","cupid":"💘","gift_heart":"💝","sparkling_heart":"💖","heartpulse":"💗","heartbeat":"💓","revolving_hearts":"💞","two_hearts":"💕","heart_decoration":"💟","heavy_heart_exclamation":"❣️","broken_heart":"💔","heart":"❤️","orange_heart":"🧡","yellow_heart":"💛","green_heart":"💚","blue_heart":"💙","purple_heart":"💜","brown_heart":"🤎","black_heart":"🖤","white_heart":"🤍","anger":"💢","boom":"💥","collision":"💥","dizzy":"💫","sweat_drops":"💦","dash":"💨","hole":"🕳️","bomb":"💣","speech_balloon":"💬","eye_speech_bubble":"👁️‍🗨️","left_speech_bubble":"🗨️","right_anger_bubble":"🗯️","thought_balloon":"💭","zzz":"💤","wave":"👋","raised_back_of_hand":"🤚","raised_hand_with_fingers_splayed":"🖐️","hand":"","raised_hand":"","vulcan_salute":"🖖","ok_hand":"👌","pinched_fingers":"🤌","pinching_hand":"🤏","v":"✌️","crossed_fingers":"🤞","love_you_gesture":"🤟","metal":"🤘","call_me_hand":"🤙","point_left":"👈","point_right":"👉","point_up_2":"👆","middle_finger":"🖕","fu":"🖕","point_down":"👇","point_up":"☝️","+1":"👍","thumbsup":"👍","-1":"👎","thumbsdown":"👎","fist_raised":"","fist":"","fist_oncoming":"👊","facepunch":"👊","punch":"👊","fist_left":"🤛","fist_right":"🤜","clap":"👏","raised_hands":"🙌","open_hands":"👐","palms_up_together":"🤲","handshake":"🤝","pray":"🙏","writing_hand":"✍️","nail_care":"💅","selfie":"🤳","muscle":"💪","mechanical_arm":"🦾","mechanical_leg":"🦿","leg":"🦵","foot":"🦶","ear":"👂","ear_with_hearing_aid":"🦻","nose":"👃","brain":"🧠","anatomical_heart":"🫀","lungs":"🫁","tooth":"🦷","bone":"🦴","eyes":"👀","eye":"👁️","tongue":"👅","lips":"👄","baby":"👶","child":"🧒","boy":"👦","girl":"👧","adult":"🧑","blond_haired_person":"👱","man":"👨","bearded_person":"🧔","red_haired_man":"👨‍🦰","curly_haired_man":"👨‍🦱","white_haired_man":"👨‍🦳","bald_man":"👨‍🦲","woman":"👩","red_haired_woman":"👩‍🦰","person_red_hair":"🧑‍🦰","curly_haired_woman":"👩‍🦱","person_curly_hair":"🧑‍🦱","white_haired_woman":"👩‍🦳","person_white_hair":"🧑‍🦳","bald_woman":"👩‍🦲","person_bald":"🧑‍🦲","blond_haired_woman":"👱‍♀️","blonde_woman":"👱‍♀️","blond_haired_man":"👱‍♂️","older_adult":"🧓","older_man":"👴","older_woman":"👵","frowning_person":"🙍","frowning_man":"🙍‍♂️","frowning_woman":"🙍‍♀️","pouting_face":"🙎","pouting_man":"🙎‍♂️","pouting_woman":"🙎‍♀️","no_good":"🙅","no_good_man":"🙅‍♂️","ng_man":"🙅‍♂️","no_good_woman":"🙅‍♀️","ng_woman":"🙅‍♀️","ok_person":"🙆","ok_man":"🙆‍♂️","ok_woman":"🙆‍♀️","tipping_hand_person":"💁","information_desk_person":"💁","tipping_hand_man":"💁‍♂️","sassy_man":"💁‍♂️","tipping_hand_woman":"💁‍♀️","sassy_woman":"💁‍♀️","raising_hand":"🙋","raising_hand_man":"🙋‍♂️","raising_hand_woman":"🙋‍♀️","deaf_person":"🧏","deaf_man":"🧏‍♂️","deaf_woman":"🧏‍♀️","bow":"🙇","bowing_man":"🙇‍♂️","bowing_woman":"🙇‍♀️","facepalm":"🤦","man_facepalming":"🤦‍♂️","woman_facepalming":"🤦‍♀️","shrug":"🤷","man_shrugging":"🤷‍♂️","woman_shrugging":"🤷‍♀️","health_worker":"🧑‍⚕️","man_health_worker":"👨‍⚕️","woman_health_worker":"👩‍⚕️","student":"🧑‍🎓","man_student":"👨‍🎓","woman_student":"👩‍🎓","teacher":"🧑‍🏫","man_teacher":"👨‍🏫","woman_teacher":"👩‍🏫","judge":"🧑‍⚖️","man_judge":"👨‍⚖️","woman_judge":"👩‍⚖️","farmer":"🧑‍🌾","man_farmer":"👨‍🌾","woman_farmer":"👩‍🌾","cook":"🧑‍🍳","man_cook":"👨‍🍳","woman_cook":"👩‍🍳","mechanic":"🧑‍🔧","man_mechanic":"👨‍🔧","woman_mechanic":"👩‍🔧","factory_worker":"🧑‍🏭","man_factory_worker":"👨‍🏭","woman_factory_worker":"👩‍🏭","office_worker":"🧑‍💼","man_office_worker":"👨‍💼","woman_office_worker":"👩‍💼","scientist":"🧑‍🔬","man_scientist":"👨‍🔬","woman_scientist":"👩‍🔬","technologist":"🧑‍💻","man_technologist":"👨‍💻","woman_technologist":"👩‍💻","singer":"🧑‍🎤","man_singer":"👨‍🎤","woman_singer":"👩‍🎤","artist":"🧑‍🎨","man_artist":"👨‍🎨","woman_artist":"👩‍🎨","pilot":"🧑‍✈️","man_pilot":"👨‍✈️","woman_pilot":"👩‍✈️","astronaut":"🧑‍🚀","man_astronaut":"👨‍🚀","woman_astronaut":"👩‍🚀","firefighter":"🧑‍🚒","man_firefighter":"👨‍🚒","woman_firefighter":"👩‍🚒","police_officer":"👮","cop":"👮","policeman":"👮‍♂️","policewoman":"👮‍♀️","detective":"🕵️","male_detective":"🕵️‍♂️","female_detective":"🕵️‍♀️","guard":"💂","guardsman":"💂‍♂️","guardswoman":"💂‍♀️","ninja":"🥷","construction_worker":"👷","construction_worker_man":"👷‍♂️","construction_worker_woman":"👷‍♀️","prince":"🤴","princess":"👸","person_with_turban":"👳","man_with_turban":"👳‍♂️","woman_with_turban":"👳‍♀️","man_with_gua_pi_mao":"👲","woman_with_headscarf":"🧕","person_in_tuxedo":"🤵","man_in_tuxedo":"🤵‍♂️","woman_in_tuxedo":"🤵‍♀️","person_with_veil":"👰","man_with_veil":"👰‍♂️","woman_with_veil":"👰‍♀️","bride_with_veil":"👰‍♀️","pregnant_woman":"🤰","breast_feeding":"🤱","woman_feeding_baby":"👩‍🍼","man_feeding_baby":"👨‍🍼","person_feeding_baby":"🧑‍🍼","angel":"👼","santa":"🎅","mrs_claus":"🤶","mx_claus":"🧑‍🎄","superhero":"🦸","superhero_man":"🦸‍♂️","superhero_woman":"🦸‍♀️","supervillain":"🦹","supervillain_man":"🦹‍♂️","supervillain_woman":"🦹‍♀️","mage":"🧙","mage_man":"🧙‍♂️","mage_woman":"🧙‍♀️","fairy":"🧚","fairy_man":"🧚‍♂️","fairy_woman":"🧚‍♀️","vampire":"🧛","vampire_man":"🧛‍♂️","vampire_woman":"🧛‍♀️","merperson":"🧜","merman":"🧜‍♂️","mermaid":"🧜‍♀️","elf":"🧝","elf_man":"🧝‍♂️","elf_woman":"🧝‍♀️","genie":"🧞","genie_man":"🧞‍♂️","genie_woman":"🧞‍♀️","zombie":"🧟","zombie_man":"🧟‍♂️","zombie_woman":"🧟‍♀️","massage":"💆","massage_man":"💆‍♂️","massage_woman":"💆‍♀️","haircut":"💇","haircut_man":"💇‍♂️","haircut_woman":"💇‍♀️","walking":"🚶","walking_man":"🚶‍♂️","walking_woman":"🚶‍♀️","standing_person":"🧍","standing_man":"🧍‍♂️","standing_woman":"🧍‍♀️","kneeling_person":"🧎","kneeling_man":"🧎‍♂️","kneeling_woman":"🧎‍♀️","person_with_probing_cane":"🧑‍🦯","man_with_probing_cane":"👨‍🦯","woman_with_probing_cane":"👩‍🦯","person_in_motorized_wheelchair":"🧑‍🦼","man_in_motorized_wheelchair":"👨‍🦼","woman_in_motorized_wheelchair":"👩‍🦼","person_in_manual_wheelchair":"🧑‍🦽","man_in_manual_wheelchair":"👨‍🦽","woman_in_manual_wheelchair":"👩‍🦽","runner":"🏃","running":"🏃","running_man":"🏃‍♂️","running_woman":"🏃‍♀️","woman_dancing":"💃","dancer":"💃","man_dancing":"🕺","business_suit_levitating":"🕴️","dancers":"👯","dancing_men":"👯‍♂️","dancing_women":"👯‍♀️","sauna_person":"🧖","sauna_man":"🧖‍♂️","sauna_woman":"🧖‍♀️","climbing":"🧗","climbing_man":"🧗‍♂️","climbing_woman":"🧗‍♀️","person_fencing":"🤺","horse_racing":"🏇","skier":"⛷️","snowboarder":"🏂","golfing":"🏌️","golfing_man":"🏌️‍♂️","golfing_woman":"🏌️‍♀️","surfer":"🏄","surfing_man":"🏄‍♂️","surfing_woman":"🏄‍♀️","rowboat":"🚣","rowing_man":"🚣‍♂️","rowing_woman":"🚣‍♀️","swimmer":"🏊","swimming_man":"🏊‍♂️","swimming_woman":"🏊‍♀️","bouncing_ball_person":"⛹️","bouncing_ball_man":"⛹️‍♂️","basketball_man":"⛹️‍♂️","bouncing_ball_woman":"⛹️‍♀️","basketball_woman":"⛹️‍♀️","weight_lifting":"🏋️","weight_lifting_man":"🏋️‍♂️","weight_lifting_woman":"🏋️‍♀️","bicyclist":"🚴","biking_man":"🚴‍♂️","biking_woman":"🚴‍♀️","mountain_bicyclist":"🚵","mountain_biking_man":"🚵‍♂️","mountain_biking_woman":"🚵‍♀️","cartwheeling":"🤸","man_cartwheeling":"🤸‍♂️","woman_cartwheeling":"🤸‍♀️","wrestling":"🤼","men_wrestling":"🤼‍♂️","women_wrestling":"🤼‍♀️","water_polo":"🤽","man_playing_water_polo":"🤽‍♂️","woman_playing_water_polo":"🤽‍♀️","handball_person":"🤾","man_playing_handball":"🤾‍♂️","woman_playing_handball":"🤾‍♀️","juggling_person":"🤹","man_juggling":"🤹‍♂️","woman_juggling":"🤹‍♀️","lotus_position":"🧘","lotus_position_man":"🧘‍♂️","lotus_position_woman":"🧘‍♀️","bath":"🛀","sleeping_bed":"🛌","people_holding_hands":"🧑‍🤝‍🧑","two_women_holding_hands":"👭","couple":"👫","two_men_holding_hands":"👬","couplekiss":"💏","couplekiss_man_woman":"👩‍❤️‍💋‍👨","couplekiss_man_man":"👨‍❤️‍💋‍👨","couplekiss_woman_woman":"👩‍❤️‍💋‍👩","couple_with_heart":"💑","couple_with_heart_woman_man":"👩‍❤️‍👨","couple_with_heart_man_man":"👨‍❤️‍👨","couple_with_heart_woman_woman":"👩‍❤️‍👩","family":"👪","family_man_woman_boy":"👨‍👩‍👦","family_man_woman_girl":"👨‍👩‍👧","family_man_woman_girl_boy":"👨‍👩‍👧‍👦","family_man_woman_boy_boy":"👨‍👩‍👦‍👦","family_man_woman_girl_girl":"👨‍👩‍👧‍👧","family_man_man_boy":"👨‍👨‍👦","family_man_man_girl":"👨‍👨‍👧","family_man_man_girl_boy":"👨‍👨‍👧‍👦","family_man_man_boy_boy":"👨‍👨‍👦‍👦","family_man_man_girl_girl":"👨‍👨‍👧‍👧","family_woman_woman_boy":"👩‍👩‍👦","family_woman_woman_girl":"👩‍👩‍👧","family_woman_woman_girl_boy":"👩‍👩‍👧‍👦","family_woman_woman_boy_boy":"👩‍👩‍👦‍👦","family_woman_woman_girl_girl":"👩‍👩‍👧‍👧","family_man_boy":"👨‍👦","family_man_boy_boy":"👨‍👦‍👦","family_man_girl":"👨‍👧","family_man_girl_boy":"👨‍👧‍👦","family_man_girl_girl":"👨‍👧‍👧","family_woman_boy":"👩‍👦","family_woman_boy_boy":"👩‍👦‍👦","family_woman_girl":"👩‍👧","family_woman_girl_boy":"👩‍👧‍👦","family_woman_girl_girl":"👩‍👧‍👧","speaking_head":"🗣️","bust_in_silhouette":"👤","busts_in_silhouette":"👥","people_hugging":"🫂","footprints":"👣","monkey_face":"🐵","monkey":"🐒","gorilla":"🦍","orangutan":"🦧","dog":"🐶","dog2":"🐕","guide_dog":"🦮","service_dog":"🐕‍🦺","poodle":"🐩","wolf":"🐺","fox_face":"🦊","raccoon":"🦝","cat":"🐱","cat2":"🐈","black_cat":"🐈‍⬛","lion":"🦁","tiger":"🐯","tiger2":"🐅","leopard":"🐆","horse":"🐴","racehorse":"🐎","unicorn":"🦄","zebra":"🦓","deer":"🦌","bison":"🦬","cow":"🐮","ox":"🐂","water_buffalo":"🐃","cow2":"🐄","pig":"🐷","pig2":"🐖","boar":"🐗","pig_nose":"🐽","ram":"🐏","sheep":"🐑","goat":"🐐","dromedary_camel":"🐪","camel":"🐫","llama":"🦙","giraffe":"🦒","elephant":"🐘","mammoth":"🦣","rhinoceros":"🦏","hippopotamus":"🦛","mouse":"🐭","mouse2":"🐁","rat":"🐀","hamster":"🐹","rabbit":"🐰","rabbit2":"🐇","chipmunk":"🐿️","beaver":"🦫","hedgehog":"🦔","bat":"🦇","bear":"🐻","polar_bear":"🐻‍❄️","koala":"🐨","panda_face":"🐼","sloth":"🦥","otter":"🦦","skunk":"🦨","kangaroo":"🦘","badger":"🦡","feet":"🐾","paw_prints":"🐾","turkey":"🦃","chicken":"🐔","rooster":"🐓","hatching_chick":"🐣","baby_chick":"🐤","hatched_chick":"🐥","bird":"🐦","penguin":"🐧","dove":"🕊️","eagle":"🦅","duck":"🦆","swan":"🦢","owl":"🦉","dodo":"🦤","feather":"🪶","flamingo":"🦩","peacock":"🦚","parrot":"🦜","frog":"🐸","crocodile":"🐊","turtle":"🐢","lizard":"🦎","snake":"🐍","dragon_face":"🐲","dragon":"🐉","sauropod":"🦕","t-rex":"🦖","whale":"🐳","whale2":"🐋","dolphin":"🐬","flipper":"🐬","seal":"🦭","fish":"🐟","tropical_fish":"🐠","blowfish":"🐡","shark":"🦈","octopus":"🐙","shell":"🐚","snail":"🐌","butterfly":"🦋","bug":"🐛","ant":"🐜","bee":"🐝","honeybee":"🐝","beetle":"🪲","lady_beetle":"🐞","cricket":"🦗","cockroach":"🪳","spider":"🕷️","spider_web":"🕸️","scorpion":"🦂","mosquito":"🦟","fly":"🪰","worm":"🪱","microbe":"🦠","bouquet":"💐","cherry_blossom":"🌸","white_flower":"💮","rosette":"🏵️","rose":"🌹","wilted_flower":"🥀","hibiscus":"🌺","sunflower":"🌻","blossom":"🌼","tulip":"🌷","seedling":"🌱","potted_plant":"🪴","evergreen_tree":"🌲","deciduous_tree":"🌳","palm_tree":"🌴","cactus":"🌵","ear_of_rice":"🌾","herb":"🌿","shamrock":"☘️","four_leaf_clover":"🍀","maple_leaf":"🍁","fallen_leaf":"🍂","leaves":"🍃","grapes":"🍇","melon":"🍈","watermelon":"🍉","tangerine":"🍊","orange":"🍊","mandarin":"🍊","lemon":"🍋","banana":"🍌","pineapple":"🍍","mango":"🥭","apple":"🍎","green_apple":"🍏","pear":"🍐","peach":"🍑","cherries":"🍒","strawberry":"🍓","blueberries":"🫐","kiwi_fruit":"🥝","tomato":"🍅","olive":"🫒","coconut":"🥥","avocado":"🥑","eggplant":"🍆","potato":"🥔","carrot":"🥕","corn":"🌽","hot_pepper":"🌶️","bell_pepper":"🫑","cucumber":"🥒","leafy_green":"🥬","broccoli":"🥦","garlic":"🧄","onion":"🧅","mushroom":"🍄","peanuts":"🥜","chestnut":"🌰","bread":"🍞","croissant":"🥐","baguette_bread":"🥖","flatbread":"🫓","pretzel":"🥨","bagel":"🥯","pancakes":"🥞","waffle":"🧇","cheese":"🧀","meat_on_bone":"🍖","poultry_leg":"🍗","cut_of_meat":"🥩","bacon":"🥓","hamburger":"🍔","fries":"🍟","pizza":"🍕","hotdog":"🌭","sandwich":"🥪","taco":"🌮","burrito":"🌯","tamale":"🫔","stuffed_flatbread":"🥙","falafel":"🧆","egg":"🥚","fried_egg":"🍳","shallow_pan_of_food":"🥘","stew":"🍲","fondue":"🫕","bowl_with_spoon":"🥣","green_salad":"🥗","popcorn":"🍿","butter":"🧈","salt":"🧂","canned_food":"🥫","bento":"🍱","rice_cracker":"🍘","rice_ball":"🍙","rice":"🍚","curry":"🍛","ramen":"🍜","spaghetti":"🍝","sweet_potato":"🍠","oden":"🍢","sushi":"🍣","fried_shrimp":"🍤","fish_cake":"🍥","moon_cake":"🥮","dango":"🍡","dumpling":"🥟","fortune_cookie":"🥠","takeout_box":"🥡","crab":"🦀","lobster":"🦞","shrimp":"🦐","squid":"🦑","oyster":"🦪","icecream":"🍦","shaved_ice":"🍧","ice_cream":"🍨","doughnut":"🍩","cookie":"🍪","birthday":"🎂","cake":"🍰","cupcake":"🧁","pie":"🥧","chocolate_bar":"🍫","candy":"🍬","lollipop":"🍭","custard":"🍮","honey_pot":"🍯","baby_bottle":"🍼","milk_glass":"🥛","coffee":"","teapot":"🫖","tea":"🍵","sake":"🍶","champagne":"🍾","wine_glass":"🍷","cocktail":"🍸","tropical_drink":"🍹","beer":"🍺","beers":"🍻","clinking_glasses":"🥂","tumbler_glass":"🥃","cup_with_straw":"🥤","bubble_tea":"🧋","beverage_box":"🧃","mate":"🧉","ice_cube":"🧊","chopsticks":"🥢","plate_with_cutlery":"🍽️","fork_and_knife":"🍴","spoon":"🥄","hocho":"🔪","knife":"🔪","amphora":"🏺","earth_africa":"🌍","earth_americas":"🌎","earth_asia":"🌏","globe_with_meridians":"🌐","world_map":"🗺️","japan":"🗾","compass":"🧭","mountain_snow":"🏔️","mountain":"⛰️","volcano":"🌋","mount_fuji":"🗻","camping":"🏕️","beach_umbrella":"🏖️","desert":"🏜️","desert_island":"🏝️","national_park":"🏞️","stadium":"🏟️","classical_building":"🏛️","building_construction":"🏗️","bricks":"🧱","rock":"🪨","wood":"🪵","hut":"🛖","houses":"🏘️","derelict_house":"🏚️","house":"🏠","house_with_garden":"🏡","office":"🏢","post_office":"🏣","european_post_office":"🏤","hospital":"🏥","bank":"🏦","hotel":"🏨","love_hotel":"🏩","convenience_store":"🏪","school":"🏫","department_store":"🏬","factory":"🏭","japanese_castle":"🏯","european_castle":"🏰","wedding":"💒","tokyo_tower":"🗼","statue_of_liberty":"🗽","church":"","mosque":"🕌","hindu_temple":"🛕","synagogue":"🕍","shinto_shrine":"⛩️","kaaba":"🕋","fountain":"","tent":"","foggy":"🌁","night_with_stars":"🌃","cityscape":"🏙️","sunrise_over_mountains":"🌄","sunrise":"🌅","city_sunset":"🌆","city_sunrise":"🌇","bridge_at_night":"🌉","hotsprings":"♨️","carousel_horse":"🎠","ferris_wheel":"🎡","roller_coaster":"🎢","barber":"💈","circus_tent":"🎪","steam_locomotive":"🚂","railway_car":"🚃","bullettrain_side":"🚄","bullettrain_front":"🚅","train2":"🚆","metro":"🚇","light_rail":"🚈","station":"🚉","tram":"🚊","monorail":"🚝","mountain_railway":"🚞","train":"🚋","bus":"🚌","oncoming_bus":"🚍","trolleybus":"🚎","minibus":"🚐","ambulance":"🚑","fire_engine":"🚒","police_car":"🚓","oncoming_police_car":"🚔","taxi":"🚕","oncoming_taxi":"🚖","car":"🚗","red_car":"🚗","oncoming_automobile":"🚘","blue_car":"🚙","pickup_truck":"🛻","truck":"🚚","articulated_lorry":"🚛","tractor":"🚜","racing_car":"🏎️","motorcycle":"🏍️","motor_scooter":"🛵","manual_wheelchair":"🦽","motorized_wheelchair":"🦼","auto_rickshaw":"🛺","bike":"🚲","kick_scooter":"🛴","skateboard":"🛹","roller_skate":"🛼","busstop":"🚏","motorway":"🛣️","railway_track":"🛤️","oil_drum":"🛢️","fuelpump":"","rotating_light":"🚨","traffic_light":"🚥","vertical_traffic_light":"🚦","stop_sign":"🛑","construction":"🚧","anchor":"","boat":"","sailboat":"","canoe":"🛶","speedboat":"🚤","passenger_ship":"🛳️","ferry":"⛴️","motor_boat":"🛥️","ship":"🚢","airplane":"✈️","small_airplane":"🛩️","flight_departure":"🛫","flight_arrival":"🛬","parachute":"🪂","seat":"💺","helicopter":"🚁","suspension_railway":"🚟","mountain_cableway":"🚠","aerial_tramway":"🚡","artificial_satellite":"🛰️","rocket":"🚀","flying_saucer":"🛸","bellhop_bell":"🛎️","luggage":"🧳","hourglass":"","hourglass_flowing_sand":"","watch":"","alarm_clock":"","stopwatch":"⏱️","timer_clock":"⏲️","mantelpiece_clock":"🕰️","clock12":"🕛","clock1230":"🕧","clock1":"🕐","clock130":"🕜","clock2":"🕑","clock230":"🕝","clock3":"🕒","clock330":"🕞","clock4":"🕓","clock430":"🕟","clock5":"🕔","clock530":"🕠","clock6":"🕕","clock630":"🕡","clock7":"🕖","clock730":"🕢","clock8":"🕗","clock830":"🕣","clock9":"🕘","clock930":"🕤","clock10":"🕙","clock1030":"🕥","clock11":"🕚","clock1130":"🕦","new_moon":"🌑","waxing_crescent_moon":"🌒","first_quarter_moon":"🌓","moon":"🌔","waxing_gibbous_moon":"🌔","full_moon":"🌕","waning_gibbous_moon":"🌖","last_quarter_moon":"🌗","waning_crescent_moon":"🌘","crescent_moon":"🌙","new_moon_with_face":"🌚","first_quarter_moon_with_face":"🌛","last_quarter_moon_with_face":"🌜","thermometer":"🌡️","sunny":"☀️","full_moon_with_face":"🌝","sun_with_face":"🌞","ringed_planet":"🪐","star":"","star2":"🌟","stars":"🌠","milky_way":"🌌","cloud":"☁️","partly_sunny":"","cloud_with_lightning_and_rain":"⛈️","sun_behind_small_cloud":"🌤️","sun_behind_large_cloud":"🌥️","sun_behind_rain_cloud":"🌦️","cloud_with_rain":"🌧️","cloud_with_snow":"🌨️","cloud_with_lightning":"🌩️","tornado":"🌪️","fog":"🌫️","wind_face":"🌬️","cyclone":"🌀","rainbow":"🌈","closed_umbrella":"🌂","open_umbrella":"☂️","umbrella":"","parasol_on_ground":"⛱️","zap":"","snowflake":"❄️","snowman_with_snow":"☃️","snowman":"","comet":"☄️","fire":"🔥","droplet":"💧","ocean":"🌊","jack_o_lantern":"🎃","christmas_tree":"🎄","fireworks":"🎆","sparkler":"🎇","firecracker":"🧨","sparkles":"","balloon":"🎈","tada":"🎉","confetti_ball":"🎊","tanabata_tree":"🎋","bamboo":"🎍","dolls":"🎎","flags":"🎏","wind_chime":"🎐","rice_scene":"🎑","red_envelope":"🧧","ribbon":"🎀","gift":"🎁","reminder_ribbon":"🎗️","tickets":"🎟️","ticket":"🎫","medal_military":"🎖️","trophy":"🏆","medal_sports":"🏅","1st_place_medal":"🥇","2nd_place_medal":"🥈","3rd_place_medal":"🥉","soccer":"","baseball":"","softball":"🥎","basketball":"🏀","volleyball":"🏐","football":"🏈","rugby_football":"🏉","tennis":"🎾","flying_disc":"🥏","bowling":"🎳","cricket_game":"🏏","field_hockey":"🏑","ice_hockey":"🏒","lacrosse":"🥍","ping_pong":"🏓","badminton":"🏸","boxing_glove":"🥊","martial_arts_uniform":"🥋","goal_net":"🥅","golf":"","ice_skate":"⛸️","fishing_pole_and_fish":"🎣","diving_mask":"🤿","running_shirt_with_sash":"🎽","ski":"🎿","sled":"🛷","curling_stone":"🥌","dart":"🎯","yo_yo":"🪀","kite":"🪁","8ball":"🎱","crystal_ball":"🔮","magic_wand":"🪄","nazar_amulet":"🧿","video_game":"🎮","joystick":"🕹️","slot_machine":"🎰","game_die":"🎲","jigsaw":"🧩","teddy_bear":"🧸","pinata":"🪅","nesting_dolls":"🪆","spades":"♠️","hearts":"♥️","diamonds":"♦️","clubs":"♣️","chess_pawn":"♟️","black_joker":"🃏","mahjong":"🀄","flower_playing_cards":"🎴","performing_arts":"🎭","framed_picture":"🖼️","art":"🎨","thread":"🧵","sewing_needle":"🪡","yarn":"🧶","knot":"🪢","eyeglasses":"👓","dark_sunglasses":"🕶️","goggles":"🥽","lab_coat":"🥼","safety_vest":"🦺","necktie":"👔","shirt":"👕","tshirt":"👕","jeans":"👖","scarf":"🧣","gloves":"🧤","coat":"🧥","socks":"🧦","dress":"👗","kimono":"👘","sari":"🥻","one_piece_swimsuit":"🩱","swim_brief":"🩲","shorts":"🩳","bikini":"👙","womans_clothes":"👚","purse":"👛","handbag":"👜","pouch":"👝","shopping":"🛍️","school_satchel":"🎒","thong_sandal":"🩴","mans_shoe":"👞","shoe":"👞","athletic_shoe":"👟","hiking_boot":"🥾","flat_shoe":"🥿","high_heel":"👠","sandal":"👡","ballet_shoes":"🩰","boot":"👢","crown":"👑","womans_hat":"👒","tophat":"🎩","mortar_board":"🎓","billed_cap":"🧢","military_helmet":"🪖","rescue_worker_helmet":"⛑️","prayer_beads":"📿","lipstick":"💄","ring":"💍","gem":"💎","mute":"🔇","speaker":"🔈","sound":"🔉","loud_sound":"🔊","loudspeaker":"📢","mega":"📣","postal_horn":"📯","bell":"🔔","no_bell":"🔕","musical_score":"🎼","musical_note":"🎵","notes":"🎶","studio_microphone":"🎙️","level_slider":"🎚️","control_knobs":"🎛️","microphone":"🎤","headphones":"🎧","radio":"📻","saxophone":"🎷","accordion":"🪗","guitar":"🎸","musical_keyboard":"🎹","trumpet":"🎺","violin":"🎻","banjo":"🪕","drum":"🥁","long_drum":"🪘","iphone":"📱","calling":"📲","phone":"☎️","telephone":"☎️","telephone_receiver":"📞","pager":"📟","fax":"📠","battery":"🔋","electric_plug":"🔌","computer":"💻","desktop_computer":"🖥️","printer":"🖨️","keyboard":"⌨️","computer_mouse":"🖱️","trackball":"🖲️","minidisc":"💽","floppy_disk":"💾","cd":"💿","dvd":"📀","abacus":"🧮","movie_camera":"🎥","film_strip":"🎞️","film_projector":"📽️","clapper":"🎬","tv":"📺","camera":"📷","camera_flash":"📸","video_camera":"📹","vhs":"📼","mag":"🔍","mag_right":"🔎","candle":"🕯️","bulb":"💡","flashlight":"🔦","izakaya_lantern":"🏮","lantern":"🏮","diya_lamp":"🪔","notebook_with_decorative_cover":"📔","closed_book":"📕","book":"📖","open_book":"📖","green_book":"📗","blue_book":"📘","orange_book":"📙","books":"📚","notebook":"📓","ledger":"📒","page_with_curl":"📃","scroll":"📜","page_facing_up":"📄","newspaper":"📰","newspaper_roll":"🗞️","bookmark_tabs":"📑","bookmark":"🔖","label":"🏷️","moneybag":"💰","coin":"🪙","yen":"💴","dollar":"💵","euro":"💶","pound":"💷","money_with_wings":"💸","credit_card":"💳","receipt":"🧾","chart":"💹","envelope":"✉️","email":"📧","e-mail":"📧","incoming_envelope":"📨","envelope_with_arrow":"📩","outbox_tray":"📤","inbox_tray":"📥","package":"📦","mailbox":"📫","mailbox_closed":"📪","mailbox_with_mail":"📬","mailbox_with_no_mail":"📭","postbox":"📮","ballot_box":"🗳️","pencil2":"✏️","black_nib":"✒️","fountain_pen":"🖋️","pen":"🖊️","paintbrush":"🖌️","crayon":"🖍️","memo":"📝","pencil":"📝","briefcase":"💼","file_folder":"📁","open_file_folder":"📂","card_index_dividers":"🗂️","date":"📅","calendar":"📆","spiral_notepad":"🗒️","spiral_calendar":"🗓️","card_index":"📇","chart_with_upwards_trend":"📈","chart_with_downwards_trend":"📉","bar_chart":"📊","clipboard":"📋","pushpin":"📌","round_pushpin":"📍","paperclip":"📎","paperclips":"🖇️","straight_ruler":"📏","triangular_ruler":"📐","scissors":"✂️","card_file_box":"🗃️","file_cabinet":"🗄️","wastebasket":"🗑️","lock":"🔒","unlock":"🔓","lock_with_ink_pen":"🔏","closed_lock_with_key":"🔐","key":"🔑","old_key":"🗝️","hammer":"🔨","axe":"🪓","pick":"⛏️","hammer_and_pick":"⚒️","hammer_and_wrench":"🛠️","dagger":"🗡️","crossed_swords":"⚔️","gun":"🔫","boomerang":"🪃","bow_and_arrow":"🏹","shield":"🛡️","carpentry_saw":"🪚","wrench":"🔧","screwdriver":"🪛","nut_and_bolt":"🔩","gear":"⚙️","clamp":"🗜️","balance_scale":"⚖️","probing_cane":"🦯","link":"🔗","chains":"⛓️","hook":"🪝","toolbox":"🧰","magnet":"🧲","ladder":"🪜","alembic":"⚗️","test_tube":"🧪","petri_dish":"🧫","dna":"🧬","microscope":"🔬","telescope":"🔭","satellite":"📡","syringe":"💉","drop_of_blood":"🩸","pill":"💊","adhesive_bandage":"🩹","stethoscope":"🩺","door":"🚪","elevator":"🛗","mirror":"🪞","window":"🪟","bed":"🛏️","couch_and_lamp":"🛋️","chair":"🪑","toilet":"🚽","plunger":"🪠","shower":"🚿","bathtub":"🛁","mouse_trap":"🪤","razor":"🪒","lotion_bottle":"🧴","safety_pin":"🧷","broom":"🧹","basket":"🧺","roll_of_paper":"🧻","bucket":"🪣","soap":"🧼","toothbrush":"🪥","sponge":"🧽","fire_extinguisher":"🧯","shopping_cart":"🛒","smoking":"🚬","coffin":"⚰️","headstone":"🪦","funeral_urn":"⚱️","moyai":"🗿","placard":"🪧","atm":"🏧","put_litter_in_its_place":"🚮","potable_water":"🚰","wheelchair":"","mens":"🚹","womens":"🚺","restroom":"🚻","baby_symbol":"🚼","wc":"🚾","passport_control":"🛂","customs":"🛃","baggage_claim":"🛄","left_luggage":"🛅","warning":"⚠️","children_crossing":"🚸","no_entry":"","no_entry_sign":"🚫","no_bicycles":"🚳","no_smoking":"🚭","do_not_litter":"🚯","non-potable_water":"🚱","no_pedestrians":"🚷","no_mobile_phones":"📵","underage":"🔞","radioactive":"☢️","biohazard":"☣️","arrow_up":"⬆️","arrow_upper_right":"↗️","arrow_right":"➡️","arrow_lower_right":"↘️","arrow_down":"⬇️","arrow_lower_left":"↙️","arrow_left":"⬅️","arrow_upper_left":"↖️","arrow_up_down":"↕️","left_right_arrow":"↔️","leftwards_arrow_with_hook":"↩️","arrow_right_hook":"↪️","arrow_heading_up":"⤴️","arrow_heading_down":"⤵️","arrows_clockwise":"🔃","arrows_counterclockwise":"🔄","back":"🔙","end":"🔚","on":"🔛","soon":"🔜","top":"🔝","place_of_worship":"🛐","atom_symbol":"⚛️","om":"🕉️","star_of_david":"✡️","wheel_of_dharma":"☸️","yin_yang":"☯️","latin_cross":"✝️","orthodox_cross":"☦️","star_and_crescent":"☪️","peace_symbol":"☮️","menorah":"🕎","six_pointed_star":"🔯","aries":"","taurus":"","gemini":"","cancer":"","leo":"","virgo":"","libra":"","scorpius":"","sagittarius":"","capricorn":"","aquarius":"","pisces":"","ophiuchus":"","twisted_rightwards_arrows":"🔀","repeat":"🔁","repeat_one":"🔂","arrow_forward":"▶️","fast_forward":"","next_track_button":"⏭️","play_or_pause_button":"⏯️","arrow_backward":"◀️","rewind":"","previous_track_button":"⏮️","arrow_up_small":"🔼","arrow_double_up":"","arrow_down_small":"🔽","arrow_double_down":"","pause_button":"⏸️","stop_button":"⏹️","record_button":"⏺️","eject_button":"⏏️","cinema":"🎦","low_brightness":"🔅","high_brightness":"🔆","signal_strength":"📶","vibration_mode":"📳","mobile_phone_off":"📴","female_sign":"♀️","male_sign":"♂️","transgender_symbol":"⚧️","heavy_multiplication_x":"✖️","heavy_plus_sign":"","heavy_minus_sign":"","heavy_division_sign":"","infinity":"♾️","bangbang":"‼️","interrobang":"⁉️","question":"","grey_question":"","grey_exclamation":"","exclamation":"","heavy_exclamation_mark":"","wavy_dash":"〰️","currency_exchange":"💱","heavy_dollar_sign":"💲","medical_symbol":"⚕️","recycle":"♻️","fleur_de_lis":"⚜️","trident":"🔱","name_badge":"📛","beginner":"🔰","o":"","white_check_mark":"","ballot_box_with_check":"☑️","heavy_check_mark":"✔️","x":"","negative_squared_cross_mark":"","curly_loop":"","loop":"","part_alternation_mark":"〽️","eight_spoked_asterisk":"✳️","eight_pointed_black_star":"✴️","sparkle":"❇️","copyright":"©️","registered":"®️","tm":"™️","hash":"#️⃣","asterisk":"*️⃣","zero":"0️⃣","one":"1️⃣","two":"2️⃣","three":"3️⃣","four":"4️⃣","five":"5️⃣","six":"6️⃣","seven":"7️⃣","eight":"8️⃣","nine":"9️⃣","keycap_ten":"🔟","capital_abcd":"🔠","abcd":"🔡","symbols":"🔣","abc":"🔤","a":"🅰️","ab":"🆎","b":"🅱️","cl":"🆑","cool":"🆒","free":"🆓","information_source":"ℹ️","id":"🆔","m":"Ⓜ️","new":"🆕","ng":"🆖","o2":"🅾️","ok":"🆗","parking":"🅿️","sos":"🆘","up":"🆙","vs":"🆚","koko":"🈁","sa":"🈂️","u6708":"🈷️","u6709":"🈶","u6307":"🈯","ideograph_advantage":"🉐","u5272":"🈹","u7121":"🈚","u7981":"🈲","accept":"🉑","u7533":"🈸","u5408":"🈴","u7a7a":"🈳","congratulations":"㊗️","secret":"㊙️","u55b6":"🈺","u6e80":"🈵","red_circle":"🔴","orange_circle":"🟠","yellow_circle":"🟡","green_circle":"🟢","large_blue_circle":"🔵","purple_circle":"🟣","brown_circle":"🟤","black_circle":"","white_circle":"","red_square":"🟥","orange_square":"🟧","yellow_square":"🟨","green_square":"🟩","blue_square":"🟦","purple_square":"🟪","brown_square":"🟫","black_large_square":"","white_large_square":"","black_medium_square":"◼️","white_medium_square":"◻️","black_medium_small_square":"","white_medium_small_square":"","black_small_square":"▪️","white_small_square":"▫️","large_orange_diamond":"🔶","large_blue_diamond":"🔷","small_orange_diamond":"🔸","small_blue_diamond":"🔹","small_red_triangle":"🔺","small_red_triangle_down":"🔻","diamond_shape_with_a_dot_inside":"💠","radio_button":"🔘","white_square_button":"🔳","black_square_button":"🔲","checkered_flag":"🏁","triangular_flag_on_post":"🚩","crossed_flags":"🎌","black_flag":"🏴","white_flag":"🏳️","rainbow_flag":"🏳️‍🌈","transgender_flag":"🏳️‍⚧️","pirate_flag":"🏴‍☠️","ascension_island":"🇦🇨","andorra":"🇦🇩","united_arab_emirates":"🇦🇪","afghanistan":"🇦🇫","antigua_barbuda":"🇦🇬","anguilla":"🇦🇮","albania":"🇦🇱","armenia":"🇦🇲","angola":"🇦🇴","antarctica":"🇦🇶","argentina":"🇦🇷","american_samoa":"🇦🇸","austria":"🇦🇹","australia":"🇦🇺","aruba":"🇦🇼","aland_islands":"🇦🇽","azerbaijan":"🇦🇿","bosnia_herzegovina":"🇧🇦","barbados":"🇧🇧","bangladesh":"🇧🇩","belgium":"🇧🇪","burkina_faso":"🇧🇫","bulgaria":"🇧🇬","bahrain":"🇧🇭","burundi":"🇧🇮","benin":"🇧🇯","st_barthelemy":"🇧🇱","bermuda":"🇧🇲","brunei":"🇧🇳","bolivia":"🇧🇴","caribbean_netherlands":"🇧🇶","brazil":"🇧🇷","bahamas":"🇧🇸","bhutan":"🇧🇹","bouvet_island":"🇧🇻","botswana":"🇧🇼","belarus":"🇧🇾","belize":"🇧🇿","canada":"🇨🇦","cocos_islands":"🇨🇨","congo_kinshasa":"🇨🇩","central_african_republic":"🇨🇫","congo_brazzaville":"🇨🇬","switzerland":"🇨🇭","cote_divoire":"🇨🇮","cook_islands":"🇨🇰","chile":"🇨🇱","cameroon":"🇨🇲","cn":"🇨🇳","colombia":"🇨🇴","clipperton_island":"🇨🇵","costa_rica":"🇨🇷","cuba":"🇨🇺","cape_verde":"🇨🇻","curacao":"🇨🇼","christmas_island":"🇨🇽","cyprus":"🇨🇾","czech_republic":"🇨🇿","de":"🇩🇪","diego_garcia":"🇩🇬","djibouti":"🇩🇯","denmark":"🇩🇰","dominica":"🇩🇲","dominican_republic":"🇩🇴","algeria":"🇩🇿","ceuta_melilla":"🇪🇦","ecuador":"🇪🇨","estonia":"🇪🇪","egypt":"🇪🇬","western_sahara":"🇪🇭","eritrea":"🇪🇷","es":"🇪🇸","ethiopia":"🇪🇹","eu":"🇪🇺","european_union":"🇪🇺","finland":"🇫🇮","fiji":"🇫🇯","falkland_islands":"🇫🇰","micronesia":"🇫🇲","faroe_islands":"🇫🇴","fr":"🇫🇷","gabon":"🇬🇦","gb":"🇬🇧","uk":"🇬🇧","grenada":"🇬🇩","georgia":"🇬🇪","french_guiana":"🇬🇫","guernsey":"🇬🇬","ghana":"🇬🇭","gibraltar":"🇬🇮","greenland":"🇬🇱","gambia":"🇬🇲","guinea":"🇬🇳","guadeloupe":"🇬🇵","equatorial_guinea":"🇬🇶","greece":"🇬🇷","south_georgia_south_sandwich_islands":"🇬🇸","guatemala":"🇬🇹","guam":"🇬🇺","guinea_bissau":"🇬🇼","guyana":"🇬🇾","hong_kong":"🇭🇰","heard_mcdonald_islands":"🇭🇲","honduras":"🇭🇳","croatia":"🇭🇷","haiti":"🇭🇹","hungary":"🇭🇺","canary_islands":"🇮🇨","indonesia":"🇮🇩","ireland":"🇮🇪","israel":"🇮🇱","isle_of_man":"🇮🇲","india":"🇮🇳","british_indian_ocean_territory":"🇮🇴","iraq":"🇮🇶","iran":"🇮🇷","iceland":"🇮🇸","it":"🇮🇹","jersey":"🇯🇪","jamaica":"🇯🇲","jordan":"🇯🇴","jp":"🇯🇵","kenya":"🇰🇪","kyrgyzstan":"🇰🇬","cambodia":"🇰🇭","kiribati":"🇰🇮","comoros":"🇰🇲","st_kitts_nevis":"🇰🇳","north_korea":"🇰🇵","kr":"🇰🇷","kuwait":"🇰🇼","cayman_islands":"🇰🇾","kazakhstan":"🇰🇿","laos":"🇱🇦","lebanon":"🇱🇧","st_lucia":"🇱🇨","liechtenstein":"🇱🇮","sri_lanka":"🇱🇰","liberia":"🇱🇷","lesotho":"🇱🇸","lithuania":"🇱🇹","luxembourg":"🇱🇺","latvia":"🇱🇻","libya":"🇱🇾","morocco":"🇲🇦","monaco":"🇲🇨","moldova":"🇲🇩","montenegro":"🇲🇪","st_martin":"🇲🇫","madagascar":"🇲🇬","marshall_islands":"🇲🇭","macedonia":"🇲🇰","mali":"🇲🇱","myanmar":"🇲🇲","mongolia":"🇲🇳","macau":"🇲🇴","northern_mariana_islands":"🇲🇵","martinique":"🇲🇶","mauritania":"🇲🇷","montserrat":"🇲🇸","malta":"🇲🇹","mauritius":"🇲🇺","maldives":"🇲🇻","malawi":"🇲🇼","mexico":"🇲🇽","malaysia":"🇲🇾","mozambique":"🇲🇿","namibia":"🇳🇦","new_caledonia":"🇳🇨","niger":"🇳🇪","norfolk_island":"🇳🇫","nigeria":"🇳🇬","nicaragua":"🇳🇮","netherlands":"🇳🇱","norway":"🇳🇴","nepal":"🇳🇵","nauru":"🇳🇷","niue":"🇳🇺","new_zealand":"🇳🇿","oman":"🇴🇲","panama":"🇵🇦","peru":"🇵🇪","french_polynesia":"🇵🇫","papua_new_guinea":"🇵🇬","philippines":"🇵🇭","pakistan":"🇵🇰","poland":"🇵🇱","st_pierre_miquelon":"🇵🇲","pitcairn_islands":"🇵🇳","puerto_rico":"🇵🇷","palestinian_territories":"🇵🇸","portugal":"🇵🇹","palau":"🇵🇼","paraguay":"🇵🇾","qatar":"🇶🇦","reunion":"🇷🇪","romania":"🇷🇴","serbia":"🇷🇸","ru":"🇷🇺","rwanda":"🇷🇼","saudi_arabia":"🇸🇦","solomon_islands":"🇸🇧","seychelles":"🇸🇨","sudan":"🇸🇩","sweden":"🇸🇪","singapore":"🇸🇬","st_helena":"🇸🇭","slovenia":"🇸🇮","svalbard_jan_mayen":"🇸🇯","slovakia":"🇸🇰","sierra_leone":"🇸🇱","san_marino":"🇸🇲","senegal":"🇸🇳","somalia":"🇸🇴","suriname":"🇸🇷","south_sudan":"🇸🇸","sao_tome_principe":"🇸🇹","el_salvador":"🇸🇻","sint_maarten":"🇸🇽","syria":"🇸🇾","swaziland":"🇸🇿","tristan_da_cunha":"🇹🇦","turks_caicos_islands":"🇹🇨","chad":"🇹🇩","french_southern_territories":"🇹🇫","togo":"🇹🇬","thailand":"🇹🇭","tajikistan":"🇹🇯","tokelau":"🇹🇰","timor_leste":"🇹🇱","turkmenistan":"🇹🇲","tunisia":"🇹🇳","tonga":"🇹🇴","tr":"🇹🇷","trinidad_tobago":"🇹🇹","tuvalu":"🇹🇻","taiwan":"🇹🇼","tanzania":"🇹🇿","ukraine":"🇺🇦","uganda":"🇺🇬","us_outlying_islands":"🇺🇲","united_nations":"🇺🇳","us":"🇺🇸","uruguay":"🇺🇾","uzbekistan":"🇺🇿","vatican_city":"🇻🇦","st_vincent_grenadines":"🇻🇨","venezuela":"🇻🇪","british_virgin_islands":"🇻🇬","us_virgin_islands":"🇻🇮","vietnam":"🇻🇳","vanuatu":"🇻🇺","wallis_futuna":"🇼🇫","samoa":"🇼🇸","kosovo":"🇽🇰","yemen":"🇾🇪","mayotte":"🇾🇹","south_africa":"🇿🇦","zambia":"🇿🇲","zimbabwe":"🇿🇼","england":"🏴󠁧󠁢󠁥󠁮󠁧󠁿","scotland":"🏴󠁧󠁢󠁳󠁣󠁴󠁿","wales":"🏴󠁧󠁢󠁷󠁬󠁳󠁿"} export const emojiDictionary = {
\ No newline at end of file 100: "💯",
1234: "🔢",
grinning: "😀",
smiley: "😃",
smile: "😄",
grin: "😁",
laughing: "😆",
satisfied: "😆",
sweat_smile: "😅",
rofl: "🤣",
joy: "😂",
slightly_smiling_face: "🙂",
upside_down_face: "🙃",
wink: "😉",
blush: "😊",
innocent: "😇",
smiling_face_with_three_hearts: "🥰",
heart_eyes: "😍",
star_struck: "🤩",
kissing_heart: "😘",
kissing: "😗",
relaxed: "☺️",
kissing_closed_eyes: "😚",
kissing_smiling_eyes: "😙",
smiling_face_with_tear: "🥲",
yum: "😋",
stuck_out_tongue: "😛",
stuck_out_tongue_winking_eye: "😜",
zany_face: "🤪",
stuck_out_tongue_closed_eyes: "😝",
money_mouth_face: "🤑",
hugs: "🤗",
hand_over_mouth: "🤭",
shushing_face: "🤫",
thinking: "🤔",
zipper_mouth_face: "🤐",
raised_eyebrow: "🤨",
neutral_face: "😐",
expressionless: "😑",
no_mouth: "😶",
smirk: "😏",
unamused: "😒",
roll_eyes: "🙄",
grimacing: "😬",
lying_face: "🤥",
relieved: "😌",
pensive: "😔",
sleepy: "😪",
drooling_face: "🤤",
sleeping: "😴",
mask: "😷",
face_with_thermometer: "🤒",
face_with_head_bandage: "🤕",
nauseated_face: "🤢",
vomiting_face: "🤮",
sneezing_face: "🤧",
hot_face: "🥵",
cold_face: "🥶",
woozy_face: "🥴",
dizzy_face: "😵",
exploding_head: "🤯",
cowboy_hat_face: "🤠",
partying_face: "🥳",
disguised_face: "🥸",
sunglasses: "😎",
nerd_face: "🤓",
monocle_face: "🧐",
confused: "😕",
worried: "😟",
slightly_frowning_face: "🙁",
frowning_face: "☹️",
open_mouth: "😮",
hushed: "😯",
astonished: "😲",
flushed: "😳",
pleading_face: "🥺",
frowning: "😦",
anguished: "😧",
fearful: "😨",
cold_sweat: "😰",
disappointed_relieved: "😥",
cry: "😢",
sob: "😭",
scream: "😱",
confounded: "😖",
persevere: "😣",
disappointed: "😞",
sweat: "😓",
weary: "😩",
tired_face: "😫",
yawning_face: "🥱",
triumph: "😤",
rage: "😡",
pout: "😡",
angry: "😠",
cursing_face: "🤬",
smiling_imp: "😈",
imp: "👿",
skull: "💀",
skull_and_crossbones: "☠️",
hankey: "💩",
poop: "💩",
shit: "💩",
clown_face: "🤡",
japanese_ogre: "👹",
japanese_goblin: "👺",
ghost: "👻",
alien: "👽",
space_invader: "👾",
robot: "🤖",
smiley_cat: "😺",
smile_cat: "😸",
joy_cat: "😹",
heart_eyes_cat: "😻",
smirk_cat: "😼",
kissing_cat: "😽",
scream_cat: "🙀",
crying_cat_face: "😿",
pouting_cat: "😾",
see_no_evil: "🙈",
hear_no_evil: "🙉",
speak_no_evil: "🙊",
kiss: "💋",
love_letter: "💌",
cupid: "💘",
gift_heart: "💝",
sparkling_heart: "💖",
heartpulse: "💗",
heartbeat: "💓",
revolving_hearts: "💞",
two_hearts: "💕",
heart_decoration: "💟",
heavy_heart_exclamation: "❣️",
broken_heart: "💔",
heart: "❤️",
orange_heart: "🧡",
yellow_heart: "💛",
green_heart: "💚",
blue_heart: "💙",
purple_heart: "💜",
brown_heart: "🤎",
black_heart: "🖤",
white_heart: "🤍",
anger: "💢",
boom: "💥",
collision: "💥",
dizzy: "💫",
sweat_drops: "💦",
dash: "💨",
hole: "🕳️",
bomb: "💣",
speech_balloon: "💬",
eye_speech_bubble: "👁️‍🗨️",
left_speech_bubble: "🗨️",
right_anger_bubble: "🗯️",
thought_balloon: "💭",
zzz: "💤",
wave: "👋",
raised_back_of_hand: "🤚",
raised_hand_with_fingers_splayed: "🖐️",
hand: "",
raised_hand: "",
vulcan_salute: "🖖",
ok_hand: "👌",
pinched_fingers: "🤌",
pinching_hand: "🤏",
v: "✌️",
crossed_fingers: "🤞",
love_you_gesture: "🤟",
metal: "🤘",
call_me_hand: "🤙",
point_left: "👈",
point_right: "👉",
point_up_2: "👆",
middle_finger: "🖕",
fu: "🖕",
point_down: "👇",
point_up: "☝️",
"+1": "👍",
thumbsup: "👍",
"-1": "👎",
thumbsdown: "👎",
fist_raised: "",
fist: "",
fist_oncoming: "👊",
facepunch: "👊",
punch: "👊",
fist_left: "🤛",
fist_right: "🤜",
clap: "👏",
raised_hands: "🙌",
open_hands: "👐",
palms_up_together: "🤲",
handshake: "🤝",
pray: "🙏",
writing_hand: "✍️",
nail_care: "💅",
selfie: "🤳",
muscle: "💪",
mechanical_arm: "🦾",
mechanical_leg: "🦿",
leg: "🦵",
foot: "🦶",
ear: "👂",
ear_with_hearing_aid: "🦻",
nose: "👃",
brain: "🧠",
anatomical_heart: "🫀",
lungs: "🫁",
tooth: "🦷",
bone: "🦴",
eyes: "👀",
eye: "👁️",
tongue: "👅",
lips: "👄",
baby: "👶",
child: "🧒",
boy: "👦",
girl: "👧",
adult: "🧑",
blond_haired_person: "👱",
man: "👨",
bearded_person: "🧔",
red_haired_man: "👨‍🦰",
curly_haired_man: "👨‍🦱",
white_haired_man: "👨‍🦳",
bald_man: "👨‍🦲",
woman: "👩",
red_haired_woman: "👩‍🦰",
person_red_hair: "🧑‍🦰",
curly_haired_woman: "👩‍🦱",
person_curly_hair: "🧑‍🦱",
white_haired_woman: "👩‍🦳",
person_white_hair: "🧑‍🦳",
bald_woman: "👩‍🦲",
person_bald: "🧑‍🦲",
blond_haired_woman: "👱‍♀️",
blonde_woman: "👱‍♀️",
blond_haired_man: "👱‍♂️",
older_adult: "🧓",
older_man: "👴",
older_woman: "👵",
frowning_person: "🙍",
frowning_man: "🙍‍♂️",
frowning_woman: "🙍‍♀️",
pouting_face: "🙎",
pouting_man: "🙎‍♂️",
pouting_woman: "🙎‍♀️",
no_good: "🙅",
no_good_man: "🙅‍♂️",
ng_man: "🙅‍♂️",
no_good_woman: "🙅‍♀️",
ng_woman: "🙅‍♀️",
ok_person: "🙆",
ok_man: "🙆‍♂️",
ok_woman: "🙆‍♀️",
tipping_hand_person: "💁",
information_desk_person: "💁",
tipping_hand_man: "💁‍♂️",
sassy_man: "💁‍♂️",
tipping_hand_woman: "💁‍♀️",
sassy_woman: "💁‍♀️",
raising_hand: "🙋",
raising_hand_man: "🙋‍♂️",
raising_hand_woman: "🙋‍♀️",
deaf_person: "🧏",
deaf_man: "🧏‍♂️",
deaf_woman: "🧏‍♀️",
bow: "🙇",
bowing_man: "🙇‍♂️",
bowing_woman: "🙇‍♀️",
facepalm: "🤦",
man_facepalming: "🤦‍♂️",
woman_facepalming: "🤦‍♀️",
shrug: "🤷",
man_shrugging: "🤷‍♂️",
woman_shrugging: "🤷‍♀️",
health_worker: "🧑‍⚕️",
man_health_worker: "👨‍⚕️",
woman_health_worker: "👩‍⚕️",
student: "🧑‍🎓",
man_student: "👨‍🎓",
woman_student: "👩‍🎓",
teacher: "🧑‍🏫",
man_teacher: "👨‍🏫",
woman_teacher: "👩‍🏫",
judge: "🧑‍⚖️",
man_judge: "👨‍⚖️",
woman_judge: "👩‍⚖️",
farmer: "🧑‍🌾",
man_farmer: "👨‍🌾",
woman_farmer: "👩‍🌾",
cook: "🧑‍🍳",
man_cook: "👨‍🍳",
woman_cook: "👩‍🍳",
mechanic: "🧑‍🔧",
man_mechanic: "👨‍🔧",
woman_mechanic: "👩‍🔧",
factory_worker: "🧑‍🏭",
man_factory_worker: "👨‍🏭",
woman_factory_worker: "👩‍🏭",
office_worker: "🧑‍💼",
man_office_worker: "👨‍💼",
woman_office_worker: "👩‍💼",
scientist: "🧑‍🔬",
man_scientist: "👨‍🔬",
woman_scientist: "👩‍🔬",
technologist: "🧑‍💻",
man_technologist: "👨‍💻",
woman_technologist: "👩‍💻",
singer: "🧑‍🎤",
man_singer: "👨‍🎤",
woman_singer: "👩‍🎤",
artist: "🧑‍🎨",
man_artist: "👨‍🎨",
woman_artist: "👩‍🎨",
pilot: "🧑‍✈️",
man_pilot: "👨‍✈️",
woman_pilot: "👩‍✈️",
astronaut: "🧑‍🚀",
man_astronaut: "👨‍🚀",
woman_astronaut: "👩‍🚀",
firefighter: "🧑‍🚒",
man_firefighter: "👨‍🚒",
woman_firefighter: "👩‍🚒",
police_officer: "👮",
cop: "👮",
policeman: "👮‍♂️",
policewoman: "👮‍♀️",
detective: "🕵️",
male_detective: "🕵️‍♂️",
female_detective: "🕵️‍♀️",
guard: "💂",
guardsman: "💂‍♂️",
guardswoman: "💂‍♀️",
ninja: "🥷",
construction_worker: "👷",
construction_worker_man: "👷‍♂️",
construction_worker_woman: "👷‍♀️",
prince: "🤴",
princess: "👸",
person_with_turban: "👳",
man_with_turban: "👳‍♂️",
woman_with_turban: "👳‍♀️",
man_with_gua_pi_mao: "👲",
woman_with_headscarf: "🧕",
person_in_tuxedo: "🤵",
man_in_tuxedo: "🤵‍♂️",
woman_in_tuxedo: "🤵‍♀️",
person_with_veil: "👰",
man_with_veil: "👰‍♂️",
woman_with_veil: "👰‍♀️",
bride_with_veil: "👰‍♀️",
pregnant_woman: "🤰",
breast_feeding: "🤱",
woman_feeding_baby: "👩‍🍼",
man_feeding_baby: "👨‍🍼",
person_feeding_baby: "🧑‍🍼",
angel: "👼",
santa: "🎅",
mrs_claus: "🤶",
mx_claus: "🧑‍🎄",
superhero: "🦸",
superhero_man: "🦸‍♂️",
superhero_woman: "🦸‍♀️",
supervillain: "🦹",
supervillain_man: "🦹‍♂️",
supervillain_woman: "🦹‍♀️",
mage: "🧙",
mage_man: "🧙‍♂️",
mage_woman: "🧙‍♀️",
fairy: "🧚",
fairy_man: "🧚‍♂️",
fairy_woman: "🧚‍♀️",
vampire: "🧛",
vampire_man: "🧛‍♂️",
vampire_woman: "🧛‍♀️",
merperson: "🧜",
merman: "🧜‍♂️",
mermaid: "🧜‍♀️",
elf: "🧝",
elf_man: "🧝‍♂️",
elf_woman: "🧝‍♀️",
genie: "🧞",
genie_man: "🧞‍♂️",
genie_woman: "🧞‍♀️",
zombie: "🧟",
zombie_man: "🧟‍♂️",
zombie_woman: "🧟‍♀️",
massage: "💆",
massage_man: "💆‍♂️",
massage_woman: "💆‍♀️",
haircut: "💇",
haircut_man: "💇‍♂️",
haircut_woman: "💇‍♀️",
walking: "🚶",
walking_man: "🚶‍♂️",
walking_woman: "🚶‍♀️",
standing_person: "🧍",
standing_man: "🧍‍♂️",
standing_woman: "🧍‍♀️",
kneeling_person: "🧎",
kneeling_man: "🧎‍♂️",
kneeling_woman: "🧎‍♀️",
person_with_probing_cane: "🧑‍🦯",
man_with_probing_cane: "👨‍🦯",
woman_with_probing_cane: "👩‍🦯",
person_in_motorized_wheelchair: "🧑‍🦼",
man_in_motorized_wheelchair: "👨‍🦼",
woman_in_motorized_wheelchair: "👩‍🦼",
person_in_manual_wheelchair: "🧑‍🦽",
man_in_manual_wheelchair: "👨‍🦽",
woman_in_manual_wheelchair: "👩‍🦽",
runner: "🏃",
running: "🏃",
running_man: "🏃‍♂️",
running_woman: "🏃‍♀️",
woman_dancing: "💃",
dancer: "💃",
man_dancing: "🕺",
business_suit_levitating: "🕴️",
dancers: "👯",
dancing_men: "👯‍♂️",
dancing_women: "👯‍♀️",
sauna_person: "🧖",
sauna_man: "🧖‍♂️",
sauna_woman: "🧖‍♀️",
climbing: "🧗",
climbing_man: "🧗‍♂️",
climbing_woman: "🧗‍♀️",
person_fencing: "🤺",
horse_racing: "🏇",
skier: "⛷️",
snowboarder: "🏂",
golfing: "🏌️",
golfing_man: "🏌️‍♂️",
golfing_woman: "🏌️‍♀️",
surfer: "🏄",
surfing_man: "🏄‍♂️",
surfing_woman: "🏄‍♀️",
rowboat: "🚣",
rowing_man: "🚣‍♂️",
rowing_woman: "🚣‍♀️",
swimmer: "🏊",
swimming_man: "🏊‍♂️",
swimming_woman: "🏊‍♀️",
bouncing_ball_person: "⛹️",
bouncing_ball_man: "⛹️‍♂️",
basketball_man: "⛹️‍♂️",
bouncing_ball_woman: "⛹️‍♀️",
basketball_woman: "⛹️‍♀️",
weight_lifting: "🏋️",
weight_lifting_man: "🏋️‍♂️",
weight_lifting_woman: "🏋️‍♀️",
bicyclist: "🚴",
biking_man: "🚴‍♂️",
biking_woman: "🚴‍♀️",
mountain_bicyclist: "🚵",
mountain_biking_man: "🚵‍♂️",
mountain_biking_woman: "🚵‍♀️",
cartwheeling: "🤸",
man_cartwheeling: "🤸‍♂️",
woman_cartwheeling: "🤸‍♀️",
wrestling: "🤼",
men_wrestling: "🤼‍♂️",
women_wrestling: "🤼‍♀️",
water_polo: "🤽",
man_playing_water_polo: "🤽‍♂️",
woman_playing_water_polo: "🤽‍♀️",
handball_person: "🤾",
man_playing_handball: "🤾‍♂️",
woman_playing_handball: "🤾‍♀️",
juggling_person: "🤹",
man_juggling: "🤹‍♂️",
woman_juggling: "🤹‍♀️",
lotus_position: "🧘",
lotus_position_man: "🧘‍♂️",
lotus_position_woman: "🧘‍♀️",
bath: "🛀",
sleeping_bed: "🛌",
people_holding_hands: "🧑‍🤝‍🧑",
two_women_holding_hands: "👭",
couple: "👫",
two_men_holding_hands: "👬",
couplekiss: "💏",
couplekiss_man_woman: "👩‍❤️‍💋‍👨",
couplekiss_man_man: "👨‍❤️‍💋‍👨",
couplekiss_woman_woman: "👩‍❤️‍💋‍👩",
couple_with_heart: "💑",
couple_with_heart_woman_man: "👩‍❤️‍👨",
couple_with_heart_man_man: "👨‍❤️‍👨",
couple_with_heart_woman_woman: "👩‍❤️‍👩",
family: "👪",
family_man_woman_boy: "👨‍👩‍👦",
family_man_woman_girl: "👨‍👩‍👧",
family_man_woman_girl_boy: "👨‍👩‍👧‍👦",
family_man_woman_boy_boy: "👨‍👩‍👦‍👦",
family_man_woman_girl_girl: "👨‍👩‍👧‍👧",
family_man_man_boy: "👨‍👨‍👦",
family_man_man_girl: "👨‍👨‍👧",
family_man_man_girl_boy: "👨‍👨‍👧‍👦",
family_man_man_boy_boy: "👨‍👨‍👦‍👦",
family_man_man_girl_girl: "👨‍👨‍👧‍👧",
family_woman_woman_boy: "👩‍👩‍👦",
family_woman_woman_girl: "👩‍👩‍👧",
family_woman_woman_girl_boy: "👩‍👩‍👧‍👦",
family_woman_woman_boy_boy: "👩‍👩‍👦‍👦",
family_woman_woman_girl_girl: "👩‍👩‍👧‍👧",
family_man_boy: "👨‍👦",
family_man_boy_boy: "👨‍👦‍👦",
family_man_girl: "👨‍👧",
family_man_girl_boy: "👨‍👧‍👦",
family_man_girl_girl: "👨‍👧‍👧",
family_woman_boy: "👩‍👦",
family_woman_boy_boy: "👩‍👦‍👦",
family_woman_girl: "👩‍👧",
family_woman_girl_boy: "👩‍👧‍👦",
family_woman_girl_girl: "👩‍👧‍👧",
speaking_head: "🗣️",
bust_in_silhouette: "👤",
busts_in_silhouette: "👥",
people_hugging: "🫂",
footprints: "👣",
monkey_face: "🐵",
monkey: "🐒",
gorilla: "🦍",
orangutan: "🦧",
dog: "🐶",
dog2: "🐕",
guide_dog: "🦮",
service_dog: "🐕‍🦺",
poodle: "🐩",
wolf: "🐺",
fox_face: "🦊",
raccoon: "🦝",
cat: "🐱",
cat2: "🐈",
black_cat: "🐈‍⬛",
lion: "🦁",
tiger: "🐯",
tiger2: "🐅",
leopard: "🐆",
horse: "🐴",
racehorse: "🐎",
unicorn: "🦄",
zebra: "🦓",
deer: "🦌",
bison: "🦬",
cow: "🐮",
ox: "🐂",
water_buffalo: "🐃",
cow2: "🐄",
pig: "🐷",
pig2: "🐖",
boar: "🐗",
pig_nose: "🐽",
ram: "🐏",
sheep: "🐑",
goat: "🐐",
dromedary_camel: "🐪",
camel: "🐫",
llama: "🦙",
giraffe: "🦒",
elephant: "🐘",
mammoth: "🦣",
rhinoceros: "🦏",
hippopotamus: "🦛",
mouse: "🐭",
mouse2: "🐁",
rat: "🐀",
hamster: "🐹",
rabbit: "🐰",
rabbit2: "🐇",
chipmunk: "🐿️",
beaver: "🦫",
hedgehog: "🦔",
bat: "🦇",
bear: "🐻",
polar_bear: "🐻‍❄️",
koala: "🐨",
panda_face: "🐼",
sloth: "🦥",
otter: "🦦",
skunk: "🦨",
kangaroo: "🦘",
badger: "🦡",
feet: "🐾",
paw_prints: "🐾",
turkey: "🦃",
chicken: "🐔",
rooster: "🐓",
hatching_chick: "🐣",
baby_chick: "🐤",
hatched_chick: "🐥",
bird: "🐦",
penguin: "🐧",
dove: "🕊️",
eagle: "🦅",
duck: "🦆",
swan: "🦢",
owl: "🦉",
dodo: "🦤",
feather: "🪶",
flamingo: "🦩",
peacock: "🦚",
parrot: "🦜",
frog: "🐸",
crocodile: "🐊",
turtle: "🐢",
lizard: "🦎",
snake: "🐍",
dragon_face: "🐲",
dragon: "🐉",
sauropod: "🦕",
"t-rex": "🦖",
whale: "🐳",
whale2: "🐋",
dolphin: "🐬",
flipper: "🐬",
seal: "🦭",
fish: "🐟",
tropical_fish: "🐠",
blowfish: "🐡",
shark: "🦈",
octopus: "🐙",
shell: "🐚",
snail: "🐌",
butterfly: "🦋",
bug: "🐛",
ant: "🐜",
bee: "🐝",
honeybee: "🐝",
beetle: "🪲",
lady_beetle: "🐞",
cricket: "🦗",
cockroach: "🪳",
spider: "🕷️",
spider_web: "🕸️",
scorpion: "🦂",
mosquito: "🦟",
fly: "🪰",
worm: "🪱",
microbe: "🦠",
bouquet: "💐",
cherry_blossom: "🌸",
white_flower: "💮",
rosette: "🏵️",
rose: "🌹",
wilted_flower: "🥀",
hibiscus: "🌺",
sunflower: "🌻",
blossom: "🌼",
tulip: "🌷",
seedling: "🌱",
potted_plant: "🪴",
evergreen_tree: "🌲",
deciduous_tree: "🌳",
palm_tree: "🌴",
cactus: "🌵",
ear_of_rice: "🌾",
herb: "🌿",
shamrock: "☘️",
four_leaf_clover: "🍀",
maple_leaf: "🍁",
fallen_leaf: "🍂",
leaves: "🍃",
grapes: "🍇",
melon: "🍈",
watermelon: "🍉",
tangerine: "🍊",
orange: "🍊",
mandarin: "🍊",
lemon: "🍋",
banana: "🍌",
pineapple: "🍍",
mango: "🥭",
apple: "🍎",
green_apple: "🍏",
pear: "🍐",
peach: "🍑",
cherries: "🍒",
strawberry: "🍓",
blueberries: "🫐",
kiwi_fruit: "🥝",
tomato: "🍅",
olive: "🫒",
coconut: "🥥",
avocado: "🥑",
eggplant: "🍆",
potato: "🥔",
carrot: "🥕",
corn: "🌽",
hot_pepper: "🌶️",
bell_pepper: "🫑",
cucumber: "🥒",
leafy_green: "🥬",
broccoli: "🥦",
garlic: "🧄",
onion: "🧅",
mushroom: "🍄",
peanuts: "🥜",
chestnut: "🌰",
bread: "🍞",
croissant: "🥐",
baguette_bread: "🥖",
flatbread: "🫓",
pretzel: "🥨",
bagel: "🥯",
pancakes: "🥞",
waffle: "🧇",
cheese: "🧀",
meat_on_bone: "🍖",
poultry_leg: "🍗",
cut_of_meat: "🥩",
bacon: "🥓",
hamburger: "🍔",
fries: "🍟",
pizza: "🍕",
hotdog: "🌭",
sandwich: "🥪",
taco: "🌮",
burrito: "🌯",
tamale: "🫔",
stuffed_flatbread: "🥙",
falafel: "🧆",
egg: "🥚",
fried_egg: "🍳",
shallow_pan_of_food: "🥘",
stew: "🍲",
fondue: "🫕",
bowl_with_spoon: "🥣",
green_salad: "🥗",
popcorn: "🍿",
butter: "🧈",
salt: "🧂",
canned_food: "🥫",
bento: "🍱",
rice_cracker: "🍘",
rice_ball: "🍙",
rice: "🍚",
curry: "🍛",
ramen: "🍜",
spaghetti: "🍝",
sweet_potato: "🍠",
oden: "🍢",
sushi: "🍣",
fried_shrimp: "🍤",
fish_cake: "🍥",
moon_cake: "🥮",
dango: "🍡",
dumpling: "🥟",
fortune_cookie: "🥠",
takeout_box: "🥡",
crab: "🦀",
lobster: "🦞",
shrimp: "🦐",
squid: "🦑",
oyster: "🦪",
icecream: "🍦",
shaved_ice: "🍧",
ice_cream: "🍨",
doughnut: "🍩",
cookie: "🍪",
birthday: "🎂",
cake: "🍰",
cupcake: "🧁",
pie: "🥧",
chocolate_bar: "🍫",
candy: "🍬",
lollipop: "🍭",
custard: "🍮",
honey_pot: "🍯",
baby_bottle: "🍼",
milk_glass: "🥛",
coffee: "",
teapot: "🫖",
tea: "🍵",
sake: "🍶",
champagne: "🍾",
wine_glass: "🍷",
cocktail: "🍸",
tropical_drink: "🍹",
beer: "🍺",
beers: "🍻",
clinking_glasses: "🥂",
tumbler_glass: "🥃",
cup_with_straw: "🥤",
bubble_tea: "🧋",
beverage_box: "🧃",
mate: "🧉",
ice_cube: "🧊",
chopsticks: "🥢",
plate_with_cutlery: "🍽️",
fork_and_knife: "🍴",
spoon: "🥄",
hocho: "🔪",
knife: "🔪",
amphora: "🏺",
earth_africa: "🌍",
earth_americas: "🌎",
earth_asia: "🌏",
globe_with_meridians: "🌐",
world_map: "🗺️",
japan: "🗾",
compass: "🧭",
mountain_snow: "🏔️",
mountain: "⛰️",
volcano: "🌋",
mount_fuji: "🗻",
camping: "🏕️",
beach_umbrella: "🏖️",
desert: "🏜️",
desert_island: "🏝️",
national_park: "🏞️",
stadium: "🏟️",
classical_building: "🏛️",
building_construction: "🏗️",
bricks: "🧱",
rock: "🪨",
wood: "🪵",
hut: "🛖",
houses: "🏘️",
derelict_house: "🏚️",
house: "🏠",
house_with_garden: "🏡",
office: "🏢",
post_office: "🏣",
european_post_office: "🏤",
hospital: "🏥",
bank: "🏦",
hotel: "🏨",
love_hotel: "🏩",
convenience_store: "🏪",
school: "🏫",
department_store: "🏬",
factory: "🏭",
japanese_castle: "🏯",
european_castle: "🏰",
wedding: "💒",
tokyo_tower: "🗼",
statue_of_liberty: "🗽",
church: "",
mosque: "🕌",
hindu_temple: "🛕",
synagogue: "🕍",
shinto_shrine: "⛩️",
kaaba: "🕋",
fountain: "",
tent: "",
foggy: "🌁",
night_with_stars: "🌃",
cityscape: "🏙️",
sunrise_over_mountains: "🌄",
sunrise: "🌅",
city_sunset: "🌆",
city_sunrise: "🌇",
bridge_at_night: "🌉",
hotsprings: "♨️",
carousel_horse: "🎠",
ferris_wheel: "🎡",
roller_coaster: "🎢",
barber: "💈",
circus_tent: "🎪",
steam_locomotive: "🚂",
railway_car: "🚃",
bullettrain_side: "🚄",
bullettrain_front: "🚅",
train2: "🚆",
metro: "🚇",
light_rail: "🚈",
station: "🚉",
tram: "🚊",
monorail: "🚝",
mountain_railway: "🚞",
train: "🚋",
bus: "🚌",
oncoming_bus: "🚍",
trolleybus: "🚎",
minibus: "🚐",
ambulance: "🚑",
fire_engine: "🚒",
police_car: "🚓",
oncoming_police_car: "🚔",
taxi: "🚕",
oncoming_taxi: "🚖",
car: "🚗",
red_car: "🚗",
oncoming_automobile: "🚘",
blue_car: "🚙",
pickup_truck: "🛻",
truck: "🚚",
articulated_lorry: "🚛",
tractor: "🚜",
racing_car: "🏎️",
motorcycle: "🏍️",
motor_scooter: "🛵",
manual_wheelchair: "🦽",
motorized_wheelchair: "🦼",
auto_rickshaw: "🛺",
bike: "🚲",
kick_scooter: "🛴",
skateboard: "🛹",
roller_skate: "🛼",
busstop: "🚏",
motorway: "🛣️",
railway_track: "🛤️",
oil_drum: "🛢️",
fuelpump: "",
rotating_light: "🚨",
traffic_light: "🚥",
vertical_traffic_light: "🚦",
stop_sign: "🛑",
construction: "🚧",
anchor: "",
boat: "",
sailboat: "",
canoe: "🛶",
speedboat: "🚤",
passenger_ship: "🛳️",
ferry: "⛴️",
motor_boat: "🛥️",
ship: "🚢",
airplane: "✈️",
small_airplane: "🛩️",
flight_departure: "🛫",
flight_arrival: "🛬",
parachute: "🪂",
seat: "💺",
helicopter: "🚁",
suspension_railway: "🚟",
mountain_cableway: "🚠",
aerial_tramway: "🚡",
artificial_satellite: "🛰️",
rocket: "🚀",
flying_saucer: "🛸",
bellhop_bell: "🛎️",
luggage: "🧳",
hourglass: "",
hourglass_flowing_sand: "",
watch: "",
alarm_clock: "",
stopwatch: "⏱️",
timer_clock: "⏲️",
mantelpiece_clock: "🕰️",
clock12: "🕛",
clock1230: "🕧",
clock1: "🕐",
clock130: "🕜",
clock2: "🕑",
clock230: "🕝",
clock3: "🕒",
clock330: "🕞",
clock4: "🕓",
clock430: "🕟",
clock5: "🕔",
clock530: "🕠",
clock6: "🕕",
clock630: "🕡",
clock7: "🕖",
clock730: "🕢",
clock8: "🕗",
clock830: "🕣",
clock9: "🕘",
clock930: "🕤",
clock10: "🕙",
clock1030: "🕥",
clock11: "🕚",
clock1130: "🕦",
new_moon: "🌑",
waxing_crescent_moon: "🌒",
first_quarter_moon: "🌓",
moon: "🌔",
waxing_gibbous_moon: "🌔",
full_moon: "🌕",
waning_gibbous_moon: "🌖",
last_quarter_moon: "🌗",
waning_crescent_moon: "🌘",
crescent_moon: "🌙",
new_moon_with_face: "🌚",
first_quarter_moon_with_face: "🌛",
last_quarter_moon_with_face: "🌜",
thermometer: "🌡️",
sunny: "☀️",
full_moon_with_face: "🌝",
sun_with_face: "🌞",
ringed_planet: "🪐",
star: "",
star2: "🌟",
stars: "🌠",
milky_way: "🌌",
cloud: "☁️",
partly_sunny: "",
cloud_with_lightning_and_rain: "⛈️",
sun_behind_small_cloud: "🌤️",
sun_behind_large_cloud: "🌥️",
sun_behind_rain_cloud: "🌦️",
cloud_with_rain: "🌧️",
cloud_with_snow: "🌨️",
cloud_with_lightning: "🌩️",
tornado: "🌪️",
fog: "🌫️",
wind_face: "🌬️",
cyclone: "🌀",
rainbow: "🌈",
closed_umbrella: "🌂",
open_umbrella: "☂️",
umbrella: "",
parasol_on_ground: "⛱️",
zap: "",
snowflake: "❄️",
snowman_with_snow: "☃️",
snowman: "",
comet: "☄️",
fire: "🔥",
droplet: "💧",
ocean: "🌊",
jack_o_lantern: "🎃",
christmas_tree: "🎄",
fireworks: "🎆",
sparkler: "🎇",
firecracker: "🧨",
sparkles: "",
balloon: "🎈",
tada: "🎉",
confetti_ball: "🎊",
tanabata_tree: "🎋",
bamboo: "🎍",
dolls: "🎎",
flags: "🎏",
wind_chime: "🎐",
rice_scene: "🎑",
red_envelope: "🧧",
ribbon: "🎀",
gift: "🎁",
reminder_ribbon: "🎗️",
tickets: "🎟️",
ticket: "🎫",
medal_military: "🎖️",
trophy: "🏆",
medal_sports: "🏅",
"1st_place_medal": "🥇",
"2nd_place_medal": "🥈",
"3rd_place_medal": "🥉",
soccer: "",
baseball: "",
softball: "🥎",
basketball: "🏀",
volleyball: "🏐",
football: "🏈",
rugby_football: "🏉",
tennis: "🎾",
flying_disc: "🥏",
bowling: "🎳",
cricket_game: "🏏",
field_hockey: "🏑",
ice_hockey: "🏒",
lacrosse: "🥍",
ping_pong: "🏓",
badminton: "🏸",
boxing_glove: "🥊",
martial_arts_uniform: "🥋",
goal_net: "🥅",
golf: "",
ice_skate: "⛸️",
fishing_pole_and_fish: "🎣",
diving_mask: "🤿",
running_shirt_with_sash: "🎽",
ski: "🎿",
sled: "🛷",
curling_stone: "🥌",
dart: "🎯",
yo_yo: "🪀",
kite: "🪁",
"8ball": "🎱",
crystal_ball: "🔮",
magic_wand: "🪄",
nazar_amulet: "🧿",
video_game: "🎮",
joystick: "🕹️",
slot_machine: "🎰",
game_die: "🎲",
jigsaw: "🧩",
teddy_bear: "🧸",
pinata: "🪅",
nesting_dolls: "🪆",
spades: "♠️",
hearts: "♥️",
diamonds: "♦️",
clubs: "♣️",
chess_pawn: "♟️",
black_joker: "🃏",
mahjong: "🀄",
flower_playing_cards: "🎴",
performing_arts: "🎭",
framed_picture: "🖼️",
art: "🎨",
thread: "🧵",
sewing_needle: "🪡",
yarn: "🧶",
knot: "🪢",
eyeglasses: "👓",
dark_sunglasses: "🕶️",
goggles: "🥽",
lab_coat: "🥼",
safety_vest: "🦺",
necktie: "👔",
shirt: "👕",
tshirt: "👕",
jeans: "👖",
scarf: "🧣",
gloves: "🧤",
coat: "🧥",
socks: "🧦",
dress: "👗",
kimono: "👘",
sari: "🥻",
one_piece_swimsuit: "🩱",
swim_brief: "🩲",
shorts: "🩳",
bikini: "👙",
womans_clothes: "👚",
purse: "👛",
handbag: "👜",
pouch: "👝",
shopping: "🛍️",
school_satchel: "🎒",
thong_sandal: "🩴",
mans_shoe: "👞",
shoe: "👞",
athletic_shoe: "👟",
hiking_boot: "🥾",
flat_shoe: "🥿",
high_heel: "👠",
sandal: "👡",
ballet_shoes: "🩰",
boot: "👢",
crown: "👑",
womans_hat: "👒",
tophat: "🎩",
mortar_board: "🎓",
billed_cap: "🧢",
military_helmet: "🪖",
rescue_worker_helmet: "⛑️",
prayer_beads: "📿",
lipstick: "💄",
ring: "💍",
gem: "💎",
mute: "🔇",
speaker: "🔈",
sound: "🔉",
loud_sound: "🔊",
loudspeaker: "📢",
mega: "📣",
postal_horn: "📯",
bell: "🔔",
no_bell: "🔕",
musical_score: "🎼",
musical_note: "🎵",
notes: "🎶",
studio_microphone: "🎙️",
level_slider: "🎚️",
control_knobs: "🎛️",
microphone: "🎤",
headphones: "🎧",
radio: "📻",
saxophone: "🎷",
accordion: "🪗",
guitar: "🎸",
musical_keyboard: "🎹",
trumpet: "🎺",
violin: "🎻",
banjo: "🪕",
drum: "🥁",
long_drum: "🪘",
iphone: "📱",
calling: "📲",
phone: "☎️",
telephone: "☎️",
telephone_receiver: "📞",
pager: "📟",
fax: "📠",
battery: "🔋",
electric_plug: "🔌",
computer: "💻",
desktop_computer: "🖥️",
printer: "🖨️",
keyboard: "⌨️",
computer_mouse: "🖱️",
trackball: "🖲️",
minidisc: "💽",
floppy_disk: "💾",
cd: "💿",
dvd: "📀",
abacus: "🧮",
movie_camera: "🎥",
film_strip: "🎞️",
film_projector: "📽️",
clapper: "🎬",
tv: "📺",
camera: "📷",
camera_flash: "📸",
video_camera: "📹",
vhs: "📼",
mag: "🔍",
mag_right: "🔎",
candle: "🕯️",
bulb: "💡",
flashlight: "🔦",
izakaya_lantern: "🏮",
lantern: "🏮",
diya_lamp: "🪔",
notebook_with_decorative_cover: "📔",
closed_book: "📕",
book: "📖",
open_book: "📖",
green_book: "📗",
blue_book: "📘",
orange_book: "📙",
books: "📚",
notebook: "📓",
ledger: "📒",
page_with_curl: "📃",
scroll: "📜",
page_facing_up: "📄",
newspaper: "📰",
newspaper_roll: "🗞️",
bookmark_tabs: "📑",
bookmark: "🔖",
label: "🏷️",
moneybag: "💰",
coin: "🪙",
yen: "💴",
dollar: "💵",
euro: "💶",
pound: "💷",
money_with_wings: "💸",
credit_card: "💳",
receipt: "🧾",
chart: "💹",
envelope: "✉️",
email: "📧",
"e-mail": "📧",
incoming_envelope: "📨",
envelope_with_arrow: "📩",
outbox_tray: "📤",
inbox_tray: "📥",
package: "📦",
mailbox: "📫",
mailbox_closed: "📪",
mailbox_with_mail: "📬",
mailbox_with_no_mail: "📭",
postbox: "📮",
ballot_box: "🗳️",
pencil2: "✏️",
black_nib: "✒️",
fountain_pen: "🖋️",
pen: "🖊️",
paintbrush: "🖌️",
crayon: "🖍️",
memo: "📝",
pencil: "📝",
briefcase: "💼",
file_folder: "📁",
open_file_folder: "📂",
card_index_dividers: "🗂️",
date: "📅",
calendar: "📆",
spiral_notepad: "🗒️",
spiral_calendar: "🗓️",
card_index: "📇",
chart_with_upwards_trend: "📈",
chart_with_downwards_trend: "📉",
bar_chart: "📊",
clipboard: "📋",
pushpin: "📌",
round_pushpin: "📍",
paperclip: "📎",
paperclips: "🖇️",
straight_ruler: "📏",
triangular_ruler: "📐",
scissors: "✂️",
card_file_box: "🗃️",
file_cabinet: "🗄️",
wastebasket: "🗑️",
lock: "🔒",
unlock: "🔓",
lock_with_ink_pen: "🔏",
closed_lock_with_key: "🔐",
key: "🔑",
old_key: "🗝️",
hammer: "🔨",
axe: "🪓",
pick: "⛏️",
hammer_and_pick: "⚒️",
hammer_and_wrench: "🛠️",
dagger: "🗡️",
crossed_swords: "⚔️",
gun: "🔫",
boomerang: "🪃",
bow_and_arrow: "🏹",
shield: "🛡️",
carpentry_saw: "🪚",
wrench: "🔧",
screwdriver: "🪛",
nut_and_bolt: "🔩",
gear: "⚙️",
clamp: "🗜️",
balance_scale: "⚖️",
probing_cane: "🦯",
link: "🔗",
chains: "⛓️",
hook: "🪝",
toolbox: "🧰",
magnet: "🧲",
ladder: "🪜",
alembic: "⚗️",
test_tube: "🧪",
petri_dish: "🧫",
dna: "🧬",
microscope: "🔬",
telescope: "🔭",
satellite: "📡",
syringe: "💉",
drop_of_blood: "🩸",
pill: "💊",
adhesive_bandage: "🩹",
stethoscope: "🩺",
door: "🚪",
elevator: "🛗",
mirror: "🪞",
window: "🪟",
bed: "🛏️",
couch_and_lamp: "🛋️",
chair: "🪑",
toilet: "🚽",
plunger: "🪠",
shower: "🚿",
bathtub: "🛁",
mouse_trap: "🪤",
razor: "🪒",
lotion_bottle: "🧴",
safety_pin: "🧷",
broom: "🧹",
basket: "🧺",
roll_of_paper: "🧻",
bucket: "🪣",
soap: "🧼",
toothbrush: "🪥",
sponge: "🧽",
fire_extinguisher: "🧯",
shopping_cart: "🛒",
smoking: "🚬",
coffin: "⚰️",
headstone: "🪦",
funeral_urn: "⚱️",
moyai: "🗿",
placard: "🪧",
atm: "🏧",
put_litter_in_its_place: "🚮",
potable_water: "🚰",
wheelchair: "",
mens: "🚹",
womens: "🚺",
restroom: "🚻",
baby_symbol: "🚼",
wc: "🚾",
passport_control: "🛂",
customs: "🛃",
baggage_claim: "🛄",
left_luggage: "🛅",
warning: "⚠️",
children_crossing: "🚸",
no_entry: "",
no_entry_sign: "🚫",
no_bicycles: "🚳",
no_smoking: "🚭",
do_not_litter: "🚯",
"non-potable_water": "🚱",
no_pedestrians: "🚷",
no_mobile_phones: "📵",
underage: "🔞",
radioactive: "☢️",
biohazard: "☣️",
arrow_up: "⬆️",
arrow_upper_right: "↗️",
arrow_right: "➡️",
arrow_lower_right: "↘️",
arrow_down: "⬇️",
arrow_lower_left: "↙️",
arrow_left: "⬅️",
arrow_upper_left: "↖️",
arrow_up_down: "↕️",
left_right_arrow: "↔️",
leftwards_arrow_with_hook: "↩️",
arrow_right_hook: "↪️",
arrow_heading_up: "⤴️",
arrow_heading_down: "⤵️",
arrows_clockwise: "🔃",
arrows_counterclockwise: "🔄",
back: "🔙",
end: "🔚",
on: "🔛",
soon: "🔜",
top: "🔝",
place_of_worship: "🛐",
atom_symbol: "⚛️",
om: "🕉️",
star_of_david: "✡️",
wheel_of_dharma: "☸️",
yin_yang: "☯️",
latin_cross: "✝️",
orthodox_cross: "☦️",
star_and_crescent: "☪️",
peace_symbol: "☮️",
menorah: "🕎",
six_pointed_star: "🔯",
aries: "",
taurus: "",
gemini: "",
cancer: "",
leo: "",
virgo: "",
libra: "",
scorpius: "",
sagittarius: "",
capricorn: "",
aquarius: "",
pisces: "",
ophiuchus: "",
twisted_rightwards_arrows: "🔀",
repeat: "🔁",
repeat_one: "🔂",
arrow_forward: "▶️",
fast_forward: "",
next_track_button: "⏭️",
play_or_pause_button: "⏯️",
arrow_backward: "◀️",
rewind: "",
previous_track_button: "⏮️",
arrow_up_small: "🔼",
arrow_double_up: "",
arrow_down_small: "🔽",
arrow_double_down: "",
pause_button: "⏸️",
stop_button: "⏹️",
record_button: "⏺️",
eject_button: "⏏️",
cinema: "🎦",
low_brightness: "🔅",
high_brightness: "🔆",
signal_strength: "📶",
vibration_mode: "📳",
mobile_phone_off: "📴",
female_sign: "♀️",
male_sign: "♂️",
transgender_symbol: "⚧️",
heavy_multiplication_x: "✖️",
heavy_plus_sign: "",
heavy_minus_sign: "",
heavy_division_sign: "",
infinity: "♾️",
bangbang: "‼️",
interrobang: "⁉️",
question: "",
grey_question: "",
grey_exclamation: "",
exclamation: "",
heavy_exclamation_mark: "",
wavy_dash: "〰️",
currency_exchange: "💱",
heavy_dollar_sign: "💲",
medical_symbol: "⚕️",
recycle: "♻️",
fleur_de_lis: "⚜️",
trident: "🔱",
name_badge: "📛",
beginner: "🔰",
o: "",
white_check_mark: "",
ballot_box_with_check: "☑️",
heavy_check_mark: "✔️",
x: "",
negative_squared_cross_mark: "",
curly_loop: "",
loop: "",
part_alternation_mark: "〽️",
eight_spoked_asterisk: "✳️",
eight_pointed_black_star: "✴️",
sparkle: "❇️",
copyright: "©️",
registered: "®️",
tm: "™️",
hash: "#️⃣",
asterisk: "*️⃣",
zero: "0️⃣",
one: "1️⃣",
two: "2️⃣",
three: "3️⃣",
four: "4️⃣",
five: "5️⃣",
six: "6️⃣",
seven: "7️⃣",
eight: "8️⃣",
nine: "9️⃣",
keycap_ten: "🔟",
capital_abcd: "🔠",
abcd: "🔡",
symbols: "🔣",
abc: "🔤",
a: "🅰️",
ab: "🆎",
b: "🅱️",
cl: "🆑",
cool: "🆒",
free: "🆓",
information_source: "ℹ️",
id: "🆔",
m: "Ⓜ️",
new: "🆕",
ng: "🆖",
o2: "🅾️",
ok: "🆗",
parking: "🅿️",
sos: "🆘",
up: "🆙",
vs: "🆚",
koko: "🈁",
sa: "🈂️",
u6708: "🈷️",
u6709: "🈶",
u6307: "🈯",
ideograph_advantage: "🉐",
u5272: "🈹",
u7121: "🈚",
u7981: "🈲",
accept: "🉑",
u7533: "🈸",
u5408: "🈴",
u7a7a: "🈳",
congratulations: "㊗️",
secret: "㊙️",
u55b6: "🈺",
u6e80: "🈵",
red_circle: "🔴",
orange_circle: "🟠",
yellow_circle: "🟡",
green_circle: "🟢",
large_blue_circle: "🔵",
purple_circle: "🟣",
brown_circle: "🟤",
black_circle: "",
white_circle: "",
red_square: "🟥",
orange_square: "🟧",
yellow_square: "🟨",
green_square: "🟩",
blue_square: "🟦",
purple_square: "🟪",
brown_square: "🟫",
black_large_square: "",
white_large_square: "",
black_medium_square: "◼️",
white_medium_square: "◻️",
black_medium_small_square: "",
white_medium_small_square: "",
black_small_square: "▪️",
white_small_square: "▫️",
large_orange_diamond: "🔶",
large_blue_diamond: "🔷",
small_orange_diamond: "🔸",
small_blue_diamond: "🔹",
small_red_triangle: "🔺",
small_red_triangle_down: "🔻",
diamond_shape_with_a_dot_inside: "💠",
radio_button: "🔘",
white_square_button: "🔳",
black_square_button: "🔲",
checkered_flag: "🏁",
triangular_flag_on_post: "🚩",
crossed_flags: "🎌",
black_flag: "🏴",
white_flag: "🏳️",
rainbow_flag: "🏳️‍🌈",
transgender_flag: "🏳️‍⚧️",
pirate_flag: "🏴‍☠️",
ascension_island: "🇦🇨",
andorra: "🇦🇩",
united_arab_emirates: "🇦🇪",
afghanistan: "🇦🇫",
antigua_barbuda: "🇦🇬",
anguilla: "🇦🇮",
albania: "🇦🇱",
armenia: "🇦🇲",
angola: "🇦🇴",
antarctica: "🇦🇶",
argentina: "🇦🇷",
american_samoa: "🇦🇸",
austria: "🇦🇹",
australia: "🇦🇺",
aruba: "🇦🇼",
aland_islands: "🇦🇽",
azerbaijan: "🇦🇿",
bosnia_herzegovina: "🇧🇦",
barbados: "🇧🇧",
bangladesh: "🇧🇩",
belgium: "🇧🇪",
burkina_faso: "🇧🇫",
bulgaria: "🇧🇬",
bahrain: "🇧🇭",
burundi: "🇧🇮",
benin: "🇧🇯",
st_barthelemy: "🇧🇱",
bermuda: "🇧🇲",
brunei: "🇧🇳",
bolivia: "🇧🇴",
caribbean_netherlands: "🇧🇶",
brazil: "🇧🇷",
bahamas: "🇧🇸",
bhutan: "🇧🇹",
bouvet_island: "🇧🇻",
botswana: "🇧🇼",
belarus: "🇧🇾",
belize: "🇧🇿",
canada: "🇨🇦",
cocos_islands: "🇨🇨",
congo_kinshasa: "🇨🇩",
central_african_republic: "🇨🇫",
congo_brazzaville: "🇨🇬",
switzerland: "🇨🇭",
cote_divoire: "🇨🇮",
cook_islands: "🇨🇰",
chile: "🇨🇱",
cameroon: "🇨🇲",
cn: "🇨🇳",
colombia: "🇨🇴",
clipperton_island: "🇨🇵",
costa_rica: "🇨🇷",
cuba: "🇨🇺",
cape_verde: "🇨🇻",
curacao: "🇨🇼",
christmas_island: "🇨🇽",
cyprus: "🇨🇾",
czech_republic: "🇨🇿",
de: "🇩🇪",
diego_garcia: "🇩🇬",
djibouti: "🇩🇯",
denmark: "🇩🇰",
dominica: "🇩🇲",
dominican_republic: "🇩🇴",
algeria: "🇩🇿",
ceuta_melilla: "🇪🇦",
ecuador: "🇪🇨",
estonia: "🇪🇪",
egypt: "🇪🇬",
western_sahara: "🇪🇭",
eritrea: "🇪🇷",
es: "🇪🇸",
ethiopia: "🇪🇹",
eu: "🇪🇺",
european_union: "🇪🇺",
finland: "🇫🇮",
fiji: "🇫🇯",
falkland_islands: "🇫🇰",
micronesia: "🇫🇲",
faroe_islands: "🇫🇴",
fr: "🇫🇷",
gabon: "🇬🇦",
gb: "🇬🇧",
uk: "🇬🇧",
grenada: "🇬🇩",
georgia: "🇬🇪",
french_guiana: "🇬🇫",
guernsey: "🇬🇬",
ghana: "🇬🇭",
gibraltar: "🇬🇮",
greenland: "🇬🇱",
gambia: "🇬🇲",
guinea: "🇬🇳",
guadeloupe: "🇬🇵",
equatorial_guinea: "🇬🇶",
greece: "🇬🇷",
south_georgia_south_sandwich_islands: "🇬🇸",
guatemala: "🇬🇹",
guam: "🇬🇺",
guinea_bissau: "🇬🇼",
guyana: "🇬🇾",
hong_kong: "🇭🇰",
heard_mcdonald_islands: "🇭🇲",
honduras: "🇭🇳",
croatia: "🇭🇷",
haiti: "🇭🇹",
hungary: "🇭🇺",
canary_islands: "🇮🇨",
indonesia: "🇮🇩",
ireland: "🇮🇪",
israel: "🇮🇱",
isle_of_man: "🇮🇲",
india: "🇮🇳",
british_indian_ocean_territory: "🇮🇴",
iraq: "🇮🇶",
iran: "🇮🇷",
iceland: "🇮🇸",
it: "🇮🇹",
jersey: "🇯🇪",
jamaica: "🇯🇲",
jordan: "🇯🇴",
jp: "🇯🇵",
kenya: "🇰🇪",
kyrgyzstan: "🇰🇬",
cambodia: "🇰🇭",
kiribati: "🇰🇮",
comoros: "🇰🇲",
st_kitts_nevis: "🇰🇳",
north_korea: "🇰🇵",
kr: "🇰🇷",
kuwait: "🇰🇼",
cayman_islands: "🇰🇾",
kazakhstan: "🇰🇿",
laos: "🇱🇦",
lebanon: "🇱🇧",
st_lucia: "🇱🇨",
liechtenstein: "🇱🇮",
sri_lanka: "🇱🇰",
liberia: "🇱🇷",
lesotho: "🇱🇸",
lithuania: "🇱🇹",
luxembourg: "🇱🇺",
latvia: "🇱🇻",
libya: "🇱🇾",
morocco: "🇲🇦",
monaco: "🇲🇨",
moldova: "🇲🇩",
montenegro: "🇲🇪",
st_martin: "🇲🇫",
madagascar: "🇲🇬",
marshall_islands: "🇲🇭",
macedonia: "🇲🇰",
mali: "🇲🇱",
myanmar: "🇲🇲",
mongolia: "🇲🇳",
macau: "🇲🇴",
northern_mariana_islands: "🇲🇵",
martinique: "🇲🇶",
mauritania: "🇲🇷",
montserrat: "🇲🇸",
malta: "🇲🇹",
mauritius: "🇲🇺",
maldives: "🇲🇻",
malawi: "🇲🇼",
mexico: "🇲🇽",
malaysia: "🇲🇾",
mozambique: "🇲🇿",
namibia: "🇳🇦",
new_caledonia: "🇳🇨",
niger: "🇳🇪",
norfolk_island: "🇳🇫",
nigeria: "🇳🇬",
nicaragua: "🇳🇮",
netherlands: "🇳🇱",
norway: "🇳🇴",
nepal: "🇳🇵",
nauru: "🇳🇷",
niue: "🇳🇺",
new_zealand: "🇳🇿",
oman: "🇴🇲",
panama: "🇵🇦",
peru: "🇵🇪",
french_polynesia: "🇵🇫",
papua_new_guinea: "🇵🇬",
philippines: "🇵🇭",
pakistan: "🇵🇰",
poland: "🇵🇱",
st_pierre_miquelon: "🇵🇲",
pitcairn_islands: "🇵🇳",
puerto_rico: "🇵🇷",
palestinian_territories: "🇵🇸",
portugal: "🇵🇹",
palau: "🇵🇼",
paraguay: "🇵🇾",
qatar: "🇶🇦",
reunion: "🇷🇪",
romania: "🇷🇴",
serbia: "🇷🇸",
ru: "🇷🇺",
rwanda: "🇷🇼",
saudi_arabia: "🇸🇦",
solomon_islands: "🇸🇧",
seychelles: "🇸🇨",
sudan: "🇸🇩",
sweden: "🇸🇪",
singapore: "🇸🇬",
st_helena: "🇸🇭",
slovenia: "🇸🇮",
svalbard_jan_mayen: "🇸🇯",
slovakia: "🇸🇰",
sierra_leone: "🇸🇱",
san_marino: "🇸🇲",
senegal: "🇸🇳",
somalia: "🇸🇴",
suriname: "🇸🇷",
south_sudan: "🇸🇸",
sao_tome_principe: "🇸🇹",
el_salvador: "🇸🇻",
sint_maarten: "🇸🇽",
syria: "🇸🇾",
swaziland: "🇸🇿",
tristan_da_cunha: "🇹🇦",
turks_caicos_islands: "🇹🇨",
chad: "🇹🇩",
french_southern_territories: "🇹🇫",
togo: "🇹🇬",
thailand: "🇹🇭",
tajikistan: "🇹🇯",
tokelau: "🇹🇰",
timor_leste: "🇹🇱",
turkmenistan: "🇹🇲",
tunisia: "🇹🇳",
tonga: "🇹🇴",
tr: "🇹🇷",
trinidad_tobago: "🇹🇹",
tuvalu: "🇹🇻",
taiwan: "🇹🇼",
tanzania: "🇹🇿",
ukraine: "🇺🇦",
uganda: "🇺🇬",
us_outlying_islands: "🇺🇲",
united_nations: "🇺🇳",
us: "🇺🇸",
uruguay: "🇺🇾",
uzbekistan: "🇺🇿",
vatican_city: "🇻🇦",
st_vincent_grenadines: "🇻🇨",
venezuela: "🇻🇪",
british_virgin_islands: "🇻🇬",
us_virgin_islands: "🇻🇮",
vietnam: "🇻🇳",
vanuatu: "🇻🇺",
wallis_futuna: "🇼🇫",
samoa: "🇼🇸",
kosovo: "🇽🇰",
yemen: "🇾🇪",
mayotte: "🇾🇹",
south_africa: "🇿🇦",
zambia: "🇿🇲",
zimbabwe: "🇿🇼",
england: "🏴󠁧󠁢󠁥󠁮󠁧󠁿",
scotland: "🏴󠁧󠁢󠁳󠁣󠁴󠁿",
wales: "🏴󠁧󠁢󠁷󠁬󠁳󠁿",
};
import message from './message.mp3'; import call_join from "./call_join.mp3";
import outbound from './outbound.mp3'; import call_leave from "./call_leave.mp3";
import call_join from './call_join.mp3'; import message from "./message.mp3";
import call_leave from './call_leave.mp3'; import outbound from "./outbound.mp3";
const SoundMap: { [key in Sounds]: string } = { const SoundMap: { [key in Sounds]: string } = {
message, message,
outbound, outbound,
call_join, call_join,
call_leave call_leave,
} };
export type Sounds = 'message' | 'outbound' | 'call_join' | 'call_leave'; export type Sounds = "message" | "outbound" | "call_join" | "call_leave";
export const SOUNDS_ARRAY: Sounds[] = [ 'message', 'outbound', 'call_join', 'call_leave' ]; export const SOUNDS_ARRAY: Sounds[] = [
"message",
"outbound",
"call_join",
"call_leave",
];
export function playSound(sound: Sounds) { export function playSound(sound: Sounds) {
let file = SoundMap[sound]; const file = SoundMap[sound];
let el = new Audio(file); const el = new Audio(file);
try { try {
el.play(); el.play();
} catch (err) { } catch (err) {
console.error('Failed to play audio file', file, err); console.error("Failed to play audio file", file, err);
} }
} }
import { observer } from "mobx-react-lite";
import { useHistory } from "react-router-dom";
import { Channel } from "revolt.js/dist/maps/Channels";
import styled from "styled-components";
import { Text } from "preact-i18n";
import { useState } from "preact/hooks";
import { dispatch, getState } from "../../redux";
import Button from "../ui/Button";
import Checkbox from "../ui/Checkbox";
import { Children } from "../../types/Preact";
const Base = styled.div`
display: flex;
flex-grow: 1;
flex-direction: column;
align-items: center;
justify-content: center;
user-select: none;
padding: 12px;
img {
height: 150px;
}
.subtext {
color: var(--secondary-foreground);
margin-bottom: 12px;
font-size: 14px;
}
.actions {
margin-top: 20px;
display: flex;
gap: 12px;
}
`;
type Props = {
gated: boolean;
children: Children;
} & {
type: "channel";
channel: Channel;
};
export default observer((props: Props) => {
const history = useHistory();
const [consent, setConsent] = useState(
getState().sectionToggle["nsfw"] ?? false,
);
const [ageGate, setAgeGate] = useState(false);
if (ageGate || !props.gated) {
return <>{props.children}</>;
}
if (
!(
props.channel.channel_type === "Group" ||
props.channel.channel_type === "TextChannel"
)
)
return <>{props.children}</>;
return (
<Base>
<img
loading="eager"
src={"https://static.revolt.chat/emoji/mutant/26a0.svg"}
draggable={false}
/>
<h2>{props.channel.name}</h2>
<span className="subtext">
<Text id={`app.main.channel.nsfw.${props.type}.marked`} />{" "}
<a href="#">
<Text id={`app.main.channel.nsfw.learn_more`} />
</a>
</span>
<Checkbox
checked={consent}
onChange={(v) => {
setConsent(v);
if (v) {
dispatch({
type: "SECTION_TOGGLE_SET",
id: "nsfw",
state: true,
});
} else {
dispatch({ type: "SECTION_TOGGLE_UNSET", id: "nsfw" });
}
}}>
<Text id="app.main.channel.nsfw.confirm" />
</Checkbox>
<div className="actions">
<Button contrast onClick={() => history.goBack()}>
<Text id="app.special.modals.actions.back" />
</Button>
<Button contrast onClick={() => consent && setAgeGate(true)}>
<Text id={`app.main.channel.nsfw.${props.type}.confirm`} />
</Button>
</div>
</Base>
);
});
import { StateUpdater, useContext, useState } from "preact/hooks"; import { SYSTEM_USER_ID } from "revolt.js";
import { AppContext } from "../../context/revoltjs/RevoltClient"; import { Channel } from "revolt.js/dist/maps/Channels";
import { Channels } from "revolt.js/dist/api/objects"; import { User } from "revolt.js/dist/maps/Users";
import { emojiDictionary } from "../../assets/emojis";
import { SYSTEM_USER_ID, User } from "revolt.js";
import UserIcon from "./user/UserIcon";
import styled, { css } from "styled-components"; import styled, { css } from "styled-components";
import Emoji from "./Emoji";
import { StateUpdater, useState } from "preact/hooks";
import { useClient } from "../../context/revoltjs/RevoltClient";
import { emojiDictionary } from "../../assets/emojis";
import ChannelIcon from "./ChannelIcon"; import ChannelIcon from "./ChannelIcon";
import Emoji from "./Emoji";
import UserIcon from "./user/UserIcon";
export type AutoCompleteState = export type AutoCompleteState =
| { type: "none" } | { type: "none" }
| ({ selected: number; within: boolean; } & ( | ({ selected: number; within: boolean } & (
{ | {
type: "emoji"; type: "emoji";
matches: string[]; matches: string[];
} | }
{ | {
type: "user"; type: "user";
matches: User[]; matches: User[];
} | }
{ | {
type: "channel"; type: "channel";
matches: Channels.TextChannel[]; matches: Channel[];
} }
)); ));
export type SearchClues = { export type SearchClues = {
users?: { type: 'channel', id: string } | { type: 'all' }, users?: { type: "channel"; id: string } | { type: "all" };
channels?: { server: string } channels?: { server: string };
}; };
export type AutoCompleteProps = { export type AutoCompleteProps = {
detached?: boolean, detached?: boolean;
state: AutoCompleteState, state: AutoCompleteState;
setState: StateUpdater<AutoCompleteState>, setState: StateUpdater<AutoCompleteState>;
onKeyUp: (ev: KeyboardEvent) => void, onKeyUp: (ev: KeyboardEvent) => void;
onKeyDown: (ev: KeyboardEvent) => boolean, onKeyDown: (ev: KeyboardEvent) => boolean;
onChange: (ev: JSX.TargetedEvent<HTMLTextAreaElement, Event>) => void, onChange: (ev: JSX.TargetedEvent<HTMLTextAreaElement, Event>) => void;
onClick: JSX.MouseEventHandler<HTMLButtonElement>, onClick: JSX.MouseEventHandler<HTMLButtonElement>;
onFocus: JSX.FocusEventHandler<HTMLTextAreaElement>, onFocus: JSX.FocusEventHandler<HTMLTextAreaElement>;
onBlur: JSX.FocusEventHandler<HTMLTextAreaElement> onBlur: JSX.FocusEventHandler<HTMLTextAreaElement>;
} };
export function useAutoComplete(setValue: (v?: string) => void, searchClues?: SearchClues): AutoCompleteProps { export function useAutoComplete(
const [state, setState] = useState<AutoCompleteState>({ type: 'none' }); setValue: (v?: string) => void,
searchClues?: SearchClues,
): AutoCompleteProps {
const [state, setState] = useState<AutoCompleteState>({ type: "none" });
const [focused, setFocused] = useState(false); const [focused, setFocused] = useState(false);
const client = useContext(AppContext); const client = useClient();
function findSearchString( function findSearchString(
el: HTMLTextAreaElement el: HTMLTextAreaElement,
): ["emoji" | "user" | "channel", string, number] | undefined { ): ["emoji" | "user" | "channel", string, number] | undefined {
if (el.selectionStart === el.selectionEnd) { if (el.selectionStart === el.selectionEnd) {
let cursor = el.selectionStart; const cursor = el.selectionStart;
let content = el.value.slice(0, cursor); const content = el.value.slice(0, cursor);
let valid = /\w/; const valid = /\w/;
let j = content.length - 1; let j = content.length - 1;
if (content[j] === '@') { if (content[j] === "@") {
return [ return ["user", "", j];
"user", } else if (content[j] === "#") {
"", return ["channel", "", j];
j
];
} else if (content[j] === '#') {
return [
"channel",
"",
j
];
} }
while (j >= 0 && valid.test(content[j])) { while (j >= 0 && valid.test(content[j])) {
...@@ -77,47 +76,48 @@ export function useAutoComplete(setValue: (v?: string) => void, searchClues?: Se ...@@ -77,47 +76,48 @@ export function useAutoComplete(setValue: (v?: string) => void, searchClues?: Se
} }
if (j === -1) return; if (j === -1) return;
let current = content[j]; const current = content[j];
if (current === ":" || current === "@" || current === "#") { if (current === ":" || current === "@" || current === "#") {
let search = content.slice(j + 1, content.length); const search = content.slice(j + 1, content.length);
if (search.length > 0) { if (search.length > 0) {
return [ return [
current === "#" ? "channel" : current === "#"
current === ":" ? "emoji" : "user", ? "channel"
: current === ":"
? "emoji"
: "user",
search.toLowerCase(), search.toLowerCase(),
j + 1 j + 1,
]; ];
} }
} }
} }
} }
function onChange(ev: JSX.TargetedEvent<HTMLTextAreaElement, Event>) { function onChange(ev: JSX.TargetedEvent<HTMLTextAreaElement, Event>) {
const el = ev.currentTarget; const el = ev.currentTarget;
let result = findSearchString(el); const result = findSearchString(el);
if (result) { if (result) {
let [type, search] = result; const [type, search] = result;
const regex = new RegExp(search, 'i'); const regex = new RegExp(search, "i");
if (type === "emoji") { if (type === "emoji") {
// ! FIXME: we should convert it to a Binary Search Tree and use that // ! TODO: we should convert it to a Binary Search Tree and use that
let matches = Object.keys(emojiDictionary) const matches = Object.keys(emojiDictionary)
.filter((emoji: string) => emoji.match(regex)) .filter((emoji: string) => emoji.match(regex))
.splice(0, 5); .splice(0, 5);
if (matches.length > 0) { if (matches.length > 0) {
let currentPosition = const currentPosition =
state.type !== "none" state.type !== "none" ? state.selected : 0;
? state.selected
: 0;
setState({ setState({
type: "emoji", type: "emoji",
matches, matches,
selected: Math.min(currentPosition, matches.length - 1), selected: Math.min(currentPosition, matches.length - 1),
within: false within: false,
}); });
return; return;
...@@ -127,71 +127,91 @@ export function useAutoComplete(setValue: (v?: string) => void, searchClues?: Se ...@@ -127,71 +127,91 @@ export function useAutoComplete(setValue: (v?: string) => void, searchClues?: Se
if (type === "user" && searchClues?.users) { if (type === "user" && searchClues?.users) {
let users: User[] = []; let users: User[] = [];
switch (searchClues.users.type) { switch (searchClues.users.type) {
case 'all': users = client.users.toArray(); break; case "all":
case 'channel': { users = [...client.users.values()];
let channel = client.channels.get(searchClues.users.id); break;
case "channel": {
const channel = client.channels.get(
searchClues.users.id,
);
switch (channel?.channel_type) { switch (channel?.channel_type) {
case 'Group': case "Group":
case 'DirectMessage': case "DirectMessage":
users = client.users.mapKeys(channel.recipients) users = channel.recipients!.filter(
.filter(x => typeof x !== 'undefined') as User[]; (x) => typeof x !== "undefined",
) as User[];
break; break;
case 'TextChannel': case "TextChannel":
const server = channel.server; {
users = client.servers.members.toArray() const server = channel.server_id;
.filter(x => x._id.substr(0, 26) === server) users = [...client.members.keys()]
.map(x => client.users.get(x._id.substr(26))) .map((x) => JSON.parse(x))
.filter(x => typeof x !== 'undefined') as User[]; .filter((x) => x.server === server)
.map((x) => client.users.get(x.user))
.filter(
(x) => typeof x !== "undefined",
) as User[];
}
break; break;
default: return; default:
return;
} }
} }
} }
users = users.filter(x => x._id !== SYSTEM_USER_ID); users = users.filter((x) => x._id !== SYSTEM_USER_ID);
let matches = (search.length > 0 ? users.filter(user => user.username.toLowerCase().match(regex)) : users) const matches = (
search.length > 0
? users.filter((user) =>
user.username.toLowerCase().match(regex),
)
: users
)
.splice(0, 5) .splice(0, 5)
.filter(x => typeof x !== "undefined"); .filter((x) => typeof x !== "undefined");
if (matches.length > 0) { if (matches.length > 0) {
let currentPosition = const currentPosition =
state.type !== "none" state.type !== "none" ? state.selected : 0;
? state.selected
: 0;
setState({ setState({
type: "user", type: "user",
matches, matches,
selected: Math.min(currentPosition, matches.length - 1), selected: Math.min(currentPosition, matches.length - 1),
within: false within: false,
}); });
return; return;
} }
} }
if (type === 'channel' && searchClues?.channels) { if (type === "channel" && searchClues?.channels) {
let channels = client.servers.get(searchClues.channels.server) const channels = client.servers
?.channels .get(searchClues.channels.server)
.map(x => client.channels.get(x)) ?.channels.filter(
.filter(x => typeof x !== 'undefined') as Channels.TextChannel[]; (x) => typeof x !== "undefined",
) as Channel[];
let matches = (search.length > 0 ? channels.filter(channel => channel.name.toLowerCase().match(regex)) : channels)
const matches = (
search.length > 0
? channels.filter((channel) =>
channel.name!.toLowerCase().match(regex),
)
: channels
)
.splice(0, 5) .splice(0, 5)
.filter(x => typeof x !== "undefined"); .filter((x) => typeof x !== "undefined");
if (matches.length > 0) { if (matches.length > 0) {
let currentPosition = const currentPosition =
state.type !== "none" state.type !== "none" ? state.selected : 0;
? state.selected
: 0;
setState({ setState({
type: "channel", type: "channel",
matches, matches,
selected: Math.min(currentPosition, matches.length - 1), selected: Math.min(currentPosition, matches.length - 1),
within: false within: false,
}); });
return; return;
...@@ -206,25 +226,25 @@ export function useAutoComplete(setValue: (v?: string) => void, searchClues?: Se ...@@ -206,25 +226,25 @@ export function useAutoComplete(setValue: (v?: string) => void, searchClues?: Se
function selectCurrent(el: HTMLTextAreaElement) { function selectCurrent(el: HTMLTextAreaElement) {
if (state.type !== "none") { if (state.type !== "none") {
let result = findSearchString(el); const result = findSearchString(el);
if (result) { if (result) {
let [_type, search, index] = result; const [_type, search, index] = result;
let content = el.value.split(""); const content = el.value.split("");
if (state.type === "emoji") { if (state.type === "emoji") {
content.splice( content.splice(
index, index,
search.length, search.length,
state.matches[state.selected], state.matches[state.selected],
": " ": ",
); );
} else if (state.type === 'user') { } else if (state.type === "user") {
content.splice( content.splice(
index - 1, index - 1,
search.length + 1, search.length + 1,
"<@", "<@",
state.matches[state.selected]._id, state.matches[state.selected]._id,
"> " "> ",
); );
} else { } else {
content.splice( content.splice(
...@@ -232,7 +252,7 @@ export function useAutoComplete(setValue: (v?: string) => void, searchClues?: Se ...@@ -232,7 +252,7 @@ export function useAutoComplete(setValue: (v?: string) => void, searchClues?: Se
search.length + 1, search.length + 1,
"<#", "<#",
state.matches[state.selected]._id, state.matches[state.selected]._id,
"> " "> ",
); );
} }
...@@ -247,13 +267,13 @@ export function useAutoComplete(setValue: (v?: string) => void, searchClues?: Se ...@@ -247,13 +267,13 @@ export function useAutoComplete(setValue: (v?: string) => void, searchClues?: Se
} }
function onKeyDown(e: KeyboardEvent) { function onKeyDown(e: KeyboardEvent) {
if (focused && state.type !== 'none') { if (focused && state.type !== "none") {
if (e.key === "ArrowUp") { if (e.key === "ArrowUp") {
e.preventDefault(); e.preventDefault();
if (state.selected > 0) { if (state.selected > 0) {
setState({ setState({
...state, ...state,
selected: state.selected - 1 selected: state.selected - 1,
}); });
} }
...@@ -265,7 +285,7 @@ export function useAutoComplete(setValue: (v?: string) => void, searchClues?: Se ...@@ -265,7 +285,7 @@ export function useAutoComplete(setValue: (v?: string) => void, searchClues?: Se
if (state.selected < state.matches.length - 1) { if (state.selected < state.matches.length - 1) {
setState({ setState({
...state, ...state,
selected: state.selected + 1 selected: state.selected + 1,
}); });
} }
...@@ -274,9 +294,7 @@ export function useAutoComplete(setValue: (v?: string) => void, searchClues?: Se ...@@ -274,9 +294,7 @@ export function useAutoComplete(setValue: (v?: string) => void, searchClues?: Se
if (e.key === "Enter" || e.key === "Tab") { if (e.key === "Enter" || e.key === "Tab") {
e.preventDefault(); e.preventDefault();
selectCurrent( selectCurrent(e.currentTarget as HTMLTextAreaElement);
e.currentTarget as HTMLTextAreaElement
);
return true; return true;
} }
...@@ -287,7 +305,7 @@ export function useAutoComplete(setValue: (v?: string) => void, searchClues?: Se ...@@ -287,7 +305,7 @@ export function useAutoComplete(setValue: (v?: string) => void, searchClues?: Se
function onKeyUp(e: KeyboardEvent) { function onKeyUp(e: KeyboardEvent) {
if (e.currentTarget !== null) { if (e.currentTarget !== null) {
// @ts-expect-error // @ts-expect-error Type mis-match.
onChange(e); onChange(e);
} }
} }
...@@ -298,12 +316,12 @@ export function useAutoComplete(setValue: (v?: string) => void, searchClues?: Se ...@@ -298,12 +316,12 @@ export function useAutoComplete(setValue: (v?: string) => void, searchClues?: Se
} }
function onBlur() { function onBlur() {
if (state.type !== 'none' && state.within) return; if (state.type !== "none" && state.within) return;
setFocused(false); setFocused(false);
} }
return { return {
state: focused ? state : { type: 'none' }, state: focused ? state : { type: "none" },
setState, setState,
onClick, onClick,
...@@ -311,8 +329,8 @@ export function useAutoComplete(setValue: (v?: string) => void, searchClues?: Se ...@@ -311,8 +329,8 @@ export function useAutoComplete(setValue: (v?: string) => void, searchClues?: Se
onKeyUp, onKeyUp,
onKeyDown, onKeyDown,
onFocus, onFocus,
onBlur onBlur,
} };
} }
const Base = styled.div<{ detached?: boolean }>` const Base = styled.div<{ detached?: boolean }>`
...@@ -333,12 +351,13 @@ const Base = styled.div<{ detached?: boolean }>` ...@@ -333,12 +351,13 @@ const Base = styled.div<{ detached?: boolean }>`
display: flex; display: flex;
font-size: 1em; font-size: 1em;
cursor: pointer; cursor: pointer;
border-radius: 6px;
align-items: center; align-items: center;
flex-direction: row; flex-direction: row;
font-family: inherit;
background: transparent; background: transparent;
color: var(--foreground); color: var(--foreground);
width: calc(100% - 12px); width: calc(100% - 12px);
border-radius: var(--border-radius);
span { span {
display: grid; display: grid;
...@@ -350,100 +369,109 @@ const Base = styled.div<{ detached?: boolean }>` ...@@ -350,100 +369,109 @@ const Base = styled.div<{ detached?: boolean }>`
} }
} }
${ props => props.detached && css` ${(props) =>
bottom: 8px; props.detached &&
css`
bottom: 8px;
> div { > div {
border-radius: 4px; border-radius: var(--border-radius);
} }
` } `}
`; `;
export default function AutoComplete({ detached, state, setState, onClick }: Pick<AutoCompleteProps, 'detached' | 'state' | 'setState' | 'onClick'>) { export default function AutoComplete({
detached,
state,
setState,
onClick,
}: Pick<AutoCompleteProps, "detached" | "state" | "setState" | "onClick">) {
return ( return (
<Base detached={detached}> <Base detached={detached}>
<div> <div>
{state.type === "emoji" && {state.type === "emoji" &&
state.matches.map((match, i) => ( state.matches.map((match, i) => (
<button <button
className={i === state.selected ? "active" : ''} key={match}
className={i === state.selected ? "active" : ""}
onMouseEnter={() => onMouseEnter={() =>
(i !== state.selected || (i !== state.selected || !state.within) &&
!state.within) && setState({
setState({
...state, ...state,
selected: i, selected: i,
within: true within: true,
}) })
} }
onMouseLeave={() => onMouseLeave={() =>
state.within && state.within &&
setState({ setState({
...state, ...state,
within: false within: false,
}) })
} }
onClick={onClick}> onClick={onClick}>
<Emoji emoji={(emojiDictionary as any)[match]} size={20} /> <Emoji
emoji={
(emojiDictionary as Record<string, string>)[
match
]
}
size={20}
/>
:{match}: :{match}:
</button> </button>
))} ))}
{state.type === "user" && {state.type === "user" &&
state.matches.map((match, i) => ( state.matches.map((match, i) => (
<button <button
className={i === state.selected ? "active" : ''} key={match}
className={i === state.selected ? "active" : ""}
onMouseEnter={() => onMouseEnter={() =>
(i !== state.selected || (i !== state.selected || !state.within) &&
!state.within) &&
setState({ setState({
...state, ...state,
selected: i, selected: i,
within: true within: true,
}) })
} }
onMouseLeave={() => onMouseLeave={() =>
state.within && state.within &&
setState({ setState({
...state, ...state,
within: false within: false,
}) })
} }
onClick={onClick}> onClick={onClick}>
<UserIcon <UserIcon size={24} target={match} status={true} />
size={24}
target={match}
status={true} />
{match.username} {match.username}
</button> </button>
))} ))}
{state.type === "channel" && {state.type === "channel" &&
state.matches.map((match, i) => ( state.matches.map((match, i) => (
<button <button
className={i === state.selected ? "active" : ''} key={match}
className={i === state.selected ? "active" : ""}
onMouseEnter={() => onMouseEnter={() =>
(i !== state.selected || (i !== state.selected || !state.within) &&
!state.within) &&
setState({ setState({
...state, ...state,
selected: i, selected: i,
within: true within: true,
}) })
} }
onMouseLeave={() => onMouseLeave={() =>
state.within && state.within &&
setState({ setState({
...state, ...state,
within: false within: false,
}) })
} }
onClick={onClick}> onClick={onClick}>
<ChannelIcon <ChannelIcon size={24} target={match} />
size={24}
target={match} />
{match.name} {match.name}
</button> </button>
))} ))}
</div> </div>
</Base> </Base>
) );
} }
import { useContext } from "preact/hooks";
import { Channels } from "revolt.js/dist/api/objects";
import { Hash, VolumeFull } from "@styled-icons/boxicons-regular"; import { Hash, VolumeFull } from "@styled-icons/boxicons-regular";
import { ImageIconBase, IconBaseProps } from "./IconBase"; import { observer } from "mobx-react-lite";
import { Channel } from "revolt.js/dist/maps/Channels";
import { useContext } from "preact/hooks";
import { AppContext } from "../../context/revoltjs/RevoltClient"; import { AppContext } from "../../context/revoltjs/RevoltClient";
interface Props extends IconBaseProps<Channels.GroupChannel | Channels.TextChannel | Channels.VoiceChannel> { import { ImageIconBase, IconBaseProps } from "./IconBase";
import fallback from "./assets/group.png";
interface Props extends IconBaseProps<Channel> {
isServerChannel?: boolean; isServerChannel?: boolean;
} }
import fallback from './assets/group.png'; export default observer(
(
export default function ChannelIcon(props: Props & Omit<JSX.HTMLAttributes<HTMLImageElement>, keyof Props>) { props: Props &
const client = useContext(AppContext); Omit<
JSX.HTMLAttributes<HTMLImageElement>,
const { size, target, attachment, isServerChannel: server, animate, children, as, ...imgProps } = props; keyof Props | "children" | "as"
const iconURL = client.generateFileURL(target?.icon ?? attachment, { max_side: 256 }, animate); >,
const isServerChannel = server || (target && (target.channel_type === 'TextChannel' || target.channel_type === 'VoiceChannel')); ) => {
const client = useContext(AppContext);
if (typeof iconURL === 'undefined') {
if (isServerChannel) { const {
if (target?.channel_type === 'VoiceChannel') { size,
return ( target,
<VolumeFull size={size} /> attachment,
) isServerChannel: server,
} else { animate,
return ( ...imgProps
<Hash size={size} /> } = props;
) const iconURL = client.generateFileURL(
target?.icon ?? attachment,
{ max_side: 256 },
animate,
);
const isServerChannel =
server ||
(target &&
(target.channel_type === "TextChannel" ||
target.channel_type === "VoiceChannel"));
if (typeof iconURL === "undefined") {
if (isServerChannel) {
if (target?.channel_type === "VoiceChannel") {
return <VolumeFull size={size} />;
}
return <Hash size={size} />;
} }
} }
}
return (
return ( // ! TODO: replace fallback with <picture /> + <source />
// ! fixme: replace fallback with <picture /> + <source /> <ImageIconBase
<ImageIconBase {...imgProps} {...imgProps}
width={size} width={size}
height={size} height={size}
aria-hidden="true" loading="lazy"
square={isServerChannel} aria-hidden="true"
src={iconURL ?? fallback} /> square={isServerChannel}
); src={iconURL ?? fallback}
} />
);
},
);
import Details from "../ui/Details"; import { ChevronDown } from "@styled-icons/boxicons-regular";
import { State, store } from "../../redux"; import { State, store } from "../../redux";
import { Action } from "../../redux/reducers"; import { Action } from "../../redux/reducers";
import Details from "../ui/Details";
import { Children } from "../../types/Preact"; import { Children } from "../../types/Preact";
import { ChevronDown } from "@styled-icons/boxicons-regular";
interface Props { interface Props {
id: string; id: string;
...@@ -15,20 +18,26 @@ interface Props { ...@@ -15,20 +18,26 @@ interface Props {
children: Children; children: Children;
} }
export default function CollapsibleSection({ id, defaultValue, summary, children, ...detailsProps }: Props) { export default function CollapsibleSection({
id,
defaultValue,
summary,
children,
...detailsProps
}: Props) {
const state: State = store.getState(); const state: State = store.getState();
function setState(state: boolean) { function setState(state: boolean) {
if (state === defaultValue) { if (state === defaultValue) {
store.dispatch({ store.dispatch({
type: 'SECTION_TOGGLE_UNSET', type: "SECTION_TOGGLE_UNSET",
id id,
} as Action); } as Action);
} else { } else {
store.dispatch({ store.dispatch({
type: 'SECTION_TOGGLE_SET', type: "SECTION_TOGGLE_SET",
id, id,
state state,
} as Action); } as Action);
} }
} }
...@@ -36,15 +45,15 @@ export default function CollapsibleSection({ id, defaultValue, summary, children ...@@ -36,15 +45,15 @@ export default function CollapsibleSection({ id, defaultValue, summary, children
return ( return (
<Details <Details
open={state.sectionToggle[id] ?? defaultValue} open={state.sectionToggle[id] ?? defaultValue}
onToggle={e => setState(e.currentTarget.open)} onToggle={(e) => setState(e.currentTarget.open)}
{...detailsProps}> {...detailsProps}>
<summary> <summary>
<div class="padding"> <div class="padding">
<ChevronDown size={20} /> <ChevronDown size={20} />
{ summary } {summary}
</div> </div>
</summary> </summary>
{ children } {children}
</Details> </Details>
) );
} }
import { EmojiPacks } from '../../redux/reducers/settings'; import { EmojiPacks } from "../../redux/reducers/settings";
var EMOJI_PACK = 'mutant'; let EMOJI_PACK = "mutant";
const REVISION = 3; const REVISION = 3;
export function setEmojiPack(pack: EmojiPacks) { export function setEmojiPack(pack: EmojiPacks) {
...@@ -13,7 +13,7 @@ function codePoints(rune: string) { ...@@ -13,7 +13,7 @@ function codePoints(rune: string) {
const pairs = []; const pairs = [];
let low = 0; let low = 0;
let i = 0; let i = 0;
while (i < rune.length) { while (i < rune.length) {
const charCode = rune.charCodeAt(i++); const charCode = rune.charCodeAt(i++);
if (low) { if (low) {
...@@ -25,7 +25,7 @@ function codePoints(rune: string) { ...@@ -25,7 +25,7 @@ function codePoints(rune: string) {
pairs.push(charCode); pairs.push(charCode);
} }
} }
return pairs; return pairs;
} }
...@@ -33,30 +33,41 @@ function codePoints(rune: string) { ...@@ -33,30 +33,41 @@ function codePoints(rune: string) {
// scripts/build.js#344 // scripts/build.js#344
// grabTheRightIcon(rawText); // grabTheRightIcon(rawText);
const UFE0Fg = /\uFE0F/g; const UFE0Fg = /\uFE0F/g;
const U200D = String.fromCharCode(0x200D); const U200D = String.fromCharCode(0x200d);
function toCodePoint(rune: string) { function toCodePoint(rune: string) {
return codePoints(rune.indexOf(U200D) < 0 ? rune.replace(UFE0Fg, '') : rune) return codePoints(rune.indexOf(U200D) < 0 ? rune.replace(UFE0Fg, "") : rune)
.map((val) => val.toString(16)) .map((val) => val.toString(16))
.join("-") .join("-");
} }
function parseEmoji(emoji: string) { function parseEmoji(emoji: string) {
let codepoint = toCodePoint(emoji); const codepoint = toCodePoint(emoji);
return `https://static.revolt.chat/emoji/${EMOJI_PACK}/${codepoint}.svg?rev=${REVISION}`; return `https://static.revolt.chat/emoji/${EMOJI_PACK}/${codepoint}.svg?rev=${REVISION}`;
} }
export default function Emoji({ emoji, size }: { emoji: string, size?: number }) { export default function Emoji({
emoji,
size,
}: {
emoji: string;
size?: number;
}) {
return ( return (
<img <img
alt={emoji} alt={emoji}
loading="lazy"
className="emoji" className="emoji"
draggable={false} draggable={false}
src={parseEmoji(emoji)} src={parseEmoji(emoji)}
style={size ? { width: `${size}px`, height: `${size}px` } : undefined} style={
size ? { width: `${size}px`, height: `${size}px` } : undefined
}
/> />
) );
} }
export function generateEmoji(emoji: string) { export function generateEmoji(emoji: string) {
return `<img class="emoji" draggable="false" alt="${emoji}" src="${parseEmoji(emoji)}" />`; return `<img loading="lazy" class="emoji" draggable="false" alt="${emoji}" src="${parseEmoji(
emoji,
)}" />`;
} }