From 6054151969dbb7eb7f8df5051650cce159828363 Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Fri, 8 Mar 2024 12:48:46 +0100 Subject: [PATCH] Support Emoji 15.1 & fixes (#4343) --- package-lock.json | 8 ++--- package.json | 2 +- src/components/auth/CountryCodeInput.tsx | 2 +- src/components/common/Composer.tsx | 2 +- src/components/common/helpers/renderText.tsx | 4 +-- src/components/common/hooks/useCustomEmoji.ts | 2 +- .../middle/composer/EmojiButton.tsx | 2 +- .../middle/composer/EmojiPicker.tsx | 4 +-- .../middle/composer/MessageInput.tsx | 2 +- .../middle/composer/helpers/customEmoji.ts | 2 +- .../middle/composer/hooks/useEmojiTooltip.ts | 4 +-- .../composer/hooks/useInputCustomEmojis.ts | 2 +- .../composer/hooks/useStickerTooltip.ts | 2 +- src/components/middle/message/Giveaway.tsx | 2 +- .../middle/message/_message-content.scss | 2 +- .../helpers/getEmojiOnlyCountForMessage.ts | 2 +- src/hooks/useEnsureCustomEmoji.ts | 2 +- src/lib/twemojiRegex.js | 6 ++-- src/util/{ => emoji}/customEmojiManager.ts | 30 +++++++++---------- src/util/{ => emoji}/emoji.ts | 28 ++++------------- src/util/emoji/fixNonStandardEmoji.ts | 20 +++++++++++++ src/util/{ => emoji}/parseEmojiOnlyString.ts | 6 ++-- src/util/textFormat.ts | 2 +- src/util/windowEnvironment.ts | 2 +- 24 files changed, 73 insertions(+), 67 deletions(-) rename src/util/{ => emoji}/customEmojiManager.ts (82%) rename src/util/{ => emoji}/emoji.ts (76%) create mode 100644 src/util/emoji/fixNonStandardEmoji.ts rename src/util/{ => emoji}/parseEmojiOnlyString.ts (82%) diff --git a/package-lock.json b/package-lock.json index 8f6c09969..63bcc9af1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "async-mutex": "^0.4.0", "big-integer": "github:painor/BigInteger.js", "croppie": "^2.6.5", - "emoji-data-ios": "git+https://github.com/korenskoy/emoji-data-ios#2886b318eae174527c4bc9fcd321940ef3a85527", + "emoji-data-ios": "git+https://github.com/korenskoy/emoji-data-ios#de1a69aff2c8eb7548df4e6bcf50c7d2304792fc", "idb-keyval": "^6.2.1", "lowlight": "^2.9.0", "mp4box": "^0.5.2", @@ -11124,9 +11124,9 @@ } }, "node_modules/emoji-data-ios": { - "version": "0.5.0", - "resolved": "git+ssh://git@github.com/korenskoy/emoji-data-ios.git#2886b318eae174527c4bc9fcd321940ef3a85527", - "integrity": "sha512-kqoSV9kSLVjl5+tCpFwxXKYNnjgASPnRMwY4aLilYGNwX/R9mBYzSiHe/YbPurggz5AisLz/PeJuJeLe7XG7Fg==", + "version": "0.5.1", + "resolved": "git+ssh://git@github.com/korenskoy/emoji-data-ios.git#de1a69aff2c8eb7548df4e6bcf50c7d2304792fc", + "integrity": "sha512-aNh0bvCsHcRuLpTgOoJ2DQBYBHjuhjrpwrZtKKQ1ZyGVg0ab2ys26bjmI+zgWYcgg48hAhO2JQPZNRaR5yOK5w==", "license": "MIT" }, "node_modules/emoji-regex": { diff --git a/package.json b/package.json index de29085d9..912d8cbaa 100644 --- a/package.json +++ b/package.json @@ -139,7 +139,7 @@ "async-mutex": "^0.4.0", "big-integer": "github:painor/BigInteger.js", "croppie": "^2.6.5", - "emoji-data-ios": "git+https://github.com/korenskoy/emoji-data-ios#2886b318eae174527c4bc9fcd321940ef3a85527", + "emoji-data-ios": "git+https://github.com/korenskoy/emoji-data-ios#de1a69aff2c8eb7548df4e6bcf50c7d2304792fc", "idb-keyval": "^6.2.1", "lowlight": "^2.9.0", "mp4box": "^0.5.2", diff --git a/src/components/auth/CountryCodeInput.tsx b/src/components/auth/CountryCodeInput.tsx index d621ca915..1ffd1260d 100644 --- a/src/components/auth/CountryCodeInput.tsx +++ b/src/components/auth/CountryCodeInput.tsx @@ -8,7 +8,7 @@ import type { ApiCountryCode } from '../../api/types'; import { ANIMATION_END_DELAY } from '../../config'; import buildClassName from '../../util/buildClassName'; -import { isoToEmoji } from '../../util/emoji'; +import { isoToEmoji } from '../../util/emoji/emoji'; import { prepareSearchWordsForNeedle } from '../../util/searchWords'; import renderText from '../common/helpers/renderText'; diff --git a/src/components/common/Composer.tsx b/src/components/common/Composer.tsx index c5221d467..6eff048c1 100644 --- a/src/components/common/Composer.tsx +++ b/src/components/common/Composer.tsx @@ -86,9 +86,9 @@ import { } from '../../global/selectors'; import { selectCurrentLimit } from '../../global/selectors/limits'; import buildClassName from '../../util/buildClassName'; -import { processMessageInputForCustomEmoji } from '../../util/customEmojiManager'; import { formatMediaDuration, formatVoiceRecordDuration } from '../../util/dateFormat'; import deleteLastCharacterOutsideSelection from '../../util/deleteLastCharacterOutsideSelection'; +import { processMessageInputForCustomEmoji } from '../../util/emoji/customEmojiManager'; import focusEditableElement from '../../util/focusEditableElement'; import { MEMO_EMPTY_ARRAY } from '../../util/memo'; import parseHtmlAsFormattedText from '../../util/parseHtmlAsFormattedText'; diff --git a/src/components/common/helpers/renderText.tsx b/src/components/common/helpers/renderText.tsx index bb6d2c267..cb80ec8da 100644 --- a/src/components/common/helpers/renderText.tsx +++ b/src/components/common/helpers/renderText.tsx @@ -10,11 +10,11 @@ import EMOJI_REGEX from '../../../lib/twemojiRegex'; import buildClassName from '../../../util/buildClassName'; import { isDeepLink } from '../../../util/deepLinkParser'; import { - fixNonStandardEmoji, handleEmojiLoad, LOADED_EMOJIS, nativeToUnifiedExtendedWithCache, -} from '../../../util/emoji'; +} from '../../../util/emoji/emoji'; +import fixNonStandardEmoji from '../../../util/emoji/fixNonStandardEmoji'; import { compact } from '../../../util/iteratees'; import { IS_EMOJI_SUPPORTED } from '../../../util/windowEnvironment'; diff --git a/src/components/common/hooks/useCustomEmoji.ts b/src/components/common/hooks/useCustomEmoji.ts index 2affad2dc..8a61eed44 100644 --- a/src/components/common/hooks/useCustomEmoji.ts +++ b/src/components/common/hooks/useCustomEmoji.ts @@ -5,7 +5,7 @@ import type { ApiSticker } from '../../../api/types'; import type { GlobalState } from '../../../global/types'; import { selectCanPlayAnimatedEmojis } from '../../../global/selectors'; -import { addCustomEmojiCallback, removeCustomEmojiCallback } from '../../../util/customEmojiManager'; +import { addCustomEmojiCallback, removeCustomEmojiCallback } from '../../../util/emoji/customEmojiManager'; import useEnsureCustomEmoji from '../../../hooks/useEnsureCustomEmoji'; import useLastCallback from '../../../hooks/useLastCallback'; diff --git a/src/components/middle/composer/EmojiButton.tsx b/src/components/middle/composer/EmojiButton.tsx index 1b09a3087..4d83f7e5f 100644 --- a/src/components/middle/composer/EmojiButton.tsx +++ b/src/components/middle/composer/EmojiButton.tsx @@ -3,7 +3,7 @@ import React, { memo } from '../../../lib/teact/teact'; import { BASE_URL, IS_PACKAGED_ELECTRON } from '../../../config'; import buildClassName from '../../../util/buildClassName'; -import { handleEmojiLoad, LOADED_EMOJIS } from '../../../util/emoji'; +import { handleEmojiLoad, LOADED_EMOJIS } from '../../../util/emoji/emoji'; import { IS_EMOJI_SUPPORTED } from '../../../util/windowEnvironment'; import useLastCallback from '../../../hooks/useLastCallback'; diff --git a/src/components/middle/composer/EmojiPicker.tsx b/src/components/middle/composer/EmojiPicker.tsx index d86076157..04d674e5c 100644 --- a/src/components/middle/composer/EmojiPicker.tsx +++ b/src/components/middle/composer/EmojiPicker.tsx @@ -10,13 +10,13 @@ import type { EmojiData, EmojiModule, EmojiRawData, -} from '../../../util/emoji'; +} from '../../../util/emoji/emoji'; import { MENU_TRANSITION_DURATION, RECENT_SYMBOL_SET_ID } from '../../../config'; import animateHorizontalScroll from '../../../util/animateHorizontalScroll'; import animateScroll from '../../../util/animateScroll'; import buildClassName from '../../../util/buildClassName'; -import { uncompressEmoji } from '../../../util/emoji'; +import { uncompressEmoji } from '../../../util/emoji/emoji'; import { pick } from '../../../util/iteratees'; import { MEMO_EMPTY_ARRAY } from '../../../util/memo'; import { IS_TOUCH_ENV } from '../../../util/windowEnvironment'; diff --git a/src/components/middle/composer/MessageInput.tsx b/src/components/middle/composer/MessageInput.tsx index a2f28a4a1..2b1d004d5 100644 --- a/src/components/middle/composer/MessageInput.tsx +++ b/src/components/middle/composer/MessageInput.tsx @@ -16,8 +16,8 @@ import { selectCanPlayAnimatedEmojis, selectDraft, selectIsInSelectMode } from ' import buildClassName from '../../../util/buildClassName'; import captureKeyboardListeners from '../../../util/captureKeyboardListeners'; import { getIsDirectTextInputDisabled } from '../../../util/directInputManager'; +import parseEmojiOnlyString from '../../../util/emoji/parseEmojiOnlyString'; import focusEditableElement from '../../../util/focusEditableElement'; -import parseEmojiOnlyString from '../../../util/parseEmojiOnlyString'; import { debounce } from '../../../util/schedulers'; import { IS_ANDROID, IS_EMOJI_SUPPORTED, IS_IOS, IS_TOUCH_ENV, diff --git a/src/components/middle/composer/helpers/customEmoji.ts b/src/components/middle/composer/helpers/customEmoji.ts index 598dd490b..7568eb321 100644 --- a/src/components/middle/composer/helpers/customEmoji.ts +++ b/src/components/middle/composer/helpers/customEmoji.ts @@ -5,7 +5,7 @@ import { ApiMessageEntityTypes } from '../../../../api/types'; import { EMOJI_SIZES } from '../../../../config'; import buildClassName from '../../../../util/buildClassName'; -import { getInputCustomEmojiParams } from '../../../../util/customEmojiManager'; +import { getInputCustomEmojiParams } from '../../../../util/emoji/customEmojiManager'; import { REM } from '../../../common/helpers/mediaDimensions'; export const INPUT_CUSTOM_EMOJI_SELECTOR = 'img[data-document-id]'; diff --git a/src/components/middle/composer/hooks/useEmojiTooltip.ts b/src/components/middle/composer/hooks/useEmojiTooltip.ts index fa9d1890a..de38c26a2 100644 --- a/src/components/middle/composer/hooks/useEmojiTooltip.ts +++ b/src/components/middle/composer/hooks/useEmojiTooltip.ts @@ -2,13 +2,13 @@ import { useEffect, useState } from '../../../../lib/teact/teact'; import { getGlobal } from '../../../../global'; import type { ApiSticker } from '../../../../api/types'; -import type { EmojiData, EmojiModule, EmojiRawData } from '../../../../util/emoji'; +import type { EmojiData, EmojiModule, EmojiRawData } from '../../../../util/emoji/emoji'; import type { Signal } from '../../../../util/signals'; import { EDITABLE_INPUT_CSS_SELECTOR, EDITABLE_INPUT_ID } from '../../../../config'; import { requestNextMutation } from '../../../../lib/fasterdom/fasterdom'; import { selectCustomEmojiForEmojis } from '../../../../global/selectors'; -import { uncompressEmoji } from '../../../../util/emoji'; +import { uncompressEmoji } from '../../../../util/emoji/emoji'; import focusEditableElement from '../../../../util/focusEditableElement'; import { buildCollectionByKey, mapValues, pickTruthy, unique, uniqueByField, diff --git a/src/components/middle/composer/hooks/useInputCustomEmojis.ts b/src/components/middle/composer/hooks/useInputCustomEmojis.ts index 5982b53d3..945eb7f0c 100644 --- a/src/components/middle/composer/hooks/useInputCustomEmojis.ts +++ b/src/components/middle/composer/hooks/useInputCustomEmojis.ts @@ -13,7 +13,7 @@ import AbsoluteVideo from '../../../../util/AbsoluteVideo'; import { addCustomEmojiInputRenderCallback, getCustomEmojiMediaDataForInput, -} from '../../../../util/customEmojiManager'; +} from '../../../../util/emoji/customEmojiManager'; import { round } from '../../../../util/math'; import { hexToRgb } from '../../../../util/switchTheme'; import { REM } from '../../../common/helpers/mediaDimensions'; diff --git a/src/components/middle/composer/hooks/useStickerTooltip.ts b/src/components/middle/composer/hooks/useStickerTooltip.ts index 2b6c7355a..908dac457 100644 --- a/src/components/middle/composer/hooks/useStickerTooltip.ts +++ b/src/components/middle/composer/hooks/useStickerTooltip.ts @@ -6,7 +6,7 @@ import type { Signal } from '../../../../util/signals'; import { EMOJI_IMG_REGEX } from '../../../../config'; import twemojiRegex from '../../../../lib/twemojiRegex'; -import parseEmojiOnlyString from '../../../../util/parseEmojiOnlyString'; +import parseEmojiOnlyString from '../../../../util/emoji/parseEmojiOnlyString'; import { IS_EMOJI_SUPPORTED } from '../../../../util/windowEnvironment'; import { prepareForRegExp } from '../helpers/prepareForRegExp'; diff --git a/src/components/middle/message/Giveaway.tsx b/src/components/middle/message/Giveaway.tsx index 52e344bc5..ddc5d0a2f 100644 --- a/src/components/middle/message/Giveaway.tsx +++ b/src/components/middle/message/Giveaway.tsx @@ -18,7 +18,7 @@ import { } from '../../../global/selectors'; import buildClassName from '../../../util/buildClassName'; import { formatDateAtTime, formatDateTimeToString } from '../../../util/dateFormat'; -import { isoToEmoji } from '../../../util/emoji'; +import { isoToEmoji } from '../../../util/emoji/emoji'; import { getServerTime } from '../../../util/serverTime'; import { callApi } from '../../../api/gramjs'; import { LOCAL_TGS_URLS } from '../../common/helpers/animatedAssets'; diff --git a/src/components/middle/message/_message-content.scss b/src/components/middle/message/_message-content.scss index 5bcfb9dac..e71c52333 100644 --- a/src/components/middle/message/_message-content.scss +++ b/src/components/middle/message/_message-content.scss @@ -814,7 +814,7 @@ --emoji-only-size: #{$size}; .text-content { - width: #{calc($size * $i)}; + width: #{calc(($size + 1px) * $i)}; font-size: calc($size * 0.9); } } diff --git a/src/global/helpers/getEmojiOnlyCountForMessage.ts b/src/global/helpers/getEmojiOnlyCountForMessage.ts index 5107e9585..15f5f7e40 100644 --- a/src/global/helpers/getEmojiOnlyCountForMessage.ts +++ b/src/global/helpers/getEmojiOnlyCountForMessage.ts @@ -1,7 +1,7 @@ import type { MediaContent } from '../../api/types'; import { ApiMessageEntityTypes } from '../../api/types'; -import parseEmojiOnlyString from '../../util/parseEmojiOnlyString'; +import parseEmojiOnlyString from '../../util/emoji/parseEmojiOnlyString'; export function getEmojiOnlyCountForMessage(content: MediaContent, groupedId?: string): number | undefined { if (!content.text) return undefined; diff --git a/src/hooks/useEnsureCustomEmoji.ts b/src/hooks/useEnsureCustomEmoji.ts index be902324b..089ad3af3 100644 --- a/src/hooks/useEnsureCustomEmoji.ts +++ b/src/hooks/useEnsureCustomEmoji.ts @@ -1,6 +1,6 @@ import { getActions, getGlobal } from '../global'; -import { addCustomEmojiInputRenderCallback } from '../util/customEmojiManager'; +import { addCustomEmojiInputRenderCallback } from '../util/emoji/customEmojiManager'; import { throttle } from '../util/schedulers'; let LOAD_QUEUE = new Set(); diff --git a/src/lib/twemojiRegex.js b/src/lib/twemojiRegex.js index 2ec4cd2a8..0f6fb3806 100644 --- a/src/lib/twemojiRegex.js +++ b/src/lib/twemojiRegex.js @@ -1,7 +1,7 @@ // Copyright Twitter Inc. Licensed under MIT // https://github.com/twitter/twemoji-parser/blob/master/LICENSE.md -// Emoji 15.0 support was taken here https://github.com/mei23/twemoji-parser -// Version d374b2f 21.12.2022 +// Emoji 15.0.2 support was taken here https://github.com/mei23/twemoji-parser +// Version 3d4dedc 15.12.2023 const vs16RegExp = /\uFE0F/g; // avoid using a string literal like `\u200D` here because minifiers expand it inline @@ -20,4 +20,4 @@ export function removeVS16s(rawEmoji) { // This file is generated by source/emoji/scripts/generate.sh // eslint-disable-next-line max-len -export default /(?:\ud83c[\udd70\udd71\udd7e\udd7f]\ufe0f)|(?:\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83e\uddd1\u200d\ud83e\udd1d\u200d\ud83e\uddd1|\ud83d\udc6b\ud83c[\udffb-\udfff]|\ud83d\udc6c\ud83c[\udffb-\udfff]|\ud83d\udc6d\ud83c[\udffb-\udfff]|\ud83d\udc8f\ud83c[\udffb-\udfff]|\ud83d\udc91\ud83c[\udffb-\udfff]|\ud83d[\udc6b-\udc6d\udc8f\udc91])|(?:\ud83d[\udc68\udc69]|\ud83e\uddd1)(?:\ud83c[\udffb-\udfff])?\u200d(?:\u2695\ufe0f|\u2696\ufe0f|\u2708\ufe0f|\ud83c[\udf3e\udf73\udf7c\udf84\udf93\udfa4\udfa8\udfeb\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92]|\ud83e[\uddaf-\uddb3\uddbc\uddbd])|(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75]|\u26f9)((?:\ud83c[\udffb-\udfff]|\ufe0f)\u200d[\u2640\u2642]\ufe0f)|(?:\ud83c[\udfc3\udfc4\udfca]|\ud83d[\udc6e\udc70\udc71\udc73\udc77\udc81\udc82\udc86\udc87\ude45-\ude47\ude4b\ude4d\ude4e\udea3\udeb4-\udeb6]|\ud83e[\udd26\udd35\udd37-\udd39\udd3d\udd3e\uddb8\uddb9\uddcd-\uddcf\uddd4\uddd6-\udddd])(?:\ud83c[\udffb-\udfff])?\u200d[\u2640\u2642]\ufe0f|(?:\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f|\ud83c\udff3\ufe0f\u200d\ud83c\udf08|\ud83d\ude36\u200d\ud83c\udf2b\ufe0f|\u2764\ufe0f\u200d\ud83d\udd25|\u2764\ufe0f\u200d\ud83e\ude79|\ud83c\udff4\u200d\u2620\ufe0f|\ud83d\udc15\u200d\ud83e\uddba|\ud83d\udc3b\u200d\u2744\ufe0f|\ud83d\udc41\u200d\ud83d\udde8|\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc6f\u200d\u2640\ufe0f|\ud83d\udc6f\u200d\u2642\ufe0f|\ud83d\ude2e\u200d\ud83d\udca8|\ud83d\ude35\u200d\ud83d\udcab|\ud83e\udd3c\u200d\u2640\ufe0f|\ud83e\udd3c\u200d\u2642\ufe0f|\ud83e\uddde\u200d\u2640\ufe0f|\ud83e\uddde\u200d\u2642\ufe0f|\ud83e\udddf\u200d\u2640\ufe0f|\ud83e\udddf\u200d\u2642\ufe0f|\ud83d\udc08\u200d\u2b1b|\ud83d\udc26\u200d\u2b1b)|[#*0-9]\ufe0f?\u20e3|(?:[©®\u2122\u265f]\ufe0f)|(?:\ud83c[\udc04\ude02\ude1a\ude2f\ude37\udf21\udf24-\udf2c\udf36\udf7d\udf96\udf97\udf99-\udf9b\udf9e\udf9f\udfcd\udfce\udfd4-\udfdf\udff3\udff5\udff7]|\ud83d[\udc3f\udc41\udcfd\udd49\udd4a\udd6f\udd70\udd73\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa\udecb\udecd-\udecf\udee0-\udee5\udee9\udef0\udef3]|[\u203c\u2049\u2139\u2194-\u2199\u21a9\u21aa\u231a\u231b\u2328\u23cf\u23ed-\u23ef\u23f1\u23f2\u23f8-\u23fa\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600-\u2604\u260e\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638-\u263a\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267b\u267f\u2692-\u2697\u2699\u269b\u269c\u26a0\u26a1\u26a7\u26aa\u26ab\u26b0\u26b1\u26bd\u26be\u26c4\u26c5\u26c8\u26cf\u26d1\u26d3\u26d4\u26e9\u26ea\u26f0-\u26f5\u26f8\u26fa\u26fd\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u271d\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u2764\u27a1\u2934\u2935\u2b05-\u2b07\u2b1b\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299])(?:\ufe0f|(?!\ufe0e))|(?:(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75\udd90]|[\u261d\u26f7\u26f9\u270c\u270d])(?:\ufe0f|(?!\ufe0e))|(?:\ud83c[\udf85\udfc2-\udfc4\udfc7\udfca]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd7a\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4-\udeb6\udec0\udecc]|\ud83e[\udd0c\udd0f\udd18-\udd1f\udd26\udd30-\udd39\udd3d\udd3e\udd77\uddb5\uddb6\uddb8\uddb9\uddbb\uddcd-\uddcf\uddd1-\udddd\udec3-\udec5\udef0-\udef8]|[\u270a\u270b]))(?:\ud83c[\udffb-\udfff])?|(?:\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf5\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf3\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf20\udf2d-\udf35\udf37-\udf7c\udf7e-\udf84\udf86-\udf93\udfa0-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcf-\udfd3\udfe0-\udff0\udff4\udff8-\udfff]|\ud83d[\udc00-\udc3e\udc40\udc44\udc45\udc51-\udc65\udc6a\udc6f\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udc8e\udc90\udc92-\udca9\udcab-\udcfc\udcff-\udd3d\udd4b-\udd4e\udd50-\udd67\udda4\uddfb-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\uded0-\uded2\uded5-\uded7\udedc-\udedf\udeeb\udeec\udef4-\udefc\udfe0-\udfeb\udff0]|\ud83e[\udd0d\udd0e\udd10-\udd17\udd20-\udd25\udd27-\udd2f\udd3a\udd3c\udd3f-\udd45\udd47-\udd76\udd78-\uddb4\uddb7\uddba\uddbc-\uddcc\uddd0\uddde-\uddff\ude70-\ude7c\ude80-\ude88\ude90-\udebd\udebf-\udec2\udece-\udedb\udee0-\udee8]|[\u23e9-\u23ec\u23f0\u23f3\u267e\u26ce\u2705\u2728\u274c\u274e\u2753-\u2755\u2795-\u2797\u27b0\u27bf\ue50a])|\ufe0f/g; +export default /(?:\ud83c[\udd70\udd71\udd7e\udd7f]\ufe0f)|(?:\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83e\udef1\ud83c\udffb\u200d\ud83e\udef2\ud83c[\udffc-\udfff]|\ud83e\udef1\ud83c\udffc\u200d\ud83e\udef2\ud83c[\udffb\udffd-\udfff]|\ud83e\udef1\ud83c\udffd\u200d\ud83e\udef2\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\udef1\ud83c\udffe\u200d\ud83e\udef2\ud83c[\udffb-\udffd\udfff]|\ud83e\udef1\ud83c\udfff\u200d\ud83e\udef2\ud83c[\udffb-\udffe]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83e\uddd1\u200d\ud83e\udd1d\u200d\ud83e\uddd1|\ud83d\udc6b\ud83c[\udffb-\udfff]|\ud83d\udc6c\ud83c[\udffb-\udfff]|\ud83d\udc6d\ud83c[\udffb-\udfff]|\ud83d\udc8f\ud83c[\udffb-\udfff]|\ud83d\udc91\ud83c[\udffb-\udfff]|\ud83e\udd1d\ud83c[\udffb-\udfff]|\ud83d[\udc6b-\udc6d\udc8f\udc91]|\ud83e\udd1d)|(?:\ud83c\udfc3|\ud83d\udeb6|\ud83e\uddce)(?:\ud83c[\udffb-\udfff])?(?:\u200d[\u2640\u2642]\ufe0f)?(?:\u200d\u27a1\ufe0f)|(?:\ud83d[\udc68\udc69]|\ud83e\uddd1)(?:\ud83c[\udffb-\udfff])?\u200d(?:\ud83e[\uddaf\uddbc\uddbd])(?:\u200d\u27a1\ufe0f)|(?:\ud83d[\udc68\udc69]|\ud83e\uddd1)(?:\ud83c[\udffb-\udfff])?\u200d(?:\u2695\ufe0f|\u2696\ufe0f|\u2708\ufe0f|\ud83c[\udf3e\udf73\udf7c\udf84\udf93\udfa4\udfa8\udfeb\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92]|\ud83e[\uddaf\uddaf-\uddb3\uddbc\uddbc\uddbd\uddbd])|(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75]|\u26f9)((?:\ud83c[\udffb-\udfff]|\ufe0f)\u200d[\u2640\u2642]\ufe0f)|(?:\ud83c[\udfc3\udfc3\udfc4\udfca]|\ud83d[\udc6e\udc70\udc71\udc73\udc77\udc81\udc82\udc86\udc87\ude45-\ude47\ude4b\ude4d\ude4e\udea3\udeb4-\udeb6\udeb6]|\ud83e[\udd26\udd35\udd37-\udd39\udd3d\udd3e\uddb8\uddb9\uddcd\uddce\uddce\uddcf\uddd4\uddd6-\udddd])(?:\ud83c[\udffb-\udfff])?\u200d[\u2640\u2642]\ufe0f|(?:\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83e\uddd1\u200d\ud83e\uddd1\u200d\ud83e\uddd2\u200d\ud83e\uddd2|\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83e\uddd1\u200d\ud83e\uddd1\u200d\ud83e\uddd2|\ud83e\uddd1\u200d\ud83e\uddd2\u200d\ud83e\uddd2|\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f|\ud83c\udff3\ufe0f\u200d\ud83c\udf08|\ud83d\ude36\u200d\ud83c\udf2b\ufe0f|\u26d3\ufe0f\u200d\ud83d\udca5|\u2764\ufe0f\u200d\ud83d\udd25|\u2764\ufe0f\u200d\ud83e\ude79|\ud83c\udf44\u200d\ud83d\udfeb|\ud83c\udf4b\u200d\ud83d\udfe9|\ud83c\udff4\u200d\u2620\ufe0f|\ud83d\udc15\u200d\ud83e\uddba|\ud83d\udc26\u200d\ud83d\udd25|\ud83d\udc3b\u200d\u2744\ufe0f|\ud83d\udc41\u200d\ud83d\udde8|\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc6f\u200d\u2640\ufe0f|\ud83d\udc6f\u200d\u2642\ufe0f|\ud83d\ude2e\u200d\ud83d\udca8|\ud83d\ude35\u200d\ud83d\udcab|\ud83d\ude42\u200d\u2194\ufe0f|\ud83d\ude42\u200d\u2195\ufe0f|\ud83e\udd3c\u200d\u2640\ufe0f|\ud83e\udd3c\u200d\u2642\ufe0f|\ud83e\uddd1\u200d\ud83e\uddd2|\ud83e\uddde\u200d\u2640\ufe0f|\ud83e\uddde\u200d\u2642\ufe0f|\ud83e\udddf\u200d\u2640\ufe0f|\ud83e\udddf\u200d\u2642\ufe0f|\ud83d\udc08\u200d\u2b1b|\ud83d\udc26\u200d\u2b1b)|[#*0-9]\ufe0f?\u20e3|(?:[©®\u2122\u265f]\ufe0f)|(?:\ud83c[\udc04\ude02\ude1a\ude2f\ude37\udf21\udf24-\udf2c\udf36\udf7d\udf96\udf97\udf99-\udf9b\udf9e\udf9f\udfcd\udfce\udfd4-\udfdf\udff3\udff5\udff7]|\ud83d[\udc3f\udc41\udcfd\udd49\udd4a\udd6f\udd70\udd73\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa\udecb\udecd-\udecf\udee0-\udee5\udee9\udef0\udef3]|[\u203c\u2049\u2139\u2194-\u2199\u21a9\u21aa\u231a\u231b\u2328\u23cf\u23ed-\u23ef\u23f1\u23f2\u23f8-\u23fa\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600-\u2604\u260e\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638-\u263a\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267b\u267f\u2692-\u2697\u2699\u269b\u269c\u26a0\u26a1\u26a7\u26aa\u26ab\u26b0\u26b1\u26bd\u26be\u26c4\u26c5\u26c8\u26cf\u26d1\u26d3\u26d4\u26e9\u26ea\u26f0-\u26f5\u26f8\u26fa\u26fd\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u271d\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u2764\u27a1\u2934\u2935\u2b05-\u2b07\u2b1b\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299])(?:\ufe0f|(?!\ufe0e))|(?:(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75\udd90]|\ud83e\udef0|[\u261d\u26f7\u26f9\u270c\u270d])(?:\ufe0f|(?!\ufe0e))|(?:\ud83c[\udf85\udfc2-\udfc4\udfc7\udfca]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd7a\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4-\udeb6\udec0\udecc]|\ud83e[\udd0c\udd0f\udd18-\udd1c\udd1e\udd1f\udd26\udd30-\udd39\udd3d\udd3e\udd77\uddb5\uddb6\uddb8\uddb9\uddbb\uddcd-\uddcf\uddd1-\udddd\udec3-\udec5\udef1-\udef8]|[\u270a\u270b]))(?:\ud83c[\udffb-\udfff])?|(?:\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf5\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf3\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf20\udf2d-\udf35\udf37-\udf7c\udf7e-\udf84\udf86-\udf93\udfa0-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcf-\udfd3\udfe0-\udff0\udff4\udff8-\udfff]|\ud83d[\udc00-\udc3e\udc40\udc44\udc45\udc51-\udc65\udc6a\udc6f\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udc8e\udc90\udc92-\udca9\udcab-\udcfc\udcff-\udd3d\udd4b-\udd4e\udd50-\udd67\udda4\uddfb-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\uded0-\uded2\uded5-\uded7\udedc-\udedf\udeeb\udeec\udef4-\udefc\udfe0-\udfeb\udff0]|\ud83e[\udd0d\udd0e\udd10-\udd17\udd20-\udd25\udd27-\udd2f\udd3a\udd3c\udd3f-\udd45\udd47-\udd76\udd78-\uddb4\uddb7\uddba\uddbc-\uddcc\uddd0\uddde-\uddff\ude70-\ude7c\ude80-\ude88\ude90-\udebd\udebf-\udec2\udece-\udedb\udee0-\udee8]|[\u23e9-\u23ec\u23f0\u23f3\u267e\u26ce\u2705\u2728\u274c\u274e\u2753-\u2755\u2795-\u2797\u27b0\u27bf\ue50a])|\ufe0f/g; diff --git a/src/util/customEmojiManager.ts b/src/util/emoji/customEmojiManager.ts similarity index 82% rename from src/util/customEmojiManager.ts rename to src/util/emoji/customEmojiManager.ts index 8c6aadf51..72dce051a 100644 --- a/src/util/customEmojiManager.ts +++ b/src/util/emoji/customEmojiManager.ts @@ -1,21 +1,21 @@ -import { addCallback } from '../lib/teact/teactn'; -import { getGlobal } from '../global'; +import { addCallback } from '../../lib/teact/teactn'; +import { getGlobal } from '../../global'; -import type { ApiSticker } from '../api/types'; -import type { GlobalState } from '../global/types'; -import { ApiMediaFormat } from '../api/types'; +import type { ApiSticker } from '../../api/types'; +import type { GlobalState } from '../../global/types'; +import { ApiMediaFormat } from '../../api/types'; -import { requestMutation } from '../lib/fasterdom/fasterdom'; -import { getStickerPreviewHash } from '../global/helpers'; -import { selectCanPlayAnimatedEmojis } from '../global/selectors'; -import { createCallbackManager } from './callbacks'; -import generateUniqueId from './generateUniqueId'; -import * as mediaLoader from './mediaLoader'; -import { throttle } from './schedulers'; -import { IS_WEBM_SUPPORTED } from './windowEnvironment'; +import { requestMutation } from '../../lib/fasterdom/fasterdom'; +import { getStickerPreviewHash } from '../../global/helpers'; +import { selectCanPlayAnimatedEmojis } from '../../global/selectors'; +import { createCallbackManager } from '../callbacks'; +import generateUniqueId from '../generateUniqueId'; +import * as mediaLoader from '../mediaLoader'; +import { throttle } from '../schedulers'; +import { IS_WEBM_SUPPORTED } from '../windowEnvironment'; -import blankSrc from '../assets/blank.png'; -import placeholderSrc from '../assets/square.svg'; +import blankSrc from '../../assets/blank.png'; +import placeholderSrc from '../../assets/square.svg'; type CustomEmojiLoadCallback = (customEmojis: GlobalState['customEmojis']) => void; type CustomEmojiInputRenderCallback = (emojiId: string) => void; diff --git a/src/util/emoji.ts b/src/util/emoji/emoji.ts similarity index 76% rename from src/util/emoji.ts rename to src/util/emoji/emoji.ts index 55689d2e4..6a3063fbe 100644 --- a/src/util/emoji.ts +++ b/src/util/emoji/emoji.ts @@ -1,6 +1,8 @@ -import { requestMutation } from '../lib/fasterdom/fasterdom'; -import EMOJI_REGEX, { removeVS16s } from '../lib/twemojiRegex'; -import withCache from './withCache'; +import { addExtraClass } from '../../lib/teact/teact-dom'; + +import { requestMutation } from '../../lib/fasterdom/fasterdom'; +import { removeVS16s } from '../../lib/twemojiRegex'; +import withCache from '../withCache'; // Due to the fact that emoji from Apple do not contain some characters, it is necessary to remove them from emoji-data // https://github.com/iamcal/emoji-data/issues/136 @@ -16,13 +18,6 @@ export type EmojiData = { emojis: Record; }; -// Non-standard variations of emojis, used on some devices -const EMOJI_EXCEPTIONS: [string | RegExp, string][] = [ - [/\u{1f3f3}\u200d\u{1f308}/gu, '\u{1f3f3}\ufe0f\u200d\u{1f308}'], // 🏳‍🌈 - [/\u{1f3f3}\u200d\u26a7\ufe0f/gu, '\u{1f3f3}\ufe0f\u200d\u26a7\ufe0f'], // 🏳️‍⚧️ - [/\u{1f937}\u200d\u2642[^\ufe0f]/gu, '\u{1f937}\u200d\u2642\ufe0f'], // 🤷‍♂️ -]; - function unifiedToNative(unified: string) { const unicodes = unified.split('-'); const codePoints = unicodes.map((i) => parseInt(i, 16)); @@ -38,21 +33,10 @@ export function handleEmojiLoad(event: React.SyntheticEvent) { LOADED_EMOJIS.add(event.currentTarget.dataset.path!); requestMutation(() => { - emoji.classList.add('open'); + addExtraClass(emoji, 'open'); }); } -export function fixNonStandardEmoji(text: string) { - // Non-standard sequences typically parsed as separate emojis, so no need to fix text without any - if (!text.match(EMOJI_REGEX)) return text; - // eslint-disable-next-line no-restricted-syntax - for (const [regex, replacement] of EMOJI_EXCEPTIONS) { - text = text.replace(regex, replacement); - } - - return text; -} - export function nativeToUnified(emoji: string) { let code; diff --git a/src/util/emoji/fixNonStandardEmoji.ts b/src/util/emoji/fixNonStandardEmoji.ts new file mode 100644 index 000000000..f327bf837 --- /dev/null +++ b/src/util/emoji/fixNonStandardEmoji.ts @@ -0,0 +1,20 @@ +import EMOJI_REGEX from '../../lib/twemojiRegex'; + +// Non-standard variations of emojis, used on some devices +const EMOJI_EXCEPTIONS: [string | RegExp, string][] = [ + [/\u{1f3f3}\u200d\u{1f308}/gu, '\u{1f3f3}\ufe0f\u200d\u{1f308}'], // 🏳‍🌈 + [/\u{1f3f3}\u200d\u26a7\ufe0f?/gu, '\u{1f3f3}\ufe0f\u200d\u26a7\ufe0f'], // 🏳️‍⚧️ + [/\u26d3\u200d\u{1f4a5}/gu, '\u26d3\ufe0f\u200d\u{1f4a5}'], // ⛓‍💥 + [/\u200d([\u2640\u2642])(?!\ufe0f)/gu, '\u200d$1\ufe0f'], // Gender variation without 0xFE0F +]; + +export default function fixNonStandardEmoji(text: string) { + // Non-standard sequences typically parsed as separate emojis, so no need to fix text without any + if (!text.match(EMOJI_REGEX)) return text; + // eslint-disable-next-line no-restricted-syntax + for (const [regex, replacement] of EMOJI_EXCEPTIONS) { + text = text.replace(regex, replacement); + } + + return text; +} diff --git a/src/util/parseEmojiOnlyString.ts b/src/util/emoji/parseEmojiOnlyString.ts similarity index 82% rename from src/util/parseEmojiOnlyString.ts rename to src/util/emoji/parseEmojiOnlyString.ts index e3eac977c..df001e8cf 100644 --- a/src/util/parseEmojiOnlyString.ts +++ b/src/util/emoji/parseEmojiOnlyString.ts @@ -1,11 +1,13 @@ -import twemojiRegex from '../lib/twemojiRegex'; +import twemojiRegex from '../../lib/twemojiRegex'; +import fixNonStandardEmoji from './fixNonStandardEmoji'; const DETECT_UP_TO = 100; const MAX_LENGTH = DETECT_UP_TO * 8; // Maximum 8 per one emoji. const RE_EMOJI_ONLY = new RegExp(`^(?:${twemojiRegex.source})+$`, ''); const parseEmojiOnlyString = (text: string): number | false => { - const lines = text.split('\n'); + const standardizedText = fixNonStandardEmoji(text); + const lines = standardizedText.split('\n'); const textWithoutNewlines = lines.join(''); if (textWithoutNewlines.length > MAX_LENGTH) { return false; diff --git a/src/util/textFormat.ts b/src/util/textFormat.ts index 446755e5b..5752de810 100644 --- a/src/util/textFormat.ts +++ b/src/util/textFormat.ts @@ -1,7 +1,7 @@ import type { LangFn } from '../hooks/useLang'; import EMOJI_REGEX from '../lib/twemojiRegex'; -import { fixNonStandardEmoji } from './emoji'; +import fixNonStandardEmoji from './emoji/fixNonStandardEmoji'; import withCache from './withCache'; export function formatInteger(value: number) { diff --git a/src/util/windowEnvironment.ts b/src/util/windowEnvironment.ts index 39e7ab282..5d0ebbedd 100644 --- a/src/util/windowEnvironment.ts +++ b/src/util/windowEnvironment.ts @@ -125,7 +125,7 @@ function isLastEmojiVersionSupported() { inlineEl.classList.add('emoji-test-element'); document.body.appendChild(inlineEl); - inlineEl.innerText = '🫸🏻'; // Emoji from 15.0 version + inlineEl.innerText = '🐦‍🔥'; // Emoji from 15.1 version const newEmojiWidth = inlineEl.offsetWidth; inlineEl.innerText = '❤️'; // Emoji from 1.0 version const legacyEmojiWidth = inlineEl.offsetWidth;