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