qt6-qtbase/qtbase-use-emoji-segmenter-to-apply-emoji-fonts-automatically.patch

5918 lines
460 KiB
Diff
Raw Normal View History

From 16850709306589a2433c0038605d365a6b6bedad Mon Sep 17 00:00:00 2001
From: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
Date: Tue, 02 Apr 2024 13:20:34 +0200
Subject: [PATCH] Use emoji segmenter to apply emoji fonts automatically
Colorful emojis in Unicode are not isolated to specific ranges
of code points like other writing systems. Instead, there are
a set of rules defining whether a sequence of characters should
be displayed in color or black/white.
http://www.unicode.org/reports/tr51/
For instance, appending a variation selector to a character can
turn it into a color emoji, even if it is a code point that
predates the invention of emojis.
In addition, sequences of joined characters that are determined
to be a color emoji sequence should be parsed by a single emoji
font, so that it can apply things like skin color, etc.
In general, users expect emojis and emoji sequences to be shown
in the preferred color font of the system, even if a selected
font has black/white characters for the symbols.
This patch applies the emoji segmenter to strings to isolate
sequences that should be in color. As an implementation hack,
we mark this in the QScriptItems as a special "emoji" script.
Note that this is not a real Unicode script and only exists
internally for this reason, because the "emojiness" of the
resulting glyph overrides the original script of the
individual characters when selecting fonts. This way, we can
use a lot of the same logic for itemizing the strings and
looking up fonts, and we don't need to increase the size of
the QScriptItem. (It is just an implementation detail and
is not exposed to the user, so it can be replaced by other
approaches later if we need to.)
When matching an emoji sequence, we always try to apply a
color font and ignore all others. The exception is if there
is no color font at all on the system, then we will find a
black and white font which supports the characters instead
as a final failsafe.
In addition, each platform will put its default emoji font
at the top of the fallbacks list in order to make this the
preference in case there are more than one. This patch also
adds API to override this with an application-defined emoji
font, since this is a common use case.
Note: The font includes an environment variable to disable
the feature as a fail safe. A flag to disable it per QFont
will be added in a follow-up.
Fixes: QTBUG-111801
Change-Id: I9431ec34d56772ab8688814963073b83b23002ae
Reviewed-by: Lars Knoll <lars@knoll.priv.no>
Reviewed-by: <carl@carlschwan.eu>
---
diff --git a/src/gui/text/coretext/qcoretextfontdatabase.mm b/src/gui/text/coretext/qcoretextfontdatabase.mm
index 2197c83f..fc551cdb 100644
--- a/src/gui/text/coretext/qcoretextfontdatabase.mm
+++ b/src/gui/text/coretext/qcoretextfontdatabase.mm
@@ -327,6 +327,7 @@ struct FontDescription {
QFont::Stretch stretch;
qreal pointSize;
bool fixedPitch;
+ bool colorFont;
QSupportedWritingSystems writingSystems;
};
@@ -359,6 +360,9 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd)
fd->style = QFont::StyleNormal;
fd->stretch = QFont::Unstretched;
fd->fixedPitch = false;
+ fd->colorFont = false;
+
+
if (QCFType<CTFontRef> tempFont = CTFontCreateWithFontDescriptor(font, 0.0, 0)) {
uint tag = QFont::Tag("OS/2").value();
@@ -393,6 +397,9 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd)
if (CFNumberRef symbolic = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontSymbolicTrait)) {
int d;
if (CFNumberGetValue(symbolic, kCFNumberSInt32Type, &d)) {
+ if (d & kCTFontColorGlyphsTrait)
+ fd->colorFont = true;
+
if (d & kCTFontMonoSpaceTrait)
fd->fixedPitch = true;
if (d & kCTFontExpandedTrait)
@@ -451,7 +458,7 @@ void QCoreTextFontDatabase::populateFromDescriptor(CTFontDescriptorRef font, con
CFRetain(font);
QPlatformFontDatabase::registerFont(family, fd.styleName, fd.foundryName, fd.weight, fd.style, fd.stretch,
true /* antialiased */, true /* scalable */, 0 /* pixelSize, ignored as font is scalable */,
- fd.fixedPitch, fd.writingSystems, (void *)font);
+ fd.fixedPitch, fd.colorFont, fd.writingSystems, (void *)font);
}
static NSString * const kQtFontDataAttribute = @"QtFontDataAttribute";
@@ -629,7 +636,18 @@ CTFontDescriptorRef descriptorForStyle(QFont::StyleHint styleHint)
}
}
-QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const
+QStringList QCoreTextFontDatabase::fallbacksForScript(QFontDatabasePrivate::ExtendedScript script) const
+{
+ if (script == QFontDatabasePrivate::Script_Emoji)
+ return QStringList{} << QStringLiteral(".Apple Color Emoji UI");
+ else
+ return QStringList{};
+}
+
+QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family,
+ QFont::Style style,
+ QFont::StyleHint styleHint,
+ QFontDatabasePrivate::ExtendedScript script) const
{
Q_UNUSED(style);
@@ -639,7 +657,7 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo
QMacAutoReleasePool pool;
- QStringList fallbackList;
+ QStringList fallbackList = fallbacksForScript(script);
QCFType<CFArrayRef> fallbackFonts = fallbacksForFamily(family);
if (!fallbackFonts || !CFArrayGetCount(fallbackFonts)) {
@@ -702,32 +720,34 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo
fallbackList.append(QStringLiteral("Apple Symbols"));
// Some Noto* fonts are not automatically enumerated by system, despite being the main
// fonts for their writing system.
- QString hardcodedFont = m_hardcodedFallbackFonts.value(script);
- if (!hardcodedFont.isEmpty() && !fallbackList.contains(hardcodedFont)) {
- if (!isFamilyPopulated(hardcodedFont)) {
- if (!m_privateFamilies.contains(hardcodedFont)) {
- QCFType<CTFontDescriptorRef> familyDescriptor = descriptorForFamily(hardcodedFont);
- QCFType<CFArrayRef> matchingFonts = CTFontDescriptorCreateMatchingFontDescriptors(familyDescriptor, nullptr);
- if (matchingFonts) {
- const int numFonts = CFArrayGetCount(matchingFonts);
- for (int i = 0; i < numFonts; ++i)
- const_cast<QCoreTextFontDatabase *>(this)->populateFromDescriptor(CTFontDescriptorRef(CFArrayGetValueAtIndex(matchingFonts, i)),
- hardcodedFont);
-
- fallbackList.append(hardcodedFont);
+ if (script < int(QChar::ScriptCount)) {
+ QString hardcodedFont = m_hardcodedFallbackFonts.value(QChar::Script(script));
+ if (!hardcodedFont.isEmpty() && !fallbackList.contains(hardcodedFont)) {
+ if (!isFamilyPopulated(hardcodedFont)) {
+ if (!m_privateFamilies.contains(hardcodedFont)) {
+ QCFType<CTFontDescriptorRef> familyDescriptor = descriptorForFamily(hardcodedFont);
+ QCFType<CFArrayRef> matchingFonts = CTFontDescriptorCreateMatchingFontDescriptors(familyDescriptor, nullptr);
+ if (matchingFonts) {
+ const int numFonts = CFArrayGetCount(matchingFonts);
+ for (int i = 0; i < numFonts; ++i)
+ const_cast<QCoreTextFontDatabase *>(this)->populateFromDescriptor(CTFontDescriptorRef(CFArrayGetValueAtIndex(matchingFonts, i)),
+ hardcodedFont);
+
+ fallbackList.append(hardcodedFont);
+ }
+
+ // Register as private family even if the font is not found, in order to avoid
+ // redoing the check later. In later calls, the font will then just be ignored.
+ m_privateFamilies.insert(hardcodedFont);
}
-
- // Register as private family even if the font is not found, in order to avoid
- // redoing the check later. In later calls, the font will then just be ignored.
- m_privateFamilies.insert(hardcodedFont);
+ } else {
+ fallbackList.append(hardcodedFont);
}
- } else {
- fallbackList.append(hardcodedFont);
}
}
#endif
- extern QStringList qt_sort_families_by_writing_system(QChar::Script, const QStringList &);
+ extern QStringList qt_sort_families_by_writing_system(QFontDatabasePrivate::ExtendedScript, const QStringList &);
fallbackList = qt_sort_families_by_writing_system(script, fallbackList);
qCDebug(lcQpaFonts).nospace() << "Fallback families ordered by script " << script << ": " << fallbackList;
diff --git a/src/gui/text/coretext/qcoretextfontdatabase_p.h b/src/gui/text/coretext/qcoretextfontdatabase_p.h
index eeea9ad6..5c8a6ad3 100644
--- a/src/gui/text/coretext/qcoretextfontdatabase_p.h
+++ b/src/gui/text/coretext/qcoretextfontdatabase_p.h
@@ -39,7 +39,7 @@ public:
void populateFamily(const QString &familyName) override;
void invalidate() override;
- QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const override;
+ QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QFontDatabasePrivate::ExtendedScript script) const override;
QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *applicationFont = nullptr) override;
void releaseHandle(void *handle) override;
bool isPrivateFontFamily(const QString &family) const override;
@@ -55,6 +55,7 @@ private:
void populateThemeFonts();
void populateFromDescriptor(CTFontDescriptorRef font, const QString &familyName = QString(), QFontDatabasePrivate::ApplicationFont *applicationFont = nullptr);
static CFArrayRef fallbacksForFamily(const QString &family);
+ QStringList fallbacksForScript(QFontDatabasePrivate::ExtendedScript script) const;
QHash<QPlatformTheme::Font, QFont *> m_themeFonts;
QHash<QString, QList<QCFType<CTFontDescriptorRef>>> m_systemFontDescriptors;
diff --git a/src/gui/text/freetype/qfreetypefontdatabase.cpp b/src/gui/text/freetype/qfreetypefontdatabase.cpp
index 018e590a..8e0aec1f 100644
--- a/src/gui/text/freetype/qfreetypefontdatabase.cpp
+++ b/src/gui/text/freetype/qfreetypefontdatabase.cpp
@@ -103,6 +103,7 @@ void QFreeTypeFontDatabase::addNamedInstancesForFace(void *face_,
QFont::Stretch stretch,
QFont::Style style,
bool fixedPitch,
+ bool isColor,
const QSupportedWritingSystems &writingSystems,
const QByteArray &fileName,
const QByteArray &fontData)
@@ -183,6 +184,7 @@ void QFreeTypeFontDatabase::addNamedInstancesForFace(void *face_,
true,
0,
fixedPitch,
+ isColor,
writingSystems,
variantFontFile);
}
@@ -224,6 +226,12 @@ QStringList QFreeTypeFontDatabase::addTTFile(const QByteArray &fontData, const Q
}
numFaces = face->num_faces;
+#if (FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) >= 20501
+ bool isColor = FT_HAS_COLOR(face);
+#else
+ bool isColor = false;
+#endif
+
QFont::Weight weight = QFont::Normal;
QFont::Style style = QFont::StyleNormal;
@@ -337,9 +345,9 @@ QStringList QFreeTypeFontDatabase::addTTFile(const QByteArray &fontData, const Q
applicationFont->properties.append(properties);
}
- registerFont(family, styleName, QString(), weight, style, stretch, true, true, 0, fixedPitch, writingSystems, fontFile);
+ registerFont(family, styleName, QString(), weight, style, stretch, true, true, 0, fixedPitch, isColor, writingSystems, fontFile);
- addNamedInstancesForFace(face, index, family, styleName, weight, stretch, style, fixedPitch, writingSystems, file, fontData);
+ addNamedInstancesForFace(face, index, family, styleName, weight, stretch, style, fixedPitch, isColor, writingSystems, file, fontData);
families.append(family);
diff --git a/src/gui/text/freetype/qfreetypefontdatabase_p.h b/src/gui/text/freetype/qfreetypefontdatabase_p.h
index 5fcec585..bc5cdbff 100644
--- a/src/gui/text/freetype/qfreetypefontdatabase_p.h
+++ b/src/gui/text/freetype/qfreetypefontdatabase_p.h
@@ -47,7 +47,7 @@ public:
static void addNamedInstancesForFace(void *face, int faceIndex,
const QString &family, const QString &styleName,
QFont::Weight weight, QFont::Stretch stretch,
- QFont::Style style, bool fixedPitch,
+ QFont::Style style, bool fixedPitch, bool isColor,
const QSupportedWritingSystems &writingSystems,
const QByteArray &fileName, const QByteArray &fontData);
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index c8881a9b..94343854 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -383,13 +383,13 @@ void QFontPrivate::unsetFeature(QFont::Tag tag)
QFontEngineData::QFontEngineData()
: ref(0), fontCacheId(QFontCache::instance()->id())
{
- memset(engines, 0, QChar::ScriptCount * sizeof(QFontEngine *));
+ memset(engines, 0, QFontDatabasePrivate::ScriptCount * sizeof(QFontEngine *));
}
QFontEngineData::~QFontEngineData()
{
Q_ASSERT(ref.loadRelaxed() == 0);
- for (int i = 0; i < QChar::ScriptCount; ++i) {
+ for (int i = 0; i < QFontDatabasePrivate::ScriptCount; ++i) {
if (engines[i]) {
if (!engines[i]->ref.deref())
delete engines[i];
@@ -2683,8 +2683,10 @@ void QFont::clearFeatures()
d->features.clear();
}
-extern QStringList qt_fallbacksForFamily(const QString &family, QFont::Style style,
- QFont::StyleHint styleHint, QChar::Script script);
+extern QStringList qt_fallbacksForFamily(const QString &family,
+ QFont::Style style,
+ QFont::StyleHint styleHint,
+ QFontDatabasePrivate::ExtendedScript script);
/*!
\fn QString QFont::defaultFamily() const
@@ -2696,8 +2698,10 @@ extern QStringList qt_fallbacksForFamily(const QString &family, QFont::Style sty
*/
QString QFont::defaultFamily() const
{
- const QStringList fallbacks = qt_fallbacksForFamily(QString(), QFont::StyleNormal
- , QFont::StyleHint(d->request.styleHint), QChar::Script_Common);
+ const QStringList fallbacks = qt_fallbacksForFamily(QString(),
+ QFont::StyleNormal,
+ QFont::StyleHint(d->request.styleHint),
+ QFontDatabasePrivate::Script_Common);
if (!fallbacks.isEmpty())
return fallbacks.first();
return QString();
@@ -3394,7 +3398,7 @@ void QFontCache::clear()
end = engineDataCache.end();
while (it != end) {
QFontEngineData *data = it.value();
- for (int i = 0; i < QChar::ScriptCount; ++i) {
+ for (int i = 0; i < QFontDatabasePrivate::ScriptCount; ++i) {
if (data->engines[i]) {
if (!data->engines[i]->ref.deref()) {
Q_ASSERT(engineCacheCount.value(data->engines[i]) == 0);
diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h
index b674e711..844ac5fc 100644
--- a/src/gui/text/qfont_p.h
+++ b/src/gui/text/qfont_p.h
@@ -23,6 +23,7 @@
#include "QtCore/qstringlist.h"
#include <QtGui/qfontdatabase.h>
#include "private/qfixed_p.h"
+#include "private/qfontdatabase_p.h"
QT_BEGIN_NAMESPACE
@@ -152,8 +153,7 @@ public:
QAtomicInt ref;
const int fontCacheId;
- QFontEngine *engines[QChar::ScriptCount];
-
+ QFontEngine *engines[QFontDatabasePrivate::ScriptCount];
private:
Q_DISABLE_COPY_MOVE(QFontEngineData)
};
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 28539977..96c2337e 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -413,6 +413,8 @@ static bool familySupportsWritingSystem(QtFontFamily *family, size_t writingSyst
Q_GUI_EXPORT QFontDatabase::WritingSystem qt_writing_system_for_script(int script)
{
+ if (script >= QChar::ScriptCount)
+ return QFontDatabase::Any;
return QFontDatabase::WritingSystem(std::find(scriptForWritingSystem,
scriptForWritingSystem + QFontDatabase::WritingSystemsCount,
script) - scriptForWritingSystem);
@@ -537,7 +539,7 @@ QFontDatabasePrivate *QFontDatabasePrivate::instance()
void qt_registerFont(const QString &familyName, const QString &stylename,
const QString &foundryname, int weight,
QFont::Style style, int stretch, bool antialiased,
- bool scalable, int pixelSize, bool fixedPitch,
+ bool scalable, int pixelSize, bool fixedPitch, bool colorFont,
const QSupportedWritingSystems &writingSystems, void *handle)
{
auto *d = QFontDatabasePrivate::instance();
@@ -549,6 +551,7 @@ void qt_registerFont(const QString &familyName, const QString &stylename,
styleKey.stretch = stretch;
QtFontFamily *f = d->family(familyName, QFontDatabasePrivate::EnsureCreated);
f->fixedPitch = fixedPitch;
+ f->colorFont = colorFont;
for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) {
if (writingSystems.supported(QFontDatabase::WritingSystem(i)))
@@ -620,7 +623,10 @@ bool qt_isFontFamilyPopulated(const QString &familyName)
Default implementation returns a list of fonts for which \a style and \a script support
has been reported during the font database population.
*/
-QStringList QPlatformFontDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const
+QStringList QPlatformFontDatabase::fallbacksForFamily(const QString &family,
+ QFont::Style style,
+ QFont::StyleHint styleHint,
+ QFontDatabasePrivate::ExtendedScript script) const
{
Q_UNUSED(family);
Q_UNUSED(styleHint);
@@ -659,7 +665,10 @@ QStringList QPlatformFontDatabase::fallbacksForFamily(const QString &family, QFo
return preferredFallbacks + otherFallbacks;
}
-static QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script)
+static QStringList fallbacksForFamily(const QString &family,
+ QFont::Style style,
+ QFont::StyleHint styleHint,
+ QFontDatabasePrivate::ExtendedScript script)
{
QMutexLocker locker(fontDatabaseMutex());
auto *db = QFontDatabasePrivate::ensureFontDatabase();
@@ -670,7 +679,7 @@ static QStringList fallbacksForFamily(const QString &family, QFont::Style style,
return *fallbacks;
// make sure that the db has all fallback families
- QStringList userFallbacks = db->applicationFallbackFontFamilies.value(script == QChar::Script_Latin ? QChar::Script_Common : script);
+ QStringList userFallbacks = db->applicationFallbackFontFamilies(script == QFontDatabasePrivate::Script_Latin ? QFontDatabasePrivate::Script_Common : script);
QStringList retList = userFallbacks + QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fallbacksForFamily(family,style,styleHint,script);
QStringList::iterator i;
@@ -693,7 +702,7 @@ static QStringList fallbacksForFamily(const QString &family, QFont::Style style,
return retList;
}
-QStringList qt_fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script)
+QStringList qt_fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QFontDatabasePrivate::ExtendedScript script)
{
QMutexLocker locker(fontDatabaseMutex());
return fallbacksForFamily(family, style, styleHint, script);
@@ -722,10 +731,10 @@ QFontEngine *QFontDatabasePrivate::loadSingleEngine(int script,
QFontCache::Key key(def,script);
QFontEngine *engine = fontCache->findEngine(key);
if (!engine) {
- const bool cacheForCommonScript = script != QChar::Script_Common
+ const bool cacheForCommonScript = script != QFontDatabasePrivate::Script_Common
&& (family->writingSystems[QFontDatabase::Latin] & QtFontFamily::Supported) != 0;
- if (Q_LIKELY(cacheForCommonScript)) {
+ if (Q_LIKELY(cacheForCommonScript) && script < QChar::ScriptCount) {
// fast path: check if engine was loaded for another script
key.script = QChar::Script_Common;
engine = fontCache->findEngine(key);
@@ -757,7 +766,7 @@ QFontEngine *QFontDatabasePrivate::loadSingleEngine(int script,
engine = pfdb->fontEngine(def, size->handle);
if (engine) {
// Also check for OpenType tables when using complex scripts
- if (!engine->supportsScript(QChar::Script(script))) {
+ if (script < QChar::ScriptCount && !engine->supportsScript(QChar::Script(script))) {
qCInfo(lcFontDb, "OpenType support missing for \"%ls\", script %d",
qUtf16Printable(def.families.constFirst()), script);
if (engine->ref.loadRelaxed() == 0)
@@ -789,7 +798,8 @@ QFontEngine *QFontDatabasePrivate::loadEngine(int script, const QFontDef &reques
Q_TRACE(QFontDatabase_loadEngine, request.families.join(QLatin1Char(';')), request.pointSize);
QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
- QFontEngineMulti *pfMultiEngine = pfdb->fontEngineMulti(engine, QChar::Script(script));
+ QFontEngineMulti *pfMultiEngine = pfdb->fontEngineMulti(engine,
+ QFontDatabasePrivate::ExtendedScript(script));
if (!request.fallBackFamilies.isEmpty()) {
QStringList fallbacks = request.fallBackFamilies;
@@ -797,7 +807,10 @@ QFontEngine *QFontDatabasePrivate::loadEngine(int script, const QFontDef &reques
if (styleHint == QFont::AnyStyle && request.fixedPitch)
styleHint = QFont::TypeWriter;
- fallbacks += fallbacksForFamily(family->name, QFont::Style(style->key.style), styleHint, QChar::Script(script));
+ fallbacks += fallbacksForFamily(family->name,
+ QFont::Style(style->key.style),
+ styleHint,
+ QFontDatabasePrivate::ExtendedScript(script));
pfMultiEngine->setFallbackFamiliesList(fallbacks);
}
@@ -877,8 +890,10 @@ unsigned int QFontDatabasePrivate::bestFoundry(int script, unsigned int score, i
desc->style = nullptr;
desc->size = nullptr;
-
- qCDebug(lcFontMatch, " REMARK: looking for best foundry for family '%s' [%d]", family->name.toLatin1().constData(), family->count);
+ qCDebug(lcFontMatch, " REMARK: looking for best foundry for family '%s'%s [%d]",
+ family->name.toLatin1().constData(),
+ family->colorFont ? " (color font)" : "",
+ family->count);
for (int x = 0; x < family->count; ++x) {
QtFontFoundry *foundry = family->foundries[x];
@@ -1068,6 +1083,10 @@ int QFontDatabasePrivate::match(int script, const QFontDef &request, const QStri
if (writingSystem != QFontDatabase::Any && !familySupportsWritingSystem(test.family, writingSystem))
continue;
+ // Check if we require a color font and check for match
+ if (script == QFontDatabasePrivate::Script_Emoji && !test.family->colorFont)
+ continue;
+
// as we know the script is supported, we can be sure
// to find a matching font here.
unsigned int newscore =
@@ -2202,6 +2221,48 @@ bool QFontDatabasePrivate::isApplicationFont(const QString &fileName)
return false;
}
+void QFontDatabasePrivate::setApplicationFallbackFontFamilies(ExtendedScript script, const QStringList &familyNames)
+{
+ applicationFallbackFontFamiliesHash[script] = familyNames;
+
+ QFontCache::instance()->clear();
+ fallbacksCache.clear();
+}
+
+QStringList QFontDatabasePrivate::applicationFallbackFontFamilies(ExtendedScript script)
+{
+ return applicationFallbackFontFamiliesHash.value(script);
+}
+
+bool QFontDatabasePrivate::removeApplicationFallbackFontFamily(ExtendedScript script, const QString &familyName)
+{
+ auto it = applicationFallbackFontFamiliesHash.find(script);
+ if (it != applicationFallbackFontFamiliesHash.end()) {
+ if (it->removeAll(familyName) > 0) {
+ if (it->isEmpty())
+ it = applicationFallbackFontFamiliesHash.erase(it);
+ QFontCache::instance()->clear();
+ fallbacksCache.clear();
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void QFontDatabasePrivate::addApplicationFallbackFontFamily(ExtendedScript script, const QString &familyName)
+{
+ auto it = applicationFallbackFontFamiliesHash.find(script);
+ if (it == applicationFallbackFontFamiliesHash.end())
+ it = applicationFallbackFontFamiliesHash.insert(script, QStringList{});
+
+ it->prepend(familyName);
+
+ QFontCache::instance()->clear();
+ fallbacksCache.clear();
+}
+
+
/*!
\since 4.2
@@ -2398,7 +2459,7 @@ void QFontDatabase::addApplicationFallbackFontFamily(QChar::Script script, const
{
QMutexLocker locker(fontDatabaseMutex());
- if (script < QChar::Script_Common) {
+ if (script < QChar::Script_Common || script >= QChar::ScriptCount) {
qCWarning(lcFontDb) << "Invalid script passed to addApplicationFallbackFontFamily:" << script;
return;
}
@@ -2407,14 +2468,7 @@ void QFontDatabase::addApplicationFallbackFontFamily(QChar::Script script, const
script = QChar::Script_Common;
auto *db = QFontDatabasePrivate::instance();
- auto it = db->applicationFallbackFontFamilies.find(script);
- if (it == db->applicationFallbackFontFamilies.end())
- it = db->applicationFallbackFontFamilies.insert(script, QStringList{});
-
- it->prepend(familyName);
-
- QFontCache::instance()->clear();
- db->fallbacksCache.clear();
+ db->addApplicationFallbackFontFamily(QFontDatabasePrivate::ExtendedScript(script), familyName);
}
/*!
@@ -2431,7 +2485,7 @@ bool QFontDatabase::removeApplicationFallbackFontFamily(QChar::Script script, co
{
QMutexLocker locker(fontDatabaseMutex());
- if (script < QChar::Script_Common) {
+ if (script < QChar::Script_Common || script >= QChar::ScriptCount) {
qCWarning(lcFontDb) << "Invalid script passed to removeApplicationFallbackFontFamily:" << script;
return false;
}
@@ -2440,18 +2494,8 @@ bool QFontDatabase::removeApplicationFallbackFontFamily(QChar::Script script, co
script = QChar::Script_Common;
auto *db = QFontDatabasePrivate::instance();
- auto it = db->applicationFallbackFontFamilies.find(script);
- if (it != db->applicationFallbackFontFamilies.end()) {
- if (it->removeAll(familyName) > 0) {
- if (it->isEmpty())
- it = db->applicationFallbackFontFamilies.erase(it);
- QFontCache::instance()->clear();
- db->fallbacksCache.clear();
- return true;
- }
- }
-
- return false;
+ return db->removeApplicationFallbackFontFamily(QFontDatabasePrivate::ExtendedScript(script),
+ familyName);
}
/*!
@@ -2471,7 +2515,7 @@ void QFontDatabase::setApplicationFallbackFontFamilies(QChar::Script script, con
{
QMutexLocker locker(fontDatabaseMutex());
- if (script < QChar::Script_Common) {
+ if (script < QChar::Script_Common || script >= QChar::ScriptCount) {
qCWarning(lcFontDb) << "Invalid script passed to setApplicationFallbackFontFamilies:" << script;
return;
}
@@ -2480,10 +2524,8 @@ void QFontDatabase::setApplicationFallbackFontFamilies(QChar::Script script, con
script = QChar::Script_Common;
auto *db = QFontDatabasePrivate::instance();
- db->applicationFallbackFontFamilies[script] = familyNames;
-
- QFontCache::instance()->clear();
- db->fallbacksCache.clear();
+ db->setApplicationFallbackFontFamilies(QFontDatabasePrivate::ExtendedScript(script),
+ familyNames);
}
/*!
@@ -2498,11 +2540,81 @@ QStringList QFontDatabase::applicationFallbackFontFamilies(QChar::Script script)
{
QMutexLocker locker(fontDatabaseMutex());
+ if (script >= QChar::ScriptCount) {
+ qCWarning(lcFontDb) << "Invalid script passed to applicationFallbackFontFamilies:" << script;
+ return QStringList{};
+ }
+
if (script == QChar::Script_Latin)
script = QChar::Script_Common;
auto *db = QFontDatabasePrivate::instance();
- return db->applicationFallbackFontFamilies.value(script);
+ return db->applicationFallbackFontFamilies(QFontDatabasePrivate::ExtendedScript(script));
+}
+
+/*!
+ \since 6.9
+
+ Adds \a familyName as an application-defined emoji font.
+
+ For displaying multi-color emojis or emoji sequences, Qt will by default prefer the system
+ default emoji font. Sometimes the application may want to override the default, either to
+ achieve a specific visual style or to show emojis that are not supported by the system.
+
+ \sa removeApplicationEmojiFontFamily, setApplicationEmojiFontFamilies(), applicationEmojiFontFamilies(), addApplicationFallbackFontFamily()
+*/
+void QFontDatabase::addApplicationEmojiFontFamily(const QString &familyName)
+{
+ QMutexLocker locker(fontDatabaseMutex());
+ auto *db = QFontDatabasePrivate::instance();
+ db->addApplicationFallbackFontFamily(QFontDatabasePrivate::Script_Emoji, familyName);
+}
+
+/*!
+ \since 6.9
+
+ Removes \a familyName from the list of application-defined emoji fonts,
+ provided that it has previously been added with \l{addApplicationEmojiFontFamily()}.
+
+ Returns true if the family name was in the list and false if it was not.
+
+ \sa addApplicationEmojiFontFamily(), setApplicationEmojiFontFamilies(), applicationEmojiFontFamilies(), removeApplicationFallbackFontFamily()
+*/
+bool QFontDatabase::removeApplicationEmojiFontFamily(const QString &familyName)
+{
+ QMutexLocker locker(fontDatabaseMutex());
+ auto *db = QFontDatabasePrivate::instance();
+ return db->removeApplicationFallbackFontFamily(QFontDatabasePrivate::Script_Emoji,
+ familyName);
+}
+
+/*!
+ \since 6.9
+
+ Sets the list of application-defined emoji fonts to \a familyNames.
+
+ \sa addApplicationEmojiFontFamily(), removeApplicationEmojiFontFamily(), applicationEmojiFontFamilies(), setApplicationFallbackFontFamilies()
+*/
+void QFontDatabase::setApplicationEmojiFontFamilies(const QStringList &familyNames)
+{
+ QMutexLocker locker(fontDatabaseMutex());
+ auto *db = QFontDatabasePrivate::instance();
+ db->setApplicationFallbackFontFamilies(QFontDatabasePrivate::Script_Emoji,
+ familyNames);
+}
+
+/*!
+ \since 6.9
+
+ Returns the list of application-defined emoji font families.
+
+ \sa addApplicationEmojiFontFamily(), removeApplicationEmojiFontFamily(), setApplicationEmojiFontFamilies(), applicationFallbackFontFamilies()
+*/
+QStringList QFontDatabase::applicationEmojiFontFamilies()
+{
+ QMutexLocker locker(fontDatabaseMutex());
+ auto *db = QFontDatabasePrivate::instance();
+ return db->applicationFallbackFontFamilies(QFontDatabasePrivate::Script_Emoji);
}
/*!
@@ -2559,12 +2671,27 @@ QFontEngine *QFontDatabasePrivate::findFont(const QFontDef &req,
QtFontDesc desc;
QList<int> blackListed;
unsigned int score = UINT_MAX;
- int index = match(multi ? QChar::Script_Common : script, request, family_name, foundry_name, &desc, blackListed, &score);
+
+ // 1.
+ // We start by looking up the family name and finding the best style/foundry. For multi fonts
+ // we always want the requested font to be on top, even if it does not support the selected
+ // script, since the fallback mechanism will handle this later. For NoFontMerging fonts, we pass
+ // in the script in order to prefer foundries that support the script. If none is found, we will
+ // retry with Script_Common later. Note that Script_Emoji is special. This means the Unicode
+ // algorithm has determined that we should use a color font. If the selected font is not
+ // a color font, we use the fall back mechanism to find one, since we want to prefer *any* color
+ // font over a non-color font in this case.
+ int index = match(multi && script != QFontDatabasePrivate::Script_Emoji ? QChar::Script_Common : script, request, family_name, foundry_name, &desc, blackListed, &score);
+
+ // 2.
+ // If no font was found or it was not a perfect match, we let the database populate family
+ // aliases and try again.
if (score > 0 && QGuiApplicationPrivate::platformIntegration()->fontDatabase()->populateFamilyAliases(family_name)) {
// We populated family aliases (e.g. localized families), so try again
- index = match(multi ? QChar::Script_Common : script, request, family_name, foundry_name, &desc, blackListed);
+ index = match(multi && script != QFontDatabasePrivate::Script_Emoji ? QChar::Script_Common : script, request, family_name, foundry_name, &desc, blackListed);
}
+ // 3.
// If we do not find a match and NoFontMerging is set, use the requested font even if it does
// not support the script.
//
@@ -2589,6 +2716,10 @@ QFontEngine *QFontDatabasePrivate::findFont(const QFontDef &req,
qCDebug(lcFontMatch, " NO MATCH FOUND\n");
}
+ // 4.
+ // If no font matching the script + family exists, we go via the fallback mechanism. This
+ // happens when the family does not exist or if we want a color font and the requested font
+ // is not.
if (!engine) {
if (!requestFamily.isEmpty()) {
QFont::StyleHint styleHint = QFont::StyleHint(request.styleHint);
@@ -2599,32 +2730,49 @@ QFontEngine *QFontDatabasePrivate::findFont(const QFontDef &req,
+ fallbacksForFamily(requestFamily,
QFont::Style(request.style),
styleHint,
- QChar::Script(script));
+ QFontDatabasePrivate::ExtendedScript(script));
if (script > QChar::Script_Common)
fallbacks += QString(); // Find the first font matching the specified script.
- for (int i = 0; !engine && i < fallbacks.size(); i++) {
- QFontDef def = request;
- def.families = QStringList(fallbacks.at(i));
- QFontCache::Key key(def, script, multi ? 1 : 0);
- engine = fontCache->findEngine(key);
- if (!engine) {
- QtFontDesc desc;
- do {
- index = match(multi ? QChar::Script_Common : script, def, def.families.constFirst(), ""_L1, &desc, blackListed);
- if (index >= 0) {
- QFontDef loadDef = def;
- if (loadDef.families.isEmpty())
- loadDef.families = QStringList(desc.family->name);
- engine = loadEngine(script, loadDef, desc.family, desc.foundry, desc.style, desc.size);
- if (engine)
- initFontDef(desc, loadDef, &engine->fontDef, multi);
- else
- blackListed.append(index);
- }
- } while (index >= 0 && !engine);
+ auto findMatchingFallback = [&](int xscript) {
+ for (int i = 0; !engine && i < fallbacks.size(); i++) {
+ QFontDef def = request;
+
+ def.families = QStringList(fallbacks.at(i));
+ QFontCache::Key key(def, xscript, multi ? 1 : 0);
+ engine = fontCache->findEngine(key);
+ if (!engine) {
+ QtFontDesc desc;
+ do {
+ index = match(xscript,
+ def,
+ def.families.constFirst(),
+ ""_L1,
+ &desc,
+ blackListed);
+
+ if (index >= 0) {
+ QFontDef loadDef = def;
+ if (loadDef.families.isEmpty())
+ loadDef.families = QStringList(desc.family->name);
+ engine = loadEngine(xscript, loadDef, desc.family, desc.foundry, desc.style, desc.size);
+ if (engine)
+ initFontDef(desc, loadDef, &engine->fontDef, multi);
+ else
+ blackListed.append(index);
+ }
+ } while (index >= 0 && !engine);
+ }
}
- }
+ };
+
+ findMatchingFallback(multi && script != QFontDatabasePrivate::Script_Emoji ? QChar::Script_Common: script);
+
+ // If we are looking for a color font and there are no color fonts on the system,
+ // we will end up here, for one final pass. This is a rare occurrence so we accept
+ // and extra pass on the fallbacks for this.
+ if (!engine && script == QFontDatabasePrivate::Script_Emoji)
+ findMatchingFallback(QChar::Script_Common);
}
if (!engine)
@@ -2721,7 +2869,7 @@ void QFontDatabasePrivate::load(const QFontPrivate *d, int script)
Q_ASSERT(fe);
if (fe->symbol || (d->request.styleStrategy & QFont::NoFontMerging)) {
- for (int i = 0; i < QChar::ScriptCount; ++i) {
+ for (int i = 0; i < QFontDatabasePrivate::ScriptCount; ++i) {
if (!d->engineData->engines[i]) {
d->engineData->engines[i] = fe;
fe->ref.ref();
@@ -2738,11 +2886,13 @@ QString QFontDatabasePrivate::resolveFontFamilyAlias(const QString &family)
return QGuiApplicationPrivate::platformIntegration()->fontDatabase()->resolveFontFamilyAlias(family);
}
-Q_GUI_EXPORT QStringList qt_sort_families_by_writing_system(QChar::Script script, const QStringList &families)
+Q_GUI_EXPORT QStringList qt_sort_families_by_writing_system(QFontDatabasePrivate::ExtendedScript script,
+ const QStringList &families)
{
size_t writingSystem = qt_writing_system_for_script(script);
- if (writingSystem == QFontDatabase::Any
- || writingSystem >= QFontDatabase::WritingSystemsCount) {
+ if (script != QFontDatabasePrivate::Script_Emoji
+ && (writingSystem == QFontDatabase::Any
+ || writingSystem >= QFontDatabase::WritingSystemsCount)) {
return families;
}
@@ -2762,7 +2912,8 @@ Q_GUI_EXPORT QStringList qt_sort_families_by_writing_system(QChar::Script script
uint order = i;
if (testFamily == nullptr
- || !familySupportsWritingSystem(testFamily, writingSystem)) {
+ || (script == QFontDatabasePrivate::Script_Emoji && !testFamily->colorFont)
+ || (script != QFontDatabasePrivate::Script_Emoji && !familySupportsWritingSystem(testFamily, writingSystem))) {
order |= 1u << 31;
}
diff --git a/src/gui/text/qfontdatabase.h b/src/gui/text/qfontdatabase.h
index 91a53426..cd5cc972 100644
--- a/src/gui/text/qfontdatabase.h
+++ b/src/gui/text/qfontdatabase.h
@@ -117,6 +117,11 @@ public:
static void setApplicationFallbackFontFamilies(QChar::Script, const QStringList &familyNames);
static QStringList applicationFallbackFontFamilies(QChar::Script script);
+ static void addApplicationEmojiFontFamily(const QString &familyName);
+ static bool removeApplicationEmojiFontFamily(const QString &familyName);
+ static void setApplicationEmojiFontFamilies(const QStringList &familyNames);
+ static QStringList applicationEmojiFontFamilies();
+
static QFont systemFont(SystemFont type);
};
diff --git a/src/gui/text/qfontdatabase_p.h b/src/gui/text/qfontdatabase_p.h
index 38e1b4ad..55fa1317 100644
--- a/src/gui/text/qfontdatabase_p.h
+++ b/src/gui/text/qfontdatabase_p.h
@@ -29,7 +29,7 @@ struct QtFontFallbacksCacheKey
QString family;
QFont::Style style;
QFont::StyleHint styleHint;
- QChar::Script script;
+ int script;
};
inline bool operator==(const QtFontFallbacksCacheKey &lhs, const QtFontFallbacksCacheKey &rhs) noexcept
@@ -151,6 +151,7 @@ struct Q_GUI_EXPORT QtFontFamily
:
populated(false),
fixedPitch(false),
+ colorFont(false),
name(n), count(0), foundries(nullptr)
{
memset(writingSystems, 0, sizeof(writingSystems));
@@ -163,6 +164,7 @@ struct Q_GUI_EXPORT QtFontFamily
bool populated : 1;
bool fixedPitch : 1;
+ bool colorFont : 1;
QString name;
QStringList aliases;
@@ -198,13 +200,21 @@ public:
EnsurePopulated
};
+ // Expands QChar::Script by adding a special "script" for emoji sequences
+ enum ExtendedScript {
+ Script_Common = QChar::Script_Common,
+ Script_Latin = QChar::Script_Latin,
+ Script_Emoji = QChar::ScriptCount,
+ ScriptCount
+ };
+
QtFontFamily *family(const QString &f, FamilyRequestFlags flags = EnsurePopulated);
int count;
QtFontFamily **families;
bool populated = false;
- QHash<QChar::Script, QStringList> applicationFallbackFontFamilies;
+ QHash<ExtendedScript, QStringList> applicationFallbackFontFamiliesHash;
QCache<QtFontFallbacksCacheKey, QStringList> fallbacksCache;
struct ApplicationFont {
@@ -232,21 +242,30 @@ public:
int addAppFont(const QByteArray &fontData, const QString &fileName);
bool isApplicationFont(const QString &fileName);
+ void setApplicationFallbackFontFamilies(ExtendedScript script, const QStringList &familyNames);
+ QStringList applicationFallbackFontFamilies(ExtendedScript script);
+ bool removeApplicationFallbackFontFamily(ExtendedScript script, const QString &familyName);
+ void addApplicationFallbackFontFamily(ExtendedScript script, const QString &familyName);
+
static QFontDatabasePrivate *instance();
static void parseFontName(const QString &name, QString &foundry, QString &family);
static QString resolveFontFamilyAlias(const QString &family);
static QFontEngine *findFont(const QFontDef &request,
- int script /* QChar::Script */,
+ int script /* QFontDatabasePrivate::ExtendedScript */,
bool preferScriptOverFamily = false);
- static void load(const QFontPrivate *d, int script /* QChar::Script */);
+ static void load(const QFontPrivate *d, int script /* QFontDatabasePrivate::ExtendedScript */);
static QFontDatabasePrivate *ensureFontDatabase();
void invalidate();
private:
- static int match(int script, const QFontDef &request, const QString &family_name,
- const QString &foundry_name, QtFontDesc *desc, const QList<int> &blacklistedFamilies,
+ static int match(int script,
+ const QFontDef &request,
+ const QString &family_name,
+ const QString &foundry_name,
+ QtFontDesc *desc,
+ const QList<int> &blacklistedFamilies,
unsigned int *resultingScore = nullptr);
static unsigned int bestFoundry(int script, unsigned int score, int styleStrategy,
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index f5aec978..2e5c0624 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -1734,7 +1734,7 @@ QFontEngineMulti::~QFontEngineMulti()
}
}
-QStringList qt_fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script);
+QStringList qt_fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QFontDatabasePrivate::ExtendedScript script);
void QFontEngineMulti::ensureFallbackFamiliesQueried()
{
@@ -1744,7 +1744,7 @@ void QFontEngineMulti::ensureFallbackFamiliesQueried()
setFallbackFamiliesList(qt_fallbacksForFamily(fontDef.families.constFirst(),
QFont::Style(fontDef.style), styleHint,
- QChar::Script(m_script)));
+ QFontDatabasePrivate::ExtendedScript(m_script)));
}
void QFontEngineMulti::setFallbackFamiliesList(const QStringList &fallbackFamilies)
@@ -1792,7 +1792,7 @@ QFontEngine *QFontEngineMulti::loadEngine(int at)
// info about the actual script of the characters may have been discarded,
// so we do not check for writing system support, but instead just load
// the family indiscriminately.
- if (QFontEngine *engine = QFontDatabasePrivate::findFont(request, QChar::Script_Common)) {
+ if (QFontEngine *engine = QFontDatabasePrivate::findFont(request, QFontDatabasePrivate::Script_Common)) {
engine->fontDef.weight = request.weight;
if (request.style > QFont::StyleNormal)
engine->fontDef.style = request.style;
@@ -2363,7 +2363,7 @@ QFontEngine *QFontEngineMulti::createMultiFontEngine(QFontEngine *fe, int script
++it;
}
if (!engine) {
- engine = QGuiApplicationPrivate::instance()->platformIntegration()->fontDatabase()->fontEngineMulti(fe, QChar::Script(script));
+ engine = QGuiApplicationPrivate::instance()->platformIntegration()->fontDatabase()->fontEngineMulti(fe, QFontDatabasePrivate::ExtendedScript(script));
fc->insertEngine(key, engine, /* insertMulti */ !faceIsLocal);
}
Q_ASSERT(engine);
diff --git a/src/gui/text/qplatformfontdatabase.cpp b/src/gui/text/qplatformfontdatabase.cpp
index a146254f..3d3f3c30 100644
--- a/src/gui/text/qplatformfontdatabase.cpp
+++ b/src/gui/text/qplatformfontdatabase.cpp
@@ -24,7 +24,7 @@ Q_LOGGING_CATEGORY(lcQpaFonts, "qt.qpa.fonts")
void qt_registerFont(const QString &familyname, const QString &stylename,
const QString &foundryname, int weight,
QFont::Style style, int stretch, bool antialiased,
- bool scalable, int pixelSize, bool fixedPitch,
+ bool scalable, int pixelSize, bool fixedPitch, bool colorFont,
const QSupportedWritingSystems &writingSystems, void *hanlde);
void qt_registerFontFamily(const QString &familyName);
@@ -55,7 +55,7 @@ bool qt_isFontFamilyPopulated(const QString &familyName);
void QPlatformFontDatabase::registerFont(const QString &familyname, const QString &stylename,
const QString &foundryname, QFont::Weight weight,
QFont::Style style, QFont::Stretch stretch, bool antialiased,
- bool scalable, int pixelSize, bool fixedPitch,
+ bool scalable, int pixelSize, bool fixedPitch, bool colorFont,
const QSupportedWritingSystems &writingSystems, void *usrPtr)
{
if (scalable)
@@ -63,7 +63,7 @@ void QPlatformFontDatabase::registerFont(const QString &familyname, const QStrin
qt_registerFont(familyname, stylename, foundryname, weight, style,
stretch, antialiased, scalable, pixelSize,
- fixedPitch, writingSystems, usrPtr);
+ fixedPitch, colorFont, writingSystems, usrPtr);
}
/*!
@@ -271,7 +271,8 @@ void QPlatformFontDatabase::invalidate()
option to fall back to the fonts given by \a fallbacks if \a fontEngine does not support
a certain character.
*/
-QFontEngineMulti *QPlatformFontDatabase::fontEngineMulti(QFontEngine *fontEngine, QChar::Script script)
+QFontEngineMulti *QPlatformFontDatabase::fontEngineMulti(QFontEngine *fontEngine,
+ QFontDatabasePrivate::ExtendedScript script)
{
return new QFontEngineMulti(fontEngine, script);
}
diff --git a/src/gui/text/qplatformfontdatabase.h b/src/gui/text/qplatformfontdatabase.h
index 3007a118..ba6dfac4 100644
--- a/src/gui/text/qplatformfontdatabase.h
+++ b/src/gui/text/qplatformfontdatabase.h
@@ -20,7 +20,6 @@
#include <QtCore/QList>
#include <QtGui/QFontDatabase>
#include <QtGui/private/qfontengine_p.h>
-#include <QtGui/private/qfont_p.h>
#include <QtGui/private/qfontdatabase_p.h>
QT_BEGIN_NAMESPACE
@@ -72,12 +71,12 @@ public:
virtual void populateFamily(const QString &familyName);
virtual void invalidate();
- virtual QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const;
+ virtual QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QFontDatabasePrivate::ExtendedScript script) const;
virtual QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *font = nullptr);
virtual QFontEngine *fontEngine(const QFontDef &fontDef, void *handle);
virtual QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference);
- virtual QFontEngineMulti *fontEngineMulti(QFontEngine *fontEngine, QChar::Script script);
+ virtual QFontEngineMulti *fontEngineMulti(QFontEngine *fontEngine, QFontDatabasePrivate::ExtendedScript script);
virtual void releaseHandle(void *handle);
virtual QString fontDir() const;
@@ -99,7 +98,7 @@ public:
static void registerFont(const QString &familyname, const QString &stylename,
const QString &foundryname, QFont::Weight weight,
QFont::Style style, QFont::Stretch stretch, bool antialiased,
- bool scalable, int pixelSize, bool fixedPitch,
+ bool scalable, int pixelSize, bool fixedPitch, bool colorFont,
const QSupportedWritingSystems &writingSystems, void *handle);
static void registerFontFamily(const QString &familyName);
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 08512bea..0f10f4a7 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -1409,8 +1409,8 @@ void QTextEngine::shapeText(int item) const
QFont font = f.font();
# if QT_CONFIG(harfbuzz)
kerningEnabled = font.kerning();
- shapingEnabled = QFontEngine::scriptRequiresOpenType(QChar::Script(si.analysis.script))
- || (font.styleStrategy() & QFont::PreferNoShaping) == 0;
+ shapingEnabled = (si.analysis.script < QChar::ScriptCount && QFontEngine::scriptRequiresOpenType(QChar::Script(si.analysis.script)))
+ || (font.styleStrategy() & QFont::PreferNoShaping) == 0;
# endif
wordSpacing = QFixed::fromReal(font.wordSpacing());
letterSpacing = QFixed::fromReal(font.letterSpacing());
@@ -1422,8 +1422,8 @@ void QTextEngine::shapeText(int item) const
QFont font = this->font(si);
#if QT_CONFIG(harfbuzz)
kerningEnabled = font.d->kerning;
- shapingEnabled = QFontEngine::scriptRequiresOpenType(QChar::Script(si.analysis.script))
- || (font.d->request.styleStrategy & QFont::PreferNoShaping) == 0;
+ shapingEnabled = (si.analysis.script < QChar::ScriptCount && QFontEngine::scriptRequiresOpenType(QChar::Script(si.analysis.script)))
+ || (font.d->request.styleStrategy & QFont::PreferNoShaping) == 0;
#endif
letterSpacingIsAbsolute = font.d->letterSpacingIsAbsolute;
letterSpacing = font.d->letterSpacing;
@@ -1615,7 +1615,9 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si,
hb_segment_properties_t props = HB_SEGMENT_PROPERTIES_DEFAULT;
props.direction = si.analysis.bidiLevel % 2 ? HB_DIRECTION_RTL : HB_DIRECTION_LTR;
- QChar::Script script = QChar::Script(si.analysis.script);
+ QChar::Script script = si.analysis.script < QChar::ScriptCount
+ ? QChar::Script(si.analysis.script)
+ : QChar::Script_Common;
props.script = hb_qt_script_to_script(script);
// ### TODO get_default_for_script?
props.language = hb_language_get_default(); // use default language from locale
@@ -1919,8 +1921,38 @@ void QTextEngine::validate() const
layoutData->string.insert(specialData->preeditPosition, specialData->preeditText);
}
+#if !defined(QT_NO_EMOJISEGMENTER)
+namespace {
+
+ enum CharacterCategory {
+ EMOJI = 0,
+ EMOJI_TEXT_PRESENTATION = 1,
+ EMOJI_EMOJI_PRESENTATION = 2,
+ EMOJI_MODIFIER_BASE = 3,
+ EMOJI_MODIFIER = 4,
+ EMOJI_VS_BASE = 5,
+ REGIONAL_INDICATOR = 6,
+ KEYCAP_BASE = 7,
+ COMBINING_ENCLOSING_KEYCAP = 8,
+ COMBINING_ENCLOSING_CIRCLE_BACKSLASH = 9,
+ ZWJ = 10,
+ VS15 = 11,
+ VS16 = 12,
+ TAG_BASE = 13,
+ TAG_SEQUENCE = 14,
+ TAG_TERM = 15,
+ OTHER = 16
+ };
+
+ typedef CharacterCategory *emoji_text_iter_t;
+
+ #include "../../3rdparty/emoji-segmenter/emoji_presentation_scanner.c"
+}
+#endif
+
void QTextEngine::itemize() const
{
+ static bool disableEmojiSegmenter = qEnvironmentVariableIntValue("QT_DISABLE_EMOJI_SEGMENTER") > 0;
validate();
if (layoutData->items.size())
return;
@@ -1950,9 +1982,76 @@ void QTextEngine::itemize() const
}
}
+#if !defined(QT_NO_EMOJISEGMENTER)
+ QVarLengthArray<CharacterCategory> categorizedString;
+ if (!disableEmojiSegmenter) {
+ // Parse emoji sequences
+ for (int i = 0; i < length; ++i) {
+ const QChar &c = string[i];
+ const bool isSurrogate = c.isHighSurrogate() && i < length - 1;
+ const char32_t ucs4 = isSurrogate
+ ? QChar::surrogateToUcs4(c, string[++i])
+ : c.unicode();
+ const QUnicodeTables::Properties *p = QUnicodeTables::properties(ucs4);
+
+ if (ucs4 == 0x20E3)
+ categorizedString.append(CharacterCategory::COMBINING_ENCLOSING_KEYCAP);
+ else if (ucs4 == 0x20E0)
+ categorizedString.append(CharacterCategory::COMBINING_ENCLOSING_CIRCLE_BACKSLASH);
+ else if (ucs4 == 0xFE0E)
+ categorizedString.append(CharacterCategory::VS15);
+ else if (ucs4 == 0xFE0F)
+ categorizedString.append(CharacterCategory::VS16);
+ else if (ucs4 == 0x200D)
+ categorizedString.append(CharacterCategory::ZWJ);
+ else if (ucs4 == 0x1F3F4)
+ categorizedString.append(CharacterCategory::TAG_BASE);
+ else if (ucs4 == 0xE007F)
+ categorizedString.append(CharacterCategory::TAG_TERM);
+ else if ((ucs4 >= 0xE0030 && ucs4 <= 0xE0039) || (ucs4 >= 0xE0061 && ucs4 <= 0xE007A))
+ categorizedString.append(CharacterCategory::TAG_SEQUENCE);
+ else if (ucs4 >= 0x1F1E6 && ucs4 <= 0x1F1FF)
+ categorizedString.append(CharacterCategory::REGIONAL_INDICATOR);
+ // emoji_keycap_sequence = [0-9#*] \x{FE0F 20E3}
+ else if ((ucs4 >= 0x0030 && ucs4 <= 0x0039) || ucs4 == 0x0023 || ucs4 == 0x002A)
+ categorizedString.append(CharacterCategory::KEYCAP_BASE);
+ else if (p->emojiFlags & uchar(QUnicodeTables::EmojiFlags::Emoji_Modifier_Base))
+ categorizedString.append(CharacterCategory::EMOJI_MODIFIER_BASE);
+ else if (p->emojiFlags & uchar(QUnicodeTables::EmojiFlags::Emoji_Modifier))
+ categorizedString.append(CharacterCategory::EMOJI_MODIFIER);
+ else if (p->emojiFlags & uchar(QUnicodeTables::EmojiFlags::Emoji_Presentation))
+ categorizedString.append(CharacterCategory::EMOJI_EMOJI_PRESENTATION);
+ // If it's in the emoji list and doesn't have the emoji presentation, it is text
+ // presentation.
+ else if (p->emojiFlags & uchar(QUnicodeTables::EmojiFlags::Emoji))
+ categorizedString.append(CharacterCategory::EMOJI_TEXT_PRESENTATION);
+ else
+ categorizedString.append(CharacterCategory::OTHER);
+ }
+ }
+#endif
+
const ushort *uc = string;
const ushort *e = uc + length;
+
+#if !defined(QT_NO_EMOJISEGMENTER)
+ const emoji_text_iter_t categoriesStart = categorizedString.data();
+ const emoji_text_iter_t categoriesEnd = categoriesStart + categorizedString.size();
+
+ emoji_text_iter_t categoryIt = categoriesStart;
+
+ bool isEmoji = false;
+ bool hasVs = false;
+ emoji_text_iter_t nextIt = categoryIt;
+#endif
+
while (uc < e) {
+#if !defined(QT_NO_EMOJISEGMENTER)
+ // Find next emoji sequence
+ if (!disableEmojiSegmenter && categoryIt == nextIt)
+ nextIt = scan_emoji_presentation(categoryIt, categoriesEnd, &isEmoji, &hasVs);
+#endif
+
switch (*uc) {
case QChar::ObjectReplacementCharacter:
{
@@ -1992,7 +2091,27 @@ void QTextEngine::itemize() const
default:
analysis->flags = QScriptAnalysis::None;
break;
+ };
+
+#if !defined(QT_NO_EMOJISEGMENTER)
+ if (!disableEmojiSegmenter) {
+ if (isEmoji) {
+ static_assert(QChar::ScriptCount < USHRT_MAX);
+ analysis->script = QFontDatabasePrivate::Script_Emoji;
+ }
+
+ if (QChar::isHighSurrogate(*uc) && (uc + 1) < e && QChar::isLowSurrogate(*(uc + 1))) {
+ if (isEmoji)
+ (analysis + 1)->script = QFontDatabasePrivate::Script_Emoji;
+
+ ++uc;
+ ++analysis;
+ }
+
+ ++categoryIt;
}
+#endif
+
++uc;
++analysis;
}
diff --git a/src/gui/text/unix/qfontconfigdatabase.cpp b/src/gui/text/unix/qfontconfigdatabase.cpp
index f6c59380..7866e341 100644
--- a/src/gui/text/unix/qfontconfigdatabase.cpp
+++ b/src/gui/text/unix/qfontconfigdatabase.cpp
@@ -477,6 +477,12 @@ static void populateFromPattern(FcPattern *pattern,
FcPatternGetDouble (pattern, FC_PIXEL_SIZE, 0, &pixel_size);
bool fixedPitch = spacing_value >= FC_MONO;
+
+ FcBool colorFont = false;
+#ifdef FC_COLOR
+ FcPatternGetBool(pattern, FC_COLOR, 1, &colorFont);
+#endif
+
// Note: stretch should really be an int but registerFont incorrectly uses an enum
QFont::Stretch stretch = QFont::Stretch(stretchFromFcWidth(width_value));
QString styleName = style_value ? QString::fromUtf8((const char *) style_value) : QString();
@@ -492,7 +498,7 @@ static void populateFromPattern(FcPattern *pattern,
applicationFont->properties.append(properties);
}
- QPlatformFontDatabase::registerFont(familyName,styleName,QLatin1StringView((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,writingSystems,fontFile);
+ QPlatformFontDatabase::registerFont(familyName,styleName,QLatin1StringView((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,colorFont,writingSystems,fontFile);
if (applicationFont != nullptr && face != nullptr && db != nullptr) {
db->addNamedInstancesForFace(face,
indexValue,
@@ -502,6 +508,7 @@ static void populateFromPattern(FcPattern *pattern,
stretch,
style,
fixedPitch,
+ colorFont,
writingSystems,
QByteArray((const char*)file_value),
applicationFont->data);
@@ -538,7 +545,7 @@ static void populateFromPattern(FcPattern *pattern,
applicationFont->properties.append(properties);
}
FontFile *altFontFile = new FontFile(*fontFile);
- QPlatformFontDatabase::registerFont(altFamilyName, altStyleName, QLatin1StringView((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,writingSystems,altFontFile);
+ QPlatformFontDatabase::registerFont(altFamilyName, altStyleName, QLatin1StringView((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,colorFont,writingSystems,altFontFile);
} else {
QPlatformFontDatabase::registerAliasToFontFamily(familyName, altFamilyName);
}
@@ -615,9 +622,9 @@ void QFontconfigDatabase::populateFontDatabase()
while (f->qtname) {
QString familyQtName = QString::fromLatin1(f->qtname);
- registerFont(familyQtName,QString(),QString(),QFont::Normal,QFont::StyleNormal,QFont::Unstretched,true,true,0,f->fixed,ws,nullptr);
- registerFont(familyQtName,QString(),QString(),QFont::Normal,QFont::StyleItalic,QFont::Unstretched,true,true,0,f->fixed,ws,nullptr);
- registerFont(familyQtName,QString(),QString(),QFont::Normal,QFont::StyleOblique,QFont::Unstretched,true,true,0,f->fixed,ws,nullptr);
+ registerFont(familyQtName,QString(),QString(),QFont::Normal,QFont::StyleNormal,QFont::Unstretched,true,true,false,0,f->fixed,ws,nullptr);
+ registerFont(familyQtName,QString(),QString(),QFont::Normal,QFont::StyleItalic,QFont::Unstretched,true,true,false,0,f->fixed,ws,nullptr);
+ registerFont(familyQtName,QString(),QString(),QFont::Normal,QFont::StyleOblique,QFont::Unstretched,true,true,false,0,f->fixed,ws,nullptr);
++f;
}
@@ -636,7 +643,7 @@ void QFontconfigDatabase::invalidate()
FcConfigAppFontClear(nullptr);
}
-QFontEngineMulti *QFontconfigDatabase::fontEngineMulti(QFontEngine *fontEngine, QChar::Script script)
+QFontEngineMulti *QFontconfigDatabase::fontEngineMulti(QFontEngine *fontEngine, QFontDatabasePrivate::ExtendedScript script)
{
return new QFontEngineMultiFontConfig(fontEngine, script);
}
@@ -760,7 +767,10 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QByteArray &fontData, qreal p
return engine;
}
-QStringList QFontconfigDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const
+QStringList QFontconfigDatabase::fallbacksForFamily(const QString &family,
+ QFont::Style style,
+ QFont::StyleHint styleHint,
+ QFontDatabasePrivate::ExtendedScript script) const
{
QStringList fallbackFamilies;
FcPattern *pattern = FcPatternCreate();
@@ -773,6 +783,14 @@ QStringList QFontconfigDatabase::fallbacksForFamily(const QString &family, QFont
value.u.s = (const FcChar8 *)cs.data();
FcPatternAdd(pattern,FC_FAMILY,value,true);
+#ifdef FC_COLOR
+ if (script == QFontDatabasePrivate::Script_Emoji) {
+ FcPatternAddBool(pattern, FC_COLOR, true);
+ value.u.s = (const FcChar8 *)"emoji";
+ FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue);
+ }
+#endif
+
int slant_value = FC_SLANT_ROMAN;
if (style == QFont::StyleItalic)
slant_value = FC_SLANT_ITALIC;
@@ -780,8 +798,8 @@ QStringList QFontconfigDatabase::fallbacksForFamily(const QString &family, QFont
slant_value = FC_SLANT_OBLIQUE;
FcPatternAddInteger(pattern, FC_SLANT, slant_value);
- Q_ASSERT(uint(script) < QChar::ScriptCount);
- if (*specialLanguages[script] != '\0') {
+ Q_ASSERT(uint(script) < QFontDatabasePrivate::ScriptCount);
+ if (uint(script) < QChar::ScriptCount && *specialLanguages[script] != '\0') {
FcLangSet *ls = FcLangSetCreate();
FcLangSetAdd(ls, (const FcChar8*)specialLanguages[script]);
FcPatternAddLangSet(pattern, FC_LANG, ls);
diff --git a/src/gui/text/unix/qfontconfigdatabase_p.h b/src/gui/text/unix/qfontconfigdatabase_p.h
index dd7a70a3..40de8919 100644
--- a/src/gui/text/unix/qfontconfigdatabase_p.h
+++ b/src/gui/text/unix/qfontconfigdatabase_p.h
@@ -29,10 +29,14 @@ public:
void populateFontDatabase() override;
void invalidate() override;
bool supportsVariableApplicationFonts() const override;
- QFontEngineMulti *fontEngineMulti(QFontEngine *fontEngine, QChar::Script script) override;
+ QFontEngineMulti *fontEngineMulti(QFontEngine *fontEngine,
+ QFontDatabasePrivate::ExtendedScript script) override;
QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override;
QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) override;
- QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const override;
+ QStringList fallbacksForFamily(const QString &family,
+ QFont::Style style,
+ QFont::StyleHint styleHint,
+ QFontDatabasePrivate::ExtendedScript script) const override;
QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *applicationFont = nullptr) override;
QString resolveFontFamilyAlias(const QString &family) const override;
QFont defaultFont() const override;
diff --git a/src/gui/text/windows/qwindowsdirectwritefontdatabase.cpp b/src/gui/text/windows/qwindowsdirectwritefontdatabase.cpp
index 610cd1d6..f2671b6c 100644
--- a/src/gui/text/windows/qwindowsdirectwritefontdatabase.cpp
+++ b/src/gui/text/windows/qwindowsdirectwritefontdatabase.cpp
@@ -138,9 +138,9 @@ void QWindowsDirectWriteFontDatabase::populateFamily(const QString &familyName)
for (uint j = 0; j < matchingFonts->GetFontCount(); ++j) {
DirectWriteScope<IDWriteFont> font;
if (SUCCEEDED(matchingFonts->GetFont(j, &font))) {
- DirectWriteScope<IDWriteFont1> font1;
- if (!SUCCEEDED(font->QueryInterface(__uuidof(IDWriteFont1),
- reinterpret_cast<void **>(&font1)))) {
+ DirectWriteScope<IDWriteFont2> font2;
+ if (!SUCCEEDED(font->QueryInterface(__uuidof(IDWriteFont2),
+ reinterpret_cast<void **>(&font2)))) {
qCWarning(lcQpaFonts) << "COM object does not support IDWriteFont1";
continue;
}
@@ -149,7 +149,7 @@ void QWindowsDirectWriteFontDatabase::populateFamily(const QString &familyName)
QString englishLocaleFamilyName;
DirectWriteScope<IDWriteFontFamily> fontFamily2;
- if (SUCCEEDED(font1->GetFontFamily(&fontFamily2))) {
+ if (SUCCEEDED(font2->GetFontFamily(&fontFamily2))) {
DirectWriteScope<IDWriteLocalizedStrings> names;
if (SUCCEEDED(fontFamily2->GetFamilyNames(&names))) {
defaultLocaleFamilyName = hasDefaultLocale ? localeString(*names, defaultLocale) : QString();
@@ -162,14 +162,15 @@ void QWindowsDirectWriteFontDatabase::populateFamily(const QString &familyName)
{
DirectWriteScope<IDWriteLocalizedStrings> names;
- if (SUCCEEDED(font1->GetFaceNames(&names))) {
+ if (SUCCEEDED(font2->GetFaceNames(&names))) {
QString defaultLocaleStyleName = hasDefaultLocale ? localeString(*names, defaultLocale) : QString();
QString englishLocaleStyleName = localeString(*names, englishLocale);
- QFont::Stretch stretch = fromDirectWriteStretch(font1->GetStretch());
- QFont::Style style = fromDirectWriteStyle(font1->GetStyle());
- QFont::Weight weight = fromDirectWriteWeight(font1->GetWeight());
- bool fixed = font1->IsMonospacedFont();
+ QFont::Stretch stretch = fromDirectWriteStretch(font2->GetStretch());
+ QFont::Style style = fromDirectWriteStyle(font2->GetStyle());
+ QFont::Weight weight = fromDirectWriteWeight(font2->GetWeight());
+ bool fixed = font2->IsMonospacedFont();
+ bool color = font2->IsColorFont();
qCDebug(lcQpaFonts) << "Family" << familyName << "has english variant" << englishLocaleStyleName << ", in default locale:" << defaultLocaleStyleName << stretch << style << weight << fixed;
@@ -190,6 +191,7 @@ void QWindowsDirectWriteFontDatabase::populateFamily(const QString &familyName)
scalable,
size,
fixed,
+ color,
writingSystems,
new FontHandle(*face, englishLocaleFamilyName));
}
@@ -205,6 +207,7 @@ void QWindowsDirectWriteFontDatabase::populateFamily(const QString &familyName)
scalable,
size,
fixed,
+ color,
writingSystems,
new FontHandle(*face, defaultLocaleFamilyName));
}
@@ -290,18 +293,20 @@ bool QWindowsDirectWriteFontDatabase::populateFamilyAliases(const QString &missi
DirectWriteScope<IDWriteFont> font;
if (SUCCEEDED(fontCollection->GetFontFromFontFace(*directWriteFontFace, &font))) {
- DirectWriteScope<IDWriteFont1> font1;
- if (SUCCEEDED(font->QueryInterface(__uuidof(IDWriteFont1),
- reinterpret_cast<void **>(&font1)))) {
+ DirectWriteScope<IDWriteFont2> font2;
+ if (SUCCEEDED(font->QueryInterface(__uuidof(IDWriteFont2),
+ reinterpret_cast<void **>(&font2)))) {
DirectWriteScope<IDWriteLocalizedStrings> names;
- if (SUCCEEDED(font1->GetFaceNames(&names))) {
+ if (SUCCEEDED(font2->GetFaceNames(&names))) {
wchar_t englishLocale[] = L"en-us";
QString englishLocaleStyleName = localeString(*names, englishLocale);
- QFont::Stretch stretch = fromDirectWriteStretch(font1->GetStretch());
- QFont::Style style = fromDirectWriteStyle(font1->GetStyle());
- QFont::Weight weight = fromDirectWriteWeight(font1->GetWeight());
- bool fixed = font1->IsMonospacedFont();
+ QFont::Stretch stretch = fromDirectWriteStretch(font2->GetStretch());
+ QFont::Style style = fromDirectWriteStyle(font2->GetStyle());
+ QFont::Weight weight = fromDirectWriteWeight(font2->GetWeight());
+ bool fixed = font2->IsMonospacedFont();
+ bool isColorFont = font2->IsColorFont();
+
QSupportedWritingSystems writingSystems = supportedWritingSystems(*directWriteFontFace);
@@ -316,6 +321,7 @@ bool QWindowsDirectWriteFontDatabase::populateFamilyAliases(const QString &missi
true,
0xffff,
fixed,
+ isColorFont,
writingSystems,
new FontHandle(*directWriteFontFace, missingFamily));
@@ -407,9 +413,13 @@ QFontEngine *QWindowsDirectWriteFontDatabase::fontEngine(const QFontDef &fontDef
return fontEngine;
}
-QStringList QWindowsDirectWriteFontDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const
+QStringList QWindowsDirectWriteFontDatabase::fallbacksForFamily(const QString &family,
+ QFont::Style style,
+ QFont::StyleHint styleHint,
+ QFontDatabasePrivate::ExtendedScript script) const
{
QStringList result;
+ result.append(QWindowsFontDatabaseBase::familiesForScript(script));
result.append(familyForStyleHint(styleHint));
result.append(extraTryFontsForFamily(family));
result.append(QPlatformFontDatabase::fallbacksForFamily(family, style, styleHint, script));
@@ -516,6 +526,7 @@ QStringList QWindowsDirectWriteFontDatabase::addApplicationFont(const QByteArray
QFont::Style style = fromDirectWriteStyle(face3->GetStyle());
QFont::Weight weight = fromDirectWriteWeight(face3->GetWeight());
bool fixed = face3->IsMonospacedFont();
+ bool color = face3->IsColorFont();
qCDebug(lcQpaFonts) << "\tFont names:" << englishLocaleFamilyName << ", " << defaultLocaleFamilyName
<< ", style names:" << englishLocaleStyleName << ", " << defaultLocaleStyleName
@@ -545,6 +556,7 @@ QStringList QWindowsDirectWriteFontDatabase::addApplicationFont(const QByteArray
scalable,
size,
fixed,
+ color,
writingSystems,
new FontHandle(face, englishLocaleFamilyName));
}
@@ -570,6 +582,7 @@ QStringList QWindowsDirectWriteFontDatabase::addApplicationFont(const QByteArray
scalable,
size,
fixed,
+ color,
writingSystems,
new FontHandle(face, defaultLocaleFamilyName));
}
@@ -595,6 +608,7 @@ QStringList QWindowsDirectWriteFontDatabase::addApplicationFont(const QByteArray
scalable,
size,
fixed,
+ color,
writingSystems,
new FontHandle(face, englishLocaleGdiCompatibleFamilyName));
}
@@ -620,6 +634,7 @@ QStringList QWindowsDirectWriteFontDatabase::addApplicationFont(const QByteArray
scalable,
size,
fixed,
+ color,
writingSystems,
new FontHandle(face, defaultLocaleGdiCompatibleFamilyName));
}
@@ -645,6 +660,7 @@ QStringList QWindowsDirectWriteFontDatabase::addApplicationFont(const QByteArray
scalable,
size,
fixed,
+ color,
writingSystems,
new FontHandle(face, englishLocaleTypographicFamilyName));
}
@@ -670,6 +686,7 @@ QStringList QWindowsDirectWriteFontDatabase::addApplicationFont(const QByteArray
scalable,
size,
fixed,
+ color,
writingSystems,
new FontHandle(face, defaultLocaleTypographicFamilyName));
}
diff --git a/src/gui/text/windows/qwindowsdirectwritefontdatabase_p.h b/src/gui/text/windows/qwindowsdirectwritefontdatabase_p.h
index 3e5e9663..1ea01cbd 100644
--- a/src/gui/text/windows/qwindowsdirectwritefontdatabase_p.h
+++ b/src/gui/text/windows/qwindowsdirectwritefontdatabase_p.h
@@ -43,7 +43,10 @@ public:
bool populateFamilyAliases(const QString &missingFamily) override;
QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override;
QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) override;
- QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const override;
+ QStringList fallbacksForFamily(const QString &family,
+ QFont::Style style,
+ QFont::StyleHint styleHint,
+ QFontDatabasePrivate::ExtendedScript script) const override;
QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *font = nullptr) override;
bool isPrivateFontFamily(const QString &family) const override;
diff --git a/src/gui/text/windows/qwindowsfontdatabase.cpp b/src/gui/text/windows/qwindowsfontdatabase.cpp
index 772620d6..73814c6a 100644
--- a/src/gui/text/windows/qwindowsfontdatabase.cpp
+++ b/src/gui/text/windows/qwindowsfontdatabase.cpp
@@ -541,19 +541,19 @@ static bool addFontToDatabase(QString familyName,
const bool wasPopulated = QPlatformFontDatabase::isFamilyPopulated(familyName);
QPlatformFontDatabase::registerFont(familyName, styleName, foundryName, weight,
- style, stretch, antialias, scalable, size, fixed, writingSystems, new QWindowsFontDatabase::FontHandle(faceName));
+ style, stretch, antialias, scalable, size, fixed, false, writingSystems, new QWindowsFontDatabase::FontHandle(faceName));
// add fonts windows can generate for us:
if (weight <= QFont::DemiBold && styleName.isEmpty())
QPlatformFontDatabase::registerFont(familyName, QString(), foundryName, QFont::Bold,
- style, stretch, antialias, scalable, size, fixed, writingSystems, new QWindowsFontDatabase::FontHandle(faceName));
+ style, stretch, antialias, scalable, size, fixed, false, writingSystems, new QWindowsFontDatabase::FontHandle(faceName));
if (style != QFont::StyleItalic && styleName.isEmpty())
QPlatformFontDatabase::registerFont(familyName, QString(), foundryName, weight,
- QFont::StyleItalic, stretch, antialias, scalable, size, fixed, writingSystems, new QWindowsFontDatabase::FontHandle(faceName));
+ QFont::StyleItalic, stretch, antialias, scalable, size, fixed, false, writingSystems, new QWindowsFontDatabase::FontHandle(faceName));
if (weight <= QFont::DemiBold && style != QFont::StyleItalic && styleName.isEmpty())
QPlatformFontDatabase::registerFont(familyName, QString(), foundryName, QFont::Bold,
- QFont::StyleItalic, stretch, antialias, scalable, size, fixed, writingSystems, new QWindowsFontDatabase::FontHandle(faceName));
+ QFont::StyleItalic, stretch, antialias, scalable, size, fixed, false, writingSystems, new QWindowsFontDatabase::FontHandle(faceName));
// We came here from populating a different font family, so we have
// to ensure the entire typographic family is populated before we
@@ -567,7 +567,7 @@ static bool addFontToDatabase(QString familyName,
if (!subFamilyName.isEmpty() && familyName != subFamilyName) {
QPlatformFontDatabase::registerFont(subFamilyName, subFamilyStyle, foundryName, weight,
- style, stretch, antialias, scalable, size, fixed, writingSystems, new QWindowsFontDatabase::FontHandle(faceName));
+ style, stretch, antialias, scalable, size, fixed, false, writingSystems, new QWindowsFontDatabase::FontHandle(faceName));
}
if (!englishName.isEmpty() && englishName != familyName)
@@ -1162,9 +1162,13 @@ void QWindowsFontDatabase::refUniqueFont(const QString &uniqueFont)
++it->refCount;
}
-QStringList QWindowsFontDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const
+QStringList QWindowsFontDatabase::fallbacksForFamily(const QString &family,
+ QFont::Style style,
+ QFont::StyleHint styleHint,
+ QFontDatabasePrivate::ExtendedScript script) const
{
QStringList result;
+ result.append(QWindowsFontDatabaseBase::familiesForScript(script));
result.append(familyForStyleHint(styleHint));
result.append(m_eudcFonts);
result.append(extraTryFontsForFamily(family));
diff --git a/src/gui/text/windows/qwindowsfontdatabase_ft.cpp b/src/gui/text/windows/qwindowsfontdatabase_ft.cpp
index 0604a85e..18d90261 100644
--- a/src/gui/text/windows/qwindowsfontdatabase_ft.cpp
+++ b/src/gui/text/windows/qwindowsfontdatabase_ft.cpp
@@ -243,24 +243,24 @@ static bool addFontToDatabase(QString familyName,
value.prepend(QFile::decodeName(qgetenv("windir") + "\\Fonts\\"));
QPlatformFontDatabase::registerFont(familyName, styleName, foundryName, weight, style, stretch,
- antialias, scalable, size, fixed, writingSystems, createFontFile(value, index));
+ antialias, scalable, size, fixed, false, writingSystems, createFontFile(value, index));
// add fonts windows can generate for us:
if (weight <= QFont::DemiBold && styleName.isEmpty())
QPlatformFontDatabase::registerFont(familyName, QString(), foundryName, QFont::Bold, style, stretch,
- antialias, scalable, size, fixed, writingSystems, createFontFile(value, index));
+ antialias, scalable, size, fixed, false, writingSystems, createFontFile(value, index));
if (style != QFont::StyleItalic && styleName.isEmpty())
QPlatformFontDatabase::registerFont(familyName, QString(), foundryName, weight, QFont::StyleItalic, stretch,
- antialias, scalable, size, fixed, writingSystems, createFontFile(value, index));
+ antialias, scalable, size, fixed, false, writingSystems, createFontFile(value, index));
if (weight <= QFont::DemiBold && style != QFont::StyleItalic && styleName.isEmpty())
QPlatformFontDatabase::registerFont(familyName, QString(), foundryName, QFont::Bold, QFont::StyleItalic, stretch,
- antialias, scalable, size, fixed, writingSystems, createFontFile(value, index));
+ antialias, scalable, size, fixed, false, writingSystems, createFontFile(value, index));
if (!subFamilyName.isEmpty() && familyName != subFamilyName) {
QPlatformFontDatabase::registerFont(subFamilyName, subFamilyStyle, foundryName, weight,
- style, stretch, antialias, scalable, size, fixed, writingSystems, createFontFile(value, index));
+ style, stretch, antialias, scalable, size, fixed, false, writingSystems, createFontFile(value, index));
}
if (!englishName.isEmpty() && englishName != familyName)
@@ -397,9 +397,13 @@ QFontEngine *QWindowsFontDatabaseFT::fontEngine(const QByteArray &fontData, qrea
return fe;
}
-QStringList QWindowsFontDatabaseFT::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const
+QStringList QWindowsFontDatabaseFT::fallbacksForFamily(const QString &family,
+ QFont::Style style,
+ QFont::StyleHint styleHint,
+ QFontDatabasePrivate::ExtendedScript script) const
{
QStringList result;
+ result.append(QWindowsFontDatabaseBase::familiesForScript(script));
result.append(QWindowsFontDatabaseBase::familyForStyleHint(styleHint));
result.append(QWindowsFontDatabaseBase::extraTryFontsForFamily(family));
result.append(QFreeTypeFontDatabase::fallbacksForFamily(family, style, styleHint, script));
diff --git a/src/gui/text/windows/qwindowsfontdatabase_ft_p.h b/src/gui/text/windows/qwindowsfontdatabase_ft_p.h
index 381a7be4..1b8fb9dd 100644
--- a/src/gui/text/windows/qwindowsfontdatabase_ft_p.h
+++ b/src/gui/text/windows/qwindowsfontdatabase_ft_p.h
@@ -33,7 +33,7 @@ public:
QStringList fallbacksForFamily(const QString &family, QFont::Style style,
QFont::StyleHint styleHint,
- QChar::Script script) const override;
+ QFontDatabasePrivate::ExtendedScript script) const override;
QString fontDir() const override;
QFont defaultFont() const override;
diff --git a/src/gui/text/windows/qwindowsfontdatabase_p.h b/src/gui/text/windows/qwindowsfontdatabase_p.h
index 0c99c91f..92628726 100644
--- a/src/gui/text/windows/qwindowsfontdatabase_p.h
+++ b/src/gui/text/windows/qwindowsfontdatabase_p.h
@@ -51,7 +51,7 @@ public:
bool populateFamilyAliases(const QString &missingFamily) override;
QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override;
QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) override;
- QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const override;
+ QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QFontDatabasePrivate::ExtendedScript script) const override;
QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *applicationFont = nullptr) override;
void releaseHandle(void *handle) override;
QString fontDir() const override;
diff --git a/src/gui/text/windows/qwindowsfontdatabasebase.cpp b/src/gui/text/windows/qwindowsfontdatabasebase.cpp
index 84e619b0..fdaf9240 100644
--- a/src/gui/text/windows/qwindowsfontdatabasebase.cpp
+++ b/src/gui/text/windows/qwindowsfontdatabasebase.cpp
@@ -873,6 +873,14 @@ QFontEngine *QWindowsFontDatabaseBase::fontEngine(const QByteArray &fontData, qr
return fontEngine;
}
+QStringList QWindowsFontDatabaseBase::familiesForScript(QFontDatabasePrivate::ExtendedScript script)
+{
+ if (script == QFontDatabasePrivate::Script_Emoji)
+ return QStringList{} << QStringLiteral("Segoe UI Emoji");
+ else
+ return QStringList{};
+}
+
QString QWindowsFontDatabaseBase::familyForStyleHint(QFont::StyleHint styleHint)
{
switch (styleHint) {
diff --git a/src/gui/text/windows/qwindowsfontdatabasebase_p.h b/src/gui/text/windows/qwindowsfontdatabasebase_p.h
index 55a33635..beb9b52f 100644
--- a/src/gui/text/windows/qwindowsfontdatabasebase_p.h
+++ b/src/gui/text/windows/qwindowsfontdatabasebase_p.h
@@ -75,6 +75,7 @@ public:
static QString familyForStyleHint(QFont::StyleHint styleHint);
static QStringList extraTryFontsForFamily(const QString &family);
+ static QStringList familiesForScript(QFontDatabasePrivate::ExtendedScript script);
class FontTable{};
class EmbeddedFont
diff --git a/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp b/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp
index 82a10dac..3c174f04 100644
--- a/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp
+++ b/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp
@@ -45,10 +45,15 @@ void QAndroidPlatformFontDatabase::populateFontDatabase()
QStringList QAndroidPlatformFontDatabase::fallbacksForFamily(const QString &family,
QFont::Style style,
QFont::StyleHint styleHint,
- QChar::Script script) const
+ QFontDatabasePrivate::ExtendedScript script) const
{
QStringList result;
+ if (script == QFontDatabasePrivate::Script_Emoji) {
+ result.append(QStringLiteral("Noto Color Emoji"));
+ result.append(QStringLiteral("Noto Color Emoji Flags"));
+ }
+
// Prepend CJK fonts by the locale.
QLocale locale = QLocale::system();
switch (locale.language()) {
diff --git a/src/plugins/platforms/android/qandroidplatformfontdatabase.h b/src/plugins/platforms/android/qandroidplatformfontdatabase.h
index 23561e22..1150a298 100644
--- a/src/plugins/platforms/android/qandroidplatformfontdatabase.h
+++ b/src/plugins/platforms/android/qandroidplatformfontdatabase.h
@@ -17,7 +17,7 @@ public:
QStringList fallbacksForFamily(const QString &family,
QFont::Style style,
QFont::StyleHint styleHint,
- QChar::Script script) const override;
+ QFontDatabasePrivate::ExtendedScript script) const override;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wasm/qwasmfontdatabase.cpp b/src/plugins/platforms/wasm/qwasmfontdatabase.cpp
index 3f3dc10f..e1882dd1 100644
--- a/src/plugins/platforms/wasm/qwasmfontdatabase.cpp
+++ b/src/plugins/platforms/wasm/qwasmfontdatabase.cpp
@@ -319,7 +319,7 @@ QFontEngine *QWasmFontDatabase::fontEngine(const QFontDef &fontDef, void *handle
QStringList QWasmFontDatabase::fallbacksForFamily(const QString &family, QFont::Style style,
QFont::StyleHint styleHint,
- QChar::Script script) const
+ QFontDatabasePrivate::ExtendedScript script) const
{
QStringList fallbacks
= QFreeTypeFontDatabase::fallbacksForFamily(family, style, styleHint, script);
diff --git a/src/plugins/platforms/wasm/qwasmfontdatabase.h b/src/plugins/platforms/wasm/qwasmfontdatabase.h
index a1c8f1ff..aea3b955 100644
--- a/src/plugins/platforms/wasm/qwasmfontdatabase.h
+++ b/src/plugins/platforms/wasm/qwasmfontdatabase.h
@@ -20,7 +20,7 @@ public:
QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override;
QStringList fallbacksForFamily(const QString &family, QFont::Style style,
QFont::StyleHint styleHint,
- QChar::Script script) const override;
+ QFontDatabasePrivate::ExtendedScript script) const override;
void releaseHandle(void *handle) override;
QFont defaultFont() const override;
diff --git a/tests/auto/gui/text/qfontdatabase/CMakeLists.txt b/tests/auto/gui/text/qfontdatabase/CMakeLists.txt
index 0cb6e8d7..03e4bdce 100644
--- a/tests/auto/gui/text/qfontdatabase/CMakeLists.txt
+++ b/tests/auto/gui/text/qfontdatabase/CMakeLists.txt
@@ -49,6 +49,7 @@ set(testdata_resource_files
"LED_REAL.TTF"
"QtTestLimitedFont-Regular.ttf"
"QtTestFallbackFont-Regular.ttf"
+ "QtEmojiTestFont-Regular.ttf"
)
qt_internal_add_resource(tst_qfontdatabase "testdata"
diff --git a/tests/auto/gui/text/qfontdatabase/QtEmojiTestFont-Regular.ttf b/tests/auto/gui/text/qfontdatabase/QtEmojiTestFont-Regular.ttf
new file mode 100644
index 00000000..e69de29b
diff --git a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
index 8733f64d..5773363d 100644
--- a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
+++ b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
@@ -71,6 +71,7 @@ private slots:
#endif
void addApplicationFontFallback();
+ void addApplicationEmojiFontFamily();
private:
QString m_ledFont;
@@ -80,6 +81,7 @@ private:
QString m_testFontVariable;
QString m_limitedFont;
QString m_fallbackFont;
+ QString m_emojiFont;
};
tst_QFontDatabase::tst_QFontDatabase()
@@ -95,6 +97,7 @@ void tst_QFontDatabase::initTestCase()
m_testFontVariable = QFINDTESTDATA("testfont_variable.ttf");
m_limitedFont = QFINDTESTDATA("QtTestLimitedFont-Regular.ttf");
m_fallbackFont = QFINDTESTDATA("QtTestFallbackFont-Regular.ttf");
+ m_emojiFont = QFINDTESTDATA("QtEmojiTestFont-Regular.ttf");
QVERIFY(!m_ledFont.isEmpty());
QVERIFY(!m_testFont.isEmpty());
QVERIFY(!m_testFontCondensed.isEmpty());
@@ -102,6 +105,7 @@ void tst_QFontDatabase::initTestCase()
QVERIFY(!m_testFontVariable.isEmpty());
QVERIFY(!m_limitedFont.isEmpty());
QVERIFY(!m_fallbackFont.isEmpty());
+ QVERIFY(!m_emojiFont.isEmpty());
}
void tst_QFontDatabase::styles_data()
@@ -760,5 +764,65 @@ void tst_QFontDatabase::addApplicationFontFallback()
QVERIFY(QFontDatabase::removeApplicationFallbackFontFamily(QChar::Script_Latin, u"QtTestFallbackFont"_s));
}
+void tst_QFontDatabase::addApplicationEmojiFontFamily()
+{
+ int id = -1;
+ auto cleanup = qScopeGuard([&id] {
+ if (id >= 0)
+ QFontDatabase::removeApplicationFont(id);
+ });
+
+ id = QFontDatabase::addApplicationFont(m_emojiFont);
+ QVERIFY(id >= 0);
+
+ QStringList families = QFontDatabase::applicationFontFamilies(id);
+ QVERIFY(families.size() > 0);
+
+ const QChar airplane(0x2708);
+ const QChar vs16(0xfe0f);
+
+ QFontDatabase::addApplicationEmojiFontFamily(families.first());
+
+ // Get emoji version of regular airplane symbol
+ {
+ QTextLayout layout;
+ layout.setText(QString(airplane) + vs16);
+ layout.beginLayout();
+ layout.createLine();
+ layout.endLayout();
+
+ QList<QGlyphRun> glyphRuns = layout.glyphRuns();
+ QCOMPARE(glyphRuns.size(), 1);
+
+ QGlyphRun glyphRun = glyphRuns.first();
+ QList<quint32> glyphIndexes = glyphRun.glyphIndexes();
+
+ QCOMPARE(glyphIndexes.size(), 1);
+ QCOMPARE(glyphIndexes.at(0), 237);
+ }
+
+ const QChar asterisk('*');
+ const QChar enclosingKeyCap(0x20e3);
+
+ // Get emoji keycap ligature (vs16 should be ignored when evaluating ligature substitution)
+ {
+ QTextLayout layout;
+ layout.setText(QString(asterisk) + vs16 + enclosingKeyCap);
+ layout.beginLayout();
+ layout.createLine();
+ layout.endLayout();
+
+ QList<QGlyphRun> glyphRuns = layout.glyphRuns();
+ QCOMPARE(glyphRuns.size(), 1);
+
+ QGlyphRun glyphRun = glyphRuns.first();
+ QList<quint32> glyphIndexes = glyphRun.glyphIndexes();
+
+ QCOMPARE(glyphIndexes.size(), 1);
+ QCOMPARE(glyphIndexes.at(0), 238);
+ }
+
+}
+
QTEST_MAIN(tst_QFontDatabase)
#include "tst_qfontdatabase.moc"
diff --git a/tests/manual/emojisequences/CMakeLists.txt b/tests/manual/emojisequences/CMakeLists.txt
new file mode 100644
index 00000000..c367bb12
--- /dev/null
+++ b/tests/manual/emojisequences/CMakeLists.txt
@@ -0,0 +1,34 @@
+# Copyright (C) 2024 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.16)
+project(emojisequences LANGUAGES CXX)
+
+find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
+find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST)
+
+qt_standard_project_setup()
+
+qt_internal_add_manual_test(emojisequences
+ GUI
+ SOURCES
+ main.cpp
+ mainwindow.h mainwindow.cpp
+ mainwindow.ui
+ LIBRARIES
+ Qt::Gui
+ Qt::Widgets
+ ENABLE_AUTOGEN_TOOLS
+ uic
+)
+
+set(emojisequences_resource_files
+ "emoji-test.txt"
+)
+
+qt_internal_add_resource(emojisequences "emojisequences"
+ PREFIX
+ "/"
+ FILES
+ ${emojisequences_resource_files}
+)
diff --git a/tests/manual/emojisequences/emoji-test.txt b/tests/manual/emojisequences/emoji-test.txt
new file mode 100644
index 00000000..3357ccf8
--- /dev/null
+++ b/tests/manual/emojisequences/emoji-test.txt
@@ -0,0 +1,3768 @@
+1F600 ; fully-qualified # 😀 grinning face
+1F601 ; fully-qualified # 😁 beaming face with smiling eyes
+1F602 ; fully-qualified # 😂 face with tears of joy
+1F923 ; fully-qualified # 🤣 rolling on the floor laughing
+1F603 ; fully-qualified # 😃 grinning face with big eyes
+1F604 ; fully-qualified # 😄 grinning face with smiling eyes
+1F605 ; fully-qualified # 😅 grinning face with sweat
+1F606 ; fully-qualified # 😆 grinning squinting face
+1F609 ; fully-qualified # 😉 winking face
+1F60A ; fully-qualified # 😊 smiling face with smiling eyes
+1F60B ; fully-qualified # 😋 face savoring food
+1F60E ; fully-qualified # 😎 smiling face with sunglasses
+1F60D ; fully-qualified # 😍 smiling face with heart-eyes
+1F618 ; fully-qualified # 😘 face blowing a kiss
+1F970 ; fully-qualified # 🥰 smiling face with 3 hearts
+1F617 ; fully-qualified # 😗 kissing face
+1F619 ; fully-qualified # 😙 kissing face with smiling eyes
+1F61A ; fully-qualified # 😚 kissing face with closed eyes
+263A FE0F ; fully-qualified # ☺️ smiling face
+263A ; non-fully-qualified # ☺ smiling face
+1F642 ; fully-qualified # 🙂 slightly smiling face
+1F917 ; fully-qualified # 🤗 hugging face
+1F929 ; fully-qualified # 🤩 star-struck
+
+# subgroup: face-neutral
+1F914 ; fully-qualified # 🤔 thinking face
+1F928 ; fully-qualified # 🤨 face with raised eyebrow
+1F610 ; fully-qualified # 😐 neutral face
+1F611 ; fully-qualified # 😑 expressionless face
+1F636 ; fully-qualified # 😶 face without mouth
+1F644 ; fully-qualified # 🙄 face with rolling eyes
+1F60F ; fully-qualified # 😏 smirking face
+1F623 ; fully-qualified # 😣 persevering face
+1F625 ; fully-qualified # 😥 sad but relieved face
+1F62E ; fully-qualified # 😮 face with open mouth
+1F910 ; fully-qualified # 🤐 zipper-mouth face
+1F62F ; fully-qualified # 😯 hushed face
+1F62A ; fully-qualified # 😪 sleepy face
+1F62B ; fully-qualified # 😫 tired face
+1F634 ; fully-qualified # 😴 sleeping face
+1F60C ; fully-qualified # 😌 relieved face
+1F61B ; fully-qualified # 😛 face with tongue
+1F61C ; fully-qualified # 😜 winking face with tongue
+1F61D ; fully-qualified # 😝 squinting face with tongue
+1F924 ; fully-qualified # 🤤 drooling face
+1F612 ; fully-qualified # 😒 unamused face
+1F613 ; fully-qualified # 😓 downcast face with sweat
+1F614 ; fully-qualified # 😔 pensive face
+1F615 ; fully-qualified # 😕 confused face
+1F643 ; fully-qualified # 🙃 upside-down face
+1F911 ; fully-qualified # 🤑 money-mouth face
+1F632 ; fully-qualified # 😲 astonished face
+
+# subgroup: face-negative
+2639 FE0F ; fully-qualified # ☹️ frowning face
+2639 ; non-fully-qualified # ☹ frowning face
+1F641 ; fully-qualified # 🙁 slightly frowning face
+1F616 ; fully-qualified # 😖 confounded face
+1F61E ; fully-qualified # 😞 disappointed face
+1F61F ; fully-qualified # 😟 worried face
+1F624 ; fully-qualified # 😤 face with steam from nose
+1F622 ; fully-qualified # 😢 crying face
+1F62D ; fully-qualified # 😭 loudly crying face
+1F626 ; fully-qualified # 😦 frowning face with open mouth
+1F627 ; fully-qualified # 😧 anguished face
+1F628 ; fully-qualified # 😨 fearful face
+1F629 ; fully-qualified # 😩 weary face
+1F92F ; fully-qualified # 🤯 exploding head
+1F62C ; fully-qualified # 😬 grimacing face
+1F630 ; fully-qualified # 😰 anxious face with sweat
+1F631 ; fully-qualified # 😱 face screaming in fear
+1F975 ; fully-qualified # 🥵 hot face
+1F976 ; fully-qualified # 🥶 cold face
+1F633 ; fully-qualified # 😳 flushed face
+1F92A ; fully-qualified # 🤪 zany face
+1F635 ; fully-qualified # 😵 dizzy face
+1F621 ; fully-qualified # 😡 pouting face
+1F620 ; fully-qualified # 😠 angry face
+1F92C ; fully-qualified # 🤬 face with symbols on mouth
+
+# subgroup: face-sick
+1F637 ; fully-qualified # 😷 face with medical mask
+1F912 ; fully-qualified # 🤒 face with thermometer
+1F915 ; fully-qualified # 🤕 face with head-bandage
+1F922 ; fully-qualified # 🤢 nauseated face
+1F92E ; fully-qualified # 🤮 face vomiting
+1F927 ; fully-qualified # 🤧 sneezing face
+
+# subgroup: face-role
+1F607 ; fully-qualified # 😇 smiling face with halo
+1F920 ; fully-qualified # 🤠 cowboy hat face
+1F973 ; fully-qualified # 🥳 partying face
+1F974 ; fully-qualified # 🥴 woozy face
+1F97A ; fully-qualified # 🥺 pleading face
+1F925 ; fully-qualified # 🤥 lying face
+1F92B ; fully-qualified # 🤫 shushing face
+1F92D ; fully-qualified # 🤭 face with hand over mouth
+1F9D0 ; fully-qualified # 🧐 face with monocle
+1F913 ; fully-qualified # 🤓 nerd face
+
+# subgroup: face-fantasy
+1F608 ; fully-qualified # 😈 smiling face with horns
+1F47F ; fully-qualified # 👿 angry face with horns
+1F921 ; fully-qualified # 🤡 clown face
+1F479 ; fully-qualified # 👹 ogre
+1F47A ; fully-qualified # 👺 goblin
+1F480 ; fully-qualified # 💀 skull
+2620 FE0F ; fully-qualified # ☠️ skull and crossbones
+2620 ; non-fully-qualified # ☠ skull and crossbones
+1F47B ; fully-qualified # 👻 ghost
+1F47D ; fully-qualified # 👽 alien
+1F47E ; fully-qualified # 👾 alien monster
+1F916 ; fully-qualified # 🤖 robot face
+1F4A9 ; fully-qualified # 💩 pile of poo
+
+# subgroup: cat-face
+1F63A ; fully-qualified # 😺 grinning cat face
+1F638 ; fully-qualified # 😸 grinning cat face with smiling eyes
+1F639 ; fully-qualified # 😹 cat face with tears of joy
+1F63B ; fully-qualified # 😻 smiling cat face with heart-eyes
+1F63C ; fully-qualified # 😼 cat face with wry smile
+1F63D ; fully-qualified # 😽 kissing cat face
+1F640 ; fully-qualified # 🙀 weary cat face
+1F63F ; fully-qualified # 😿 crying cat face
+1F63E ; fully-qualified # 😾 pouting cat face
+
+# subgroup: monkey-face
+1F648 ; fully-qualified # 🙈 see-no-evil monkey
+1F649 ; fully-qualified # 🙉 hear-no-evil monkey
+1F64A ; fully-qualified # 🙊 speak-no-evil monkey
+
+# subgroup: skin-tone
+1F3FB ; fully-qualified # 🏻 light skin tone
+1F3FC ; fully-qualified # 🏼 medium-light skin tone
+1F3FD ; fully-qualified # 🏽 medium skin tone
+1F3FE ; fully-qualified # 🏾 medium-dark skin tone
+1F3FF ; fully-qualified # 🏿 dark skin tone
+
+# subgroup: person
+1F476 ; fully-qualified # 👶 baby
+1F476 1F3FB ; fully-qualified # 👶🏻 baby: light skin tone
+1F476 1F3FC ; fully-qualified # 👶🏼 baby: medium-light skin tone
+1F476 1F3FD ; fully-qualified # 👶🏽 baby: medium skin tone
+1F476 1F3FE ; fully-qualified # 👶🏾 baby: medium-dark skin tone
+1F476 1F3FF ; fully-qualified # 👶🏿 baby: dark skin tone
+1F9D2 ; fully-qualified # 🧒 child
+1F9D2 1F3FB ; fully-qualified # 🧒🏻 child: light skin tone
+1F9D2 1F3FC ; fully-qualified # 🧒🏼 child: medium-light skin tone
+1F9D2 1F3FD ; fully-qualified # 🧒🏽 child: medium skin tone
+1F9D2 1F3FE ; fully-qualified # 🧒🏾 child: medium-dark skin tone
+1F9D2 1F3FF ; fully-qualified # 🧒🏿 child: dark skin tone
+1F466 ; fully-qualified # 👦 boy
+1F466 1F3FB ; fully-qualified # 👦🏻 boy: light skin tone
+1F466 1F3FC ; fully-qualified # 👦🏼 boy: medium-light skin tone
+1F466 1F3FD ; fully-qualified # 👦🏽 boy: medium skin tone
+1F466 1F3FE ; fully-qualified # 👦🏾 boy: medium-dark skin tone
+1F466 1F3FF ; fully-qualified # 👦🏿 boy: dark skin tone
+1F467 ; fully-qualified # 👧 girl
+1F467 1F3FB ; fully-qualified # 👧🏻 girl: light skin tone
+1F467 1F3FC ; fully-qualified # 👧🏼 girl: medium-light skin tone
+1F467 1F3FD ; fully-qualified # 👧🏽 girl: medium skin tone
+1F467 1F3FE ; fully-qualified # 👧🏾 girl: medium-dark skin tone
+1F467 1F3FF ; fully-qualified # 👧🏿 girl: dark skin tone
+1F9D1 ; fully-qualified # 🧑 adult
+1F9D1 1F3FB ; fully-qualified # 🧑🏻 adult: light skin tone
+1F9D1 1F3FC ; fully-qualified # 🧑🏼 adult: medium-light skin tone
+1F9D1 1F3FD ; fully-qualified # 🧑🏽 adult: medium skin tone
+1F9D1 1F3FE ; fully-qualified # 🧑🏾 adult: medium-dark skin tone
+1F9D1 1F3FF ; fully-qualified # 🧑🏿 adult: dark skin tone
+1F468 ; fully-qualified # 👨 man
+1F468 1F3FB ; fully-qualified # 👨🏻 man: light skin tone
+1F468 1F3FC ; fully-qualified # 👨🏼 man: medium-light skin tone
+1F468 1F3FD ; fully-qualified # 👨🏽 man: medium skin tone
+1F468 1F3FE ; fully-qualified # 👨🏾 man: medium-dark skin tone
+1F468 1F3FF ; fully-qualified # 👨🏿 man: dark skin tone
+1F469 ; fully-qualified # 👩 woman
+1F469 1F3FB ; fully-qualified # 👩🏻 woman: light skin tone
+1F469 1F3FC ; fully-qualified # 👩🏼 woman: medium-light skin tone
+1F469 1F3FD ; fully-qualified # 👩🏽 woman: medium skin tone
+1F469 1F3FE ; fully-qualified # 👩🏾 woman: medium-dark skin tone
+1F469 1F3FF ; fully-qualified # 👩🏿 woman: dark skin tone
+1F9D3 ; fully-qualified # 🧓 older adult
+1F9D3 1F3FB ; fully-qualified # 🧓🏻 older adult: light skin tone
+1F9D3 1F3FC ; fully-qualified # 🧓🏼 older adult: medium-light skin tone
+1F9D3 1F3FD ; fully-qualified # 🧓🏽 older adult: medium skin tone
+1F9D3 1F3FE ; fully-qualified # 🧓🏾 older adult: medium-dark skin tone
+1F9D3 1F3FF ; fully-qualified # 🧓🏿 older adult: dark skin tone
+1F474 ; fully-qualified # 👴 old man
+1F474 1F3FB ; fully-qualified # 👴🏻 old man: light skin tone
+1F474 1F3FC ; fully-qualified # 👴🏼 old man: medium-light skin tone
+1F474 1F3FD ; fully-qualified # 👴🏽 old man: medium skin tone
+1F474 1F3FE ; fully-qualified # 👴🏾 old man: medium-dark skin tone
+1F474 1F3FF ; fully-qualified # 👴🏿 old man: dark skin tone
+1F475 ; fully-qualified # 👵 old woman
+1F475 1F3FB ; fully-qualified # 👵🏻 old woman: light skin tone
+1F475 1F3FC ; fully-qualified # 👵🏼 old woman: medium-light skin tone
+1F475 1F3FD ; fully-qualified # 👵🏽 old woman: medium skin tone
+1F475 1F3FE ; fully-qualified # 👵🏾 old woman: medium-dark skin tone
+1F475 1F3FF ; fully-qualified # 👵🏿 old woman: dark skin tone
+
+# subgroup: person-role
+1F468 200D 2695 FE0F ; fully-qualified # 👨‍⚕️ man health worker
+1F468 200D 2695 ; non-fully-qualified # 👨‍⚕ man health worker
+1F468 1F3FB 200D 2695 FE0F ; fully-qualified # 👨🏻‍⚕️ man health worker: light skin tone
+1F468 1F3FB 200D 2695 ; non-fully-qualified # 👨🏻‍⚕ man health worker: light skin tone
+1F468 1F3FC 200D 2695 FE0F ; fully-qualified # 👨🏼‍⚕️ man health worker: medium-light skin tone
+1F468 1F3FC 200D 2695 ; non-fully-qualified # 👨🏼‍⚕ man health worker: medium-light skin tone
+1F468 1F3FD 200D 2695 FE0F ; fully-qualified # 👨🏽‍⚕️ man health worker: medium skin tone
+1F468 1F3FD 200D 2695 ; non-fully-qualified # 👨🏽‍⚕ man health worker: medium skin tone
+1F468 1F3FE 200D 2695 FE0F ; fully-qualified # 👨🏾‍⚕️ man health worker: medium-dark skin tone
+1F468 1F3FE 200D 2695 ; non-fully-qualified # 👨🏾‍⚕ man health worker: medium-dark skin tone
+1F468 1F3FF 200D 2695 FE0F ; fully-qualified # 👨🏿‍⚕️ man health worker: dark skin tone
+1F468 1F3FF 200D 2695 ; non-fully-qualified # 👨🏿‍⚕ man health worker: dark skin tone
+1F469 200D 2695 FE0F ; fully-qualified # 👩‍⚕️ woman health worker
+1F469 200D 2695 ; non-fully-qualified # 👩‍⚕ woman health worker
+1F469 1F3FB 200D 2695 FE0F ; fully-qualified # 👩🏻‍⚕️ woman health worker: light skin tone
+1F469 1F3FB 200D 2695 ; non-fully-qualified # 👩🏻‍⚕ woman health worker: light skin tone
+1F469 1F3FC 200D 2695 FE0F ; fully-qualified # 👩🏼‍⚕️ woman health worker: medium-light skin tone
+1F469 1F3FC 200D 2695 ; non-fully-qualified # 👩🏼‍⚕ woman health worker: medium-light skin tone
+1F469 1F3FD 200D 2695 FE0F ; fully-qualified # 👩🏽‍⚕️ woman health worker: medium skin tone
+1F469 1F3FD 200D 2695 ; non-fully-qualified # 👩🏽‍⚕ woman health worker: medium skin tone
+1F469 1F3FE 200D 2695 FE0F ; fully-qualified # 👩🏾‍⚕️ woman health worker: medium-dark skin tone
+1F469 1F3FE 200D 2695 ; non-fully-qualified # 👩🏾‍⚕ woman health worker: medium-dark skin tone
+1F469 1F3FF 200D 2695 FE0F ; fully-qualified # 👩🏿‍⚕️ woman health worker: dark skin tone
+1F469 1F3FF 200D 2695 ; non-fully-qualified # 👩🏿‍⚕ woman health worker: dark skin tone
+1F468 200D 1F393 ; fully-qualified # 👨‍🎓 man student
+1F468 1F3FB 200D 1F393 ; fully-qualified # 👨🏻‍🎓 man student: light skin tone
+1F468 1F3FC 200D 1F393 ; fully-qualified # 👨🏼‍🎓 man student: medium-light skin tone
+1F468 1F3FD 200D 1F393 ; fully-qualified # 👨🏽‍🎓 man student: medium skin tone
+1F468 1F3FE 200D 1F393 ; fully-qualified # 👨🏾‍🎓 man student: medium-dark skin tone
+1F468 1F3FF 200D 1F393 ; fully-qualified # 👨🏿‍🎓 man student: dark skin tone
+1F469 200D 1F393 ; fully-qualified # 👩‍🎓 woman student
+1F469 1F3FB 200D 1F393 ; fully-qualified # 👩🏻‍🎓 woman student: light skin tone
+1F469 1F3FC 200D 1F393 ; fully-qualified # 👩🏼‍🎓 woman student: medium-light skin tone
+1F469 1F3FD 200D 1F393 ; fully-qualified # 👩🏽‍🎓 woman student: medium skin tone
+1F469 1F3FE 200D 1F393 ; fully-qualified # 👩🏾‍🎓 woman student: medium-dark skin tone
+1F469 1F3FF 200D 1F393 ; fully-qualified # 👩🏿‍🎓 woman student: dark skin tone
+1F468 200D 1F3EB ; fully-qualified # 👨‍🏫 man teacher
+1F468 1F3FB 200D 1F3EB ; fully-qualified # 👨🏻‍🏫 man teacher: light skin tone
+1F468 1F3FC 200D 1F3EB ; fully-qualified # 👨🏼‍🏫 man teacher: medium-light skin tone
+1F468 1F3FD 200D 1F3EB ; fully-qualified # 👨🏽‍🏫 man teacher: medium skin tone
+1F468 1F3FE 200D 1F3EB ; fully-qualified # 👨🏾‍🏫 man teacher: medium-dark skin tone
+1F468 1F3FF 200D 1F3EB ; fully-qualified # 👨🏿‍🏫 man teacher: dark skin tone
+1F469 200D 1F3EB ; fully-qualified # 👩‍🏫 woman teacher
+1F469 1F3FB 200D 1F3EB ; fully-qualified # 👩🏻‍🏫 woman teacher: light skin tone
+1F469 1F3FC 200D 1F3EB ; fully-qualified # 👩🏼‍🏫 woman teacher: medium-light skin tone
+1F469 1F3FD 200D 1F3EB ; fully-qualified # 👩🏽‍🏫 woman teacher: medium skin tone
+1F469 1F3FE 200D 1F3EB ; fully-qualified # 👩🏾‍🏫 woman teacher: medium-dark skin tone
+1F469 1F3FF 200D 1F3EB ; fully-qualified # 👩🏿‍🏫 woman teacher: dark skin tone
+1F468 200D 2696 FE0F ; fully-qualified # 👨‍⚖️ man judge
+1F468 200D 2696 ; non-fully-qualified # 👨‍⚖ man judge
+1F468 1F3FB 200D 2696 FE0F ; fully-qualified # 👨🏻‍⚖️ man judge: light skin tone
+1F468 1F3FB 200D 2696 ; non-fully-qualified # 👨🏻‍⚖ man judge: light skin tone
+1F468 1F3FC 200D 2696 FE0F ; fully-qualified # 👨🏼‍⚖️ man judge: medium-light skin tone
+1F468 1F3FC 200D 2696 ; non-fully-qualified # 👨🏼‍⚖ man judge: medium-light skin tone
+1F468 1F3FD 200D 2696 FE0F ; fully-qualified # 👨🏽‍⚖️ man judge: medium skin tone
+1F468 1F3FD 200D 2696 ; non-fully-qualified # 👨🏽‍⚖ man judge: medium skin tone
+1F468 1F3FE 200D 2696 FE0F ; fully-qualified # 👨🏾‍⚖️ man judge: medium-dark skin tone
+1F468 1F3FE 200D 2696 ; non-fully-qualified # 👨🏾‍⚖ man judge: medium-dark skin tone
+1F468 1F3FF 200D 2696 FE0F ; fully-qualified # 👨🏿‍⚖️ man judge: dark skin tone
+1F468 1F3FF 200D 2696 ; non-fully-qualified # 👨🏿‍⚖ man judge: dark skin tone
+1F469 200D 2696 FE0F ; fully-qualified # 👩‍⚖️ woman judge
+1F469 200D 2696 ; non-fully-qualified # 👩‍⚖ woman judge
+1F469 1F3FB 200D 2696 FE0F ; fully-qualified # 👩🏻‍⚖️ woman judge: light skin tone
+1F469 1F3FB 200D 2696 ; non-fully-qualified # 👩🏻‍⚖ woman judge: light skin tone
+1F469 1F3FC 200D 2696 FE0F ; fully-qualified # 👩🏼‍⚖️ woman judge: medium-light skin tone
+1F469 1F3FC 200D 2696 ; non-fully-qualified # 👩🏼‍⚖ woman judge: medium-light skin tone
+1F469 1F3FD 200D 2696 FE0F ; fully-qualified # 👩🏽‍⚖️ woman judge: medium skin tone
+1F469 1F3FD 200D 2696 ; non-fully-qualified # 👩🏽‍⚖ woman judge: medium skin tone
+1F469 1F3FE 200D 2696 FE0F ; fully-qualified # 👩🏾‍⚖️ woman judge: medium-dark skin tone
+1F469 1F3FE 200D 2696 ; non-fully-qualified # 👩🏾‍⚖ woman judge: medium-dark skin tone
+1F469 1F3FF 200D 2696 FE0F ; fully-qualified # 👩🏿‍⚖️ woman judge: dark skin tone
+1F469 1F3FF 200D 2696 ; non-fully-qualified # 👩🏿‍⚖ woman judge: dark skin tone
+1F468 200D 1F33E ; fully-qualified # 👨‍🌾 man farmer
+1F468 1F3FB 200D 1F33E ; fully-qualified # 👨🏻‍🌾 man farmer: light skin tone
+1F468 1F3FC 200D 1F33E ; fully-qualified # 👨🏼‍🌾 man farmer: medium-light skin tone
+1F468 1F3FD 200D 1F33E ; fully-qualified # 👨🏽‍🌾 man farmer: medium skin tone
+1F468 1F3FE 200D 1F33E ; fully-qualified # 👨🏾‍🌾 man farmer: medium-dark skin tone
+1F468 1F3FF 200D 1F33E ; fully-qualified # 👨🏿‍🌾 man farmer: dark skin tone
+1F469 200D 1F33E ; fully-qualified # 👩‍🌾 woman farmer
+1F469 1F3FB 200D 1F33E ; fully-qualified # 👩🏻‍🌾 woman farmer: light skin tone
+1F469 1F3FC 200D 1F33E ; fully-qualified # 👩🏼‍🌾 woman farmer: medium-light skin tone
+1F469 1F3FD 200D 1F33E ; fully-qualified # 👩🏽‍🌾 woman farmer: medium skin tone
+1F469 1F3FE 200D 1F33E ; fully-qualified # 👩🏾‍🌾 woman farmer: medium-dark skin tone
+1F469 1F3FF 200D 1F33E ; fully-qualified # 👩🏿‍🌾 woman farmer: dark skin tone
+1F468 200D 1F373 ; fully-qualified # 👨‍🍳 man cook
+1F468 1F3FB 200D 1F373 ; fully-qualified # 👨🏻‍🍳 man cook: light skin tone
+1F468 1F3FC 200D 1F373 ; fully-qualified # 👨🏼‍🍳 man cook: medium-light skin tone
+1F468 1F3FD 200D 1F373 ; fully-qualified # 👨🏽‍🍳 man cook: medium skin tone
+1F468 1F3FE 200D 1F373 ; fully-qualified # 👨🏾‍🍳 man cook: medium-dark skin tone
+1F468 1F3FF 200D 1F373 ; fully-qualified # 👨🏿‍🍳 man cook: dark skin tone
+1F469 200D 1F373 ; fully-qualified # 👩‍🍳 woman cook
+1F469 1F3FB 200D 1F373 ; fully-qualified # 👩🏻‍🍳 woman cook: light skin tone
+1F469 1F3FC 200D 1F373 ; fully-qualified # 👩🏼‍🍳 woman cook: medium-light skin tone
+1F469 1F3FD 200D 1F373 ; fully-qualified # 👩🏽‍🍳 woman cook: medium skin tone
+1F469 1F3FE 200D 1F373 ; fully-qualified # 👩🏾‍🍳 woman cook: medium-dark skin tone
+1F469 1F3FF 200D 1F373 ; fully-qualified # 👩🏿‍🍳 woman cook: dark skin tone
+1F468 200D 1F527 ; fully-qualified # 👨‍🔧 man mechanic
+1F468 1F3FB 200D 1F527 ; fully-qualified # 👨🏻‍🔧 man mechanic: light skin tone
+1F468 1F3FC 200D 1F527 ; fully-qualified # 👨🏼‍🔧 man mechanic: medium-light skin tone
+1F468 1F3FD 200D 1F527 ; fully-qualified # 👨🏽‍🔧 man mechanic: medium skin tone
+1F468 1F3FE 200D 1F527 ; fully-qualified # 👨🏾‍🔧 man mechanic: medium-dark skin tone
+1F468 1F3FF 200D 1F527 ; fully-qualified # 👨🏿‍🔧 man mechanic: dark skin tone
+1F469 200D 1F527 ; fully-qualified # 👩‍🔧 woman mechanic
+1F469 1F3FB 200D 1F527 ; fully-qualified # 👩🏻‍🔧 woman mechanic: light skin tone
+1F469 1F3FC 200D 1F527 ; fully-qualified # 👩🏼‍🔧 woman mechanic: medium-light skin tone
+1F469 1F3FD 200D 1F527 ; fully-qualified # 👩🏽‍🔧 woman mechanic: medium skin tone
+1F469 1F3FE 200D 1F527 ; fully-qualified # 👩🏾‍🔧 woman mechanic: medium-dark skin tone
+1F469 1F3FF 200D 1F527 ; fully-qualified # 👩🏿‍🔧 woman mechanic: dark skin tone
+1F468 200D 1F3ED ; fully-qualified # 👨‍🏭 man factory worker
+1F468 1F3FB 200D 1F3ED ; fully-qualified # 👨🏻‍🏭 man factory worker: light skin tone
+1F468 1F3FC 200D 1F3ED ; fully-qualified # 👨🏼‍🏭 man factory worker: medium-light skin tone
+1F468 1F3FD 200D 1F3ED ; fully-qualified # 👨🏽‍🏭 man factory worker: medium skin tone
+1F468 1F3FE 200D 1F3ED ; fully-qualified # 👨🏾‍🏭 man factory worker: medium-dark skin tone
+1F468 1F3FF 200D 1F3ED ; fully-qualified # 👨🏿‍🏭 man factory worker: dark skin tone
+1F469 200D 1F3ED ; fully-qualified # 👩‍🏭 woman factory worker
+1F469 1F3FB 200D 1F3ED ; fully-qualified # 👩🏻‍🏭 woman factory worker: light skin tone
+1F469 1F3FC 200D 1F3ED ; fully-qualified # 👩🏼‍🏭 woman factory worker: medium-light skin tone
+1F469 1F3FD 200D 1F3ED ; fully-qualified # 👩🏽‍🏭 woman factory worker: medium skin tone
+1F469 1F3FE 200D 1F3ED ; fully-qualified # 👩🏾‍🏭 woman factory worker: medium-dark skin tone
+1F469 1F3FF 200D 1F3ED ; fully-qualified # 👩🏿‍🏭 woman factory worker: dark skin tone
+1F468 200D 1F4BC ; fully-qualified # 👨‍💼 man office worker
+1F468 1F3FB 200D 1F4BC ; fully-qualified # 👨🏻‍💼 man office worker: light skin tone
+1F468 1F3FC 200D 1F4BC ; fully-qualified # 👨🏼‍💼 man office worker: medium-light skin tone
+1F468 1F3FD 200D 1F4BC ; fully-qualified # 👨🏽‍💼 man office worker: medium skin tone
+1F468 1F3FE 200D 1F4BC ; fully-qualified # 👨🏾‍💼 man office worker: medium-dark skin tone
+1F468 1F3FF 200D 1F4BC ; fully-qualified # 👨🏿‍💼 man office worker: dark skin tone
+1F469 200D 1F4BC ; fully-qualified # 👩‍💼 woman office worker
+1F469 1F3FB 200D 1F4BC ; fully-qualified # 👩🏻‍💼 woman office worker: light skin tone
+1F469 1F3FC 200D 1F4BC ; fully-qualified # 👩🏼‍💼 woman office worker: medium-light skin tone
+1F469 1F3FD 200D 1F4BC ; fully-qualified # 👩🏽‍💼 woman office worker: medium skin tone
+1F469 1F3FE 200D 1F4BC ; fully-qualified # 👩🏾‍💼 woman office worker: medium-dark skin tone
+1F469 1F3FF 200D 1F4BC ; fully-qualified # 👩🏿‍💼 woman office worker: dark skin tone
+1F468 200D 1F52C ; fully-qualified # 👨‍🔬 man scientist
+1F468 1F3FB 200D 1F52C ; fully-qualified # 👨🏻‍🔬 man scientist: light skin tone
+1F468 1F3FC 200D 1F52C ; fully-qualified # 👨🏼‍🔬 man scientist: medium-light skin tone
+1F468 1F3FD 200D 1F52C ; fully-qualified # 👨🏽‍🔬 man scientist: medium skin tone
+1F468 1F3FE 200D 1F52C ; fully-qualified # 👨🏾‍🔬 man scientist: medium-dark skin tone
+1F468 1F3FF 200D 1F52C ; fully-qualified # 👨🏿‍🔬 man scientist: dark skin tone
+1F469 200D 1F52C ; fully-qualified # 👩‍🔬 woman scientist
+1F469 1F3FB 200D 1F52C ; fully-qualified # 👩🏻‍🔬 woman scientist: light skin tone
+1F469 1F3FC 200D 1F52C ; fully-qualified # 👩🏼‍🔬 woman scientist: medium-light skin tone
+1F469 1F3FD 200D 1F52C ; fully-qualified # 👩🏽‍🔬 woman scientist: medium skin tone
+1F469 1F3FE 200D 1F52C ; fully-qualified # 👩🏾‍🔬 woman scientist: medium-dark skin tone
+1F469 1F3FF 200D 1F52C ; fully-qualified # 👩🏿‍🔬 woman scientist: dark skin tone
+1F468 200D 1F4BB ; fully-qualified # 👨‍💻 man technologist
+1F468 1F3FB 200D 1F4BB ; fully-qualified # 👨🏻‍💻 man technologist: light skin tone
+1F468 1F3FC 200D 1F4BB ; fully-qualified # 👨🏼‍💻 man technologist: medium-light skin tone
+1F468 1F3FD 200D 1F4BB ; fully-qualified # 👨🏽‍💻 man technologist: medium skin tone
+1F468 1F3FE 200D 1F4BB ; fully-qualified # 👨🏾‍💻 man technologist: medium-dark skin tone
+1F468 1F3FF 200D 1F4BB ; fully-qualified # 👨🏿‍💻 man technologist: dark skin tone
+1F469 200D 1F4BB ; fully-qualified # 👩‍💻 woman technologist
+1F469 1F3FB 200D 1F4BB ; fully-qualified # 👩🏻‍💻 woman technologist: light skin tone
+1F469 1F3FC 200D 1F4BB ; fully-qualified # 👩🏼‍💻 woman technologist: medium-light skin tone
+1F469 1F3FD 200D 1F4BB ; fully-qualified # 👩🏽‍💻 woman technologist: medium skin tone
+1F469 1F3FE 200D 1F4BB ; fully-qualified # 👩🏾‍💻 woman technologist: medium-dark skin tone
+1F469 1F3FF 200D 1F4BB ; fully-qualified # 👩🏿‍💻 woman technologist: dark skin tone
+1F468 200D 1F3A4 ; fully-qualified # 👨‍🎤 man singer
+1F468 1F3FB 200D 1F3A4 ; fully-qualified # 👨🏻‍🎤 man singer: light skin tone
+1F468 1F3FC 200D 1F3A4 ; fully-qualified # 👨🏼‍🎤 man singer: medium-light skin tone
+1F468 1F3FD 200D 1F3A4 ; fully-qualified # 👨🏽‍🎤 man singer: medium skin tone
+1F468 1F3FE 200D 1F3A4 ; fully-qualified # 👨🏾‍🎤 man singer: medium-dark skin tone
+1F468 1F3FF 200D 1F3A4 ; fully-qualified # 👨🏿‍🎤 man singer: dark skin tone
+1F469 200D 1F3A4 ; fully-qualified # 👩‍🎤 woman singer
+1F469 1F3FB 200D 1F3A4 ; fully-qualified # 👩🏻‍🎤 woman singer: light skin tone
+1F469 1F3FC 200D 1F3A4 ; fully-qualified # 👩🏼‍🎤 woman singer: medium-light skin tone
+1F469 1F3FD 200D 1F3A4 ; fully-qualified # 👩🏽‍🎤 woman singer: medium skin tone
+1F469 1F3FE 200D 1F3A4 ; fully-qualified # 👩🏾‍🎤 woman singer: medium-dark skin tone
+1F469 1F3FF 200D 1F3A4 ; fully-qualified # 👩🏿‍🎤 woman singer: dark skin tone
+1F468 200D 1F3A8 ; fully-qualified # 👨‍🎨 man artist
+1F468 1F3FB 200D 1F3A8 ; fully-qualified # 👨🏻‍🎨 man artist: light skin tone
+1F468 1F3FC 200D 1F3A8 ; fully-qualified # 👨🏼‍🎨 man artist: medium-light skin tone
+1F468 1F3FD 200D 1F3A8 ; fully-qualified # 👨🏽‍🎨 man artist: medium skin tone
+1F468 1F3FE 200D 1F3A8 ; fully-qualified # 👨🏾‍🎨 man artist: medium-dark skin tone
+1F468 1F3FF 200D 1F3A8 ; fully-qualified # 👨🏿‍🎨 man artist: dark skin tone
+1F469 200D 1F3A8 ; fully-qualified # 👩‍🎨 woman artist
+1F469 1F3FB 200D 1F3A8 ; fully-qualified # 👩🏻‍🎨 woman artist: light skin tone
+1F469 1F3FC 200D 1F3A8 ; fully-qualified # 👩🏼‍🎨 woman artist: medium-light skin tone
+1F469 1F3FD 200D 1F3A8 ; fully-qualified # 👩🏽‍🎨 woman artist: medium skin tone
+1F469 1F3FE 200D 1F3A8 ; fully-qualified # 👩🏾‍🎨 woman artist: medium-dark skin tone
+1F469 1F3FF 200D 1F3A8 ; fully-qualified # 👩🏿‍🎨 woman artist: dark skin tone
+1F468 200D 2708 FE0F ; fully-qualified # 👨‍✈️ man pilot
+1F468 200D 2708 ; non-fully-qualified # 👨‍✈ man pilot
+1F468 1F3FB 200D 2708 FE0F ; fully-qualified # 👨🏻‍✈️ man pilot: light skin tone
+1F468 1F3FB 200D 2708 ; non-fully-qualified # 👨🏻‍✈ man pilot: light skin tone
+1F468 1F3FC 200D 2708 FE0F ; fully-qualified # 👨🏼‍✈️ man pilot: medium-light skin tone
+1F468 1F3FC 200D 2708 ; non-fully-qualified # 👨🏼‍✈ man pilot: medium-light skin tone
+1F468 1F3FD 200D 2708 FE0F ; fully-qualified # 👨🏽‍✈️ man pilot: medium skin tone
+1F468 1F3FD 200D 2708 ; non-fully-qualified # 👨🏽‍✈ man pilot: medium skin tone
+1F468 1F3FE 200D 2708 FE0F ; fully-qualified # 👨🏾‍✈️ man pilot: medium-dark skin tone
+1F468 1F3FE 200D 2708 ; non-fully-qualified # 👨🏾‍✈ man pilot: medium-dark skin tone
+1F468 1F3FF 200D 2708 FE0F ; fully-qualified # 👨🏿‍✈️ man pilot: dark skin tone
+1F468 1F3FF 200D 2708 ; non-fully-qualified # 👨🏿‍✈ man pilot: dark skin tone
+1F469 200D 2708 FE0F ; fully-qualified # 👩‍✈️ woman pilot
+1F469 200D 2708 ; non-fully-qualified # 👩‍✈ woman pilot
+1F469 1F3FB 200D 2708 FE0F ; fully-qualified # 👩🏻‍✈️ woman pilot: light skin tone
+1F469 1F3FB 200D 2708 ; non-fully-qualified # 👩🏻‍✈ woman pilot: light skin tone
+1F469 1F3FC 200D 2708 FE0F ; fully-qualified # 👩🏼‍✈️ woman pilot: medium-light skin tone
+1F469 1F3FC 200D 2708 ; non-fully-qualified # 👩🏼‍✈ woman pilot: medium-light skin tone
+1F469 1F3FD 200D 2708 FE0F ; fully-qualified # 👩🏽‍✈️ woman pilot: medium skin tone
+1F469 1F3FD 200D 2708 ; non-fully-qualified # 👩🏽‍✈ woman pilot: medium skin tone
+1F469 1F3FE 200D 2708 FE0F ; fully-qualified # 👩🏾‍✈️ woman pilot: medium-dark skin tone
+1F469 1F3FE 200D 2708 ; non-fully-qualified # 👩🏾‍✈ woman pilot: medium-dark skin tone
+1F469 1F3FF 200D 2708 FE0F ; fully-qualified # 👩🏿‍✈️ woman pilot: dark skin tone
+1F469 1F3FF 200D 2708 ; non-fully-qualified # 👩🏿‍✈ woman pilot: dark skin tone
+1F468 200D 1F680 ; fully-qualified # 👨‍🚀 man astronaut
+1F468 1F3FB 200D 1F680 ; fully-qualified # 👨🏻‍🚀 man astronaut: light skin tone
+1F468 1F3FC 200D 1F680 ; fully-qualified # 👨🏼‍🚀 man astronaut: medium-light skin tone
+1F468 1F3FD 200D 1F680 ; fully-qualified # 👨🏽‍🚀 man astronaut: medium skin tone
+1F468 1F3FE 200D 1F680 ; fully-qualified # 👨🏾‍🚀 man astronaut: medium-dark skin tone
+1F468 1F3FF 200D 1F680 ; fully-qualified # 👨🏿‍🚀 man astronaut: dark skin tone
+1F469 200D 1F680 ; fully-qualified # 👩‍🚀 woman astronaut
+1F469 1F3FB 200D 1F680 ; fully-qualified # 👩🏻‍🚀 woman astronaut: light skin tone
+1F469 1F3FC 200D 1F680 ; fully-qualified # 👩🏼‍🚀 woman astronaut: medium-light skin tone
+1F469 1F3FD 200D 1F680 ; fully-qualified # 👩🏽‍🚀 woman astronaut: medium skin tone
+1F469 1F3FE 200D 1F680 ; fully-qualified # 👩🏾‍🚀 woman astronaut: medium-dark skin tone
+1F469 1F3FF 200D 1F680 ; fully-qualified # 👩🏿‍🚀 woman astronaut: dark skin tone
+1F468 200D 1F692 ; fully-qualified # 👨‍🚒 man firefighter
+1F468 1F3FB 200D 1F692 ; fully-qualified # 👨🏻‍🚒 man firefighter: light skin tone
+1F468 1F3FC 200D 1F692 ; fully-qualified # 👨🏼‍🚒 man firefighter: medium-light skin tone
+1F468 1F3FD 200D 1F692 ; fully-qualified # 👨🏽‍🚒 man firefighter: medium skin tone
+1F468 1F3FE 200D 1F692 ; fully-qualified # 👨🏾‍🚒 man firefighter: medium-dark skin tone
+1F468 1F3FF 200D 1F692 ; fully-qualified # 👨🏿‍🚒 man firefighter: dark skin tone
+1F469 200D 1F692 ; fully-qualified # 👩‍🚒 woman firefighter
+1F469 1F3FB 200D 1F692 ; fully-qualified # 👩🏻‍🚒 woman firefighter: light skin tone
+1F469 1F3FC 200D 1F692 ; fully-qualified # 👩🏼‍🚒 woman firefighter: medium-light skin tone
+1F469 1F3FD 200D 1F692 ; fully-qualified # 👩🏽‍🚒 woman firefighter: medium skin tone
+1F469 1F3FE 200D 1F692 ; fully-qualified # 👩🏾‍🚒 woman firefighter: medium-dark skin tone
+1F469 1F3FF 200D 1F692 ; fully-qualified # 👩🏿‍🚒 woman firefighter: dark skin tone
+1F46E ; fully-qualified # 👮 police officer
+1F46E 1F3FB ; fully-qualified # 👮🏻 police officer: light skin tone
+1F46E 1F3FC ; fully-qualified # 👮🏼 police officer: medium-light skin tone
+1F46E 1F3FD ; fully-qualified # 👮🏽 police officer: medium skin tone
+1F46E 1F3FE ; fully-qualified # 👮🏾 police officer: medium-dark skin tone
+1F46E 1F3FF ; fully-qualified # 👮🏿 police officer: dark skin tone
+1F46E 200D 2642 FE0F ; fully-qualified # 👮‍♂️ man police officer
+1F46E 200D 2642 ; non-fully-qualified # 👮‍♂ man police officer
+1F46E 1F3FB 200D 2642 FE0F ; fully-qualified # 👮🏻‍♂️ man police officer: light skin tone
+1F46E 1F3FB 200D 2642 ; non-fully-qualified # 👮🏻‍♂ man police officer: light skin tone
+1F46E 1F3FC 200D 2642 FE0F ; fully-qualified # 👮🏼‍♂️ man police officer: medium-light skin tone
+1F46E 1F3FC 200D 2642 ; non-fully-qualified # 👮🏼‍♂ man police officer: medium-light skin tone
+1F46E 1F3FD 200D 2642 FE0F ; fully-qualified # 👮🏽‍♂️ man police officer: medium skin tone
+1F46E 1F3FD 200D 2642 ; non-fully-qualified # 👮🏽‍♂ man police officer: medium skin tone
+1F46E 1F3FE 200D 2642 FE0F ; fully-qualified # 👮🏾‍♂️ man police officer: medium-dark skin tone
+1F46E 1F3FE 200D 2642 ; non-fully-qualified # 👮🏾‍♂ man police officer: medium-dark skin tone
+1F46E 1F3FF 200D 2642 FE0F ; fully-qualified # 👮🏿‍♂️ man police officer: dark skin tone
+1F46E 1F3FF 200D 2642 ; non-fully-qualified # 👮🏿‍♂ man police officer: dark skin tone
+1F46E 200D 2640 FE0F ; fully-qualified # 👮‍♀️ woman police officer
+1F46E 200D 2640 ; non-fully-qualified # 👮‍♀ woman police officer
+1F46E 1F3FB 200D 2640 FE0F ; fully-qualified # 👮🏻‍♀️ woman police officer: light skin tone
+1F46E 1F3FB 200D 2640 ; non-fully-qualified # 👮🏻‍♀ woman police officer: light skin tone
+1F46E 1F3FC 200D 2640 FE0F ; fully-qualified # 👮🏼‍♀️ woman police officer: medium-light skin tone
+1F46E 1F3FC 200D 2640 ; non-fully-qualified # 👮🏼‍♀ woman police officer: medium-light skin tone
+1F46E 1F3FD 200D 2640 FE0F ; fully-qualified # 👮🏽‍♀️ woman police officer: medium skin tone
+1F46E 1F3FD 200D 2640 ; non-fully-qualified # 👮🏽‍♀ woman police officer: medium skin tone
+1F46E 1F3FE 200D 2640 FE0F ; fully-qualified # 👮🏾‍♀️ woman police officer: medium-dark skin tone
+1F46E 1F3FE 200D 2640 ; non-fully-qualified # 👮🏾‍♀ woman police officer: medium-dark skin tone
+1F46E 1F3FF 200D 2640 FE0F ; fully-qualified # 👮🏿‍♀️ woman police officer: dark skin tone
+1F46E 1F3FF 200D 2640 ; non-fully-qualified # 👮🏿‍♀ woman police officer: dark skin tone
+1F575 FE0F ; fully-qualified # 🕵️ detective
+1F575 ; non-fully-qualified # 🕵 detective
+1F575 1F3FB ; fully-qualified # 🕵🏻 detective: light skin tone
+1F575 1F3FC ; fully-qualified # 🕵🏼 detective: medium-light skin tone
+1F575 1F3FD ; fully-qualified # 🕵🏽 detective: medium skin tone
+1F575 1F3FE ; fully-qualified # 🕵🏾 detective: medium-dark skin tone
+1F575 1F3FF ; fully-qualified # 🕵🏿 detective: dark skin tone
+1F575 FE0F 200D 2642 FE0F ; fully-qualified # 🕵️‍♂️ man detective
+1F575 200D 2642 FE0F ; non-fully-qualified # 🕵‍♂️ man detective
+1F575 FE0F 200D 2642 ; non-fully-qualified # 🕵️‍♂ man detective
+1F575 200D 2642 ; non-fully-qualified # 🕵‍♂ man detective
+1F575 1F3FB 200D 2642 FE0F ; fully-qualified # 🕵🏻‍♂️ man detective: light skin tone
+1F575 1F3FB 200D 2642 ; non-fully-qualified # 🕵🏻‍♂ man detective: light skin tone
+1F575 1F3FC 200D 2642 FE0F ; fully-qualified # 🕵🏼‍♂️ man detective: medium-light skin tone
+1F575 1F3FC 200D 2642 ; non-fully-qualified # 🕵🏼‍♂ man detective: medium-light skin tone
+1F575 1F3FD 200D 2642 FE0F ; fully-qualified # 🕵🏽‍♂️ man detective: medium skin tone
+1F575 1F3FD 200D 2642 ; non-fully-qualified # 🕵🏽‍♂ man detective: medium skin tone
+1F575 1F3FE 200D 2642 FE0F ; fully-qualified # 🕵🏾‍♂️ man detective: medium-dark skin tone
+1F575 1F3FE 200D 2642 ; non-fully-qualified # 🕵🏾‍♂ man detective: medium-dark skin tone
+1F575 1F3FF 200D 2642 FE0F ; fully-qualified # 🕵🏿‍♂️ man detective: dark skin tone
+1F575 1F3FF 200D 2642 ; non-fully-qualified # 🕵🏿‍♂ man detective: dark skin tone
+1F575 FE0F 200D 2640 FE0F ; fully-qualified # 🕵️‍♀️ woman detective
+1F575 200D 2640 FE0F ; non-fully-qualified # 🕵‍♀️ woman detective
+1F575 FE0F 200D 2640 ; non-fully-qualified # 🕵️‍♀ woman detective
+1F575 200D 2640 ; non-fully-qualified # 🕵‍♀ woman detective
+1F575 1F3FB 200D 2640 FE0F ; fully-qualified # 🕵🏻‍♀️ woman detective: light skin tone
+1F575 1F3FB 200D 2640 ; non-fully-qualified # 🕵🏻‍♀ woman detective: light skin tone
+1F575 1F3FC 200D 2640 FE0F ; fully-qualified # 🕵🏼‍♀️ woman detective: medium-light skin tone
+1F575 1F3FC 200D 2640 ; non-fully-qualified # 🕵🏼‍♀ woman detective: medium-light skin tone
+1F575 1F3FD 200D 2640 FE0F ; fully-qualified # 🕵🏽‍♀️ woman detective: medium skin tone
+1F575 1F3FD 200D 2640 ; non-fully-qualified # 🕵🏽‍♀ woman detective: medium skin tone
+1F575 1F3FE 200D 2640 FE0F ; fully-qualified # 🕵🏾‍♀️ woman detective: medium-dark skin tone
+1F575 1F3FE 200D 2640 ; non-fully-qualified # 🕵🏾‍♀ woman detective: medium-dark skin tone
+1F575 1F3FF 200D 2640 FE0F ; fully-qualified # 🕵🏿‍♀️ woman detective: dark skin tone
+1F575 1F3FF 200D 2640 ; non-fully-qualified # 🕵🏿‍♀ woman detective: dark skin tone
+1F482 ; fully-qualified # 💂 guard
+1F482 1F3FB ; fully-qualified # 💂🏻 guard: light skin tone
+1F482 1F3FC ; fully-qualified # 💂🏼 guard: medium-light skin tone
+1F482 1F3FD ; fully-qualified # 💂🏽 guard: medium skin tone
+1F482 1F3FE ; fully-qualified # 💂🏾 guard: medium-dark skin tone
+1F482 1F3FF ; fully-qualified # 💂🏿 guard: dark skin tone
+1F482 200D 2642 FE0F ; fully-qualified # 💂‍♂️ man guard
+1F482 200D 2642 ; non-fully-qualified # 💂‍♂ man guard
+1F482 1F3FB 200D 2642 FE0F ; fully-qualified # 💂🏻‍♂️ man guard: light skin tone
+1F482 1F3FB 200D 2642 ; non-fully-qualified # 💂🏻‍♂ man guard: light skin tone
+1F482 1F3FC 200D 2642 FE0F ; fully-qualified # 💂🏼‍♂️ man guard: medium-light skin tone
+1F482 1F3FC 200D 2642 ; non-fully-qualified # 💂🏼‍♂ man guard: medium-light skin tone
+1F482 1F3FD 200D 2642 FE0F ; fully-qualified # 💂🏽‍♂️ man guard: medium skin tone
+1F482 1F3FD 200D 2642 ; non-fully-qualified # 💂🏽‍♂ man guard: medium skin tone
+1F482 1F3FE 200D 2642 FE0F ; fully-qualified # 💂🏾‍♂️ man guard: medium-dark skin tone
+1F482 1F3FE 200D 2642 ; non-fully-qualified # 💂🏾‍♂ man guard: medium-dark skin tone
+1F482 1F3FF 200D 2642 FE0F ; fully-qualified # 💂🏿‍♂️ man guard: dark skin tone
+1F482 1F3FF 200D 2642 ; non-fully-qualified # 💂🏿‍♂ man guard: dark skin tone
+1F482 200D 2640 FE0F ; fully-qualified # 💂‍♀️ woman guard
+1F482 200D 2640 ; non-fully-qualified # 💂‍♀ woman guard
+1F482 1F3FB 200D 2640 FE0F ; fully-qualified # 💂🏻‍♀️ woman guard: light skin tone
+1F482 1F3FB 200D 2640 ; non-fully-qualified # 💂🏻‍♀ woman guard: light skin tone
+1F482 1F3FC 200D 2640 FE0F ; fully-qualified # 💂🏼‍♀️ woman guard: medium-light skin tone
+1F482 1F3FC 200D 2640 ; non-fully-qualified # 💂🏼‍♀ woman guard: medium-light skin tone
+1F482 1F3FD 200D 2640 FE0F ; fully-qualified # 💂🏽‍♀️ woman guard: medium skin tone
+1F482 1F3FD 200D 2640 ; non-fully-qualified # 💂🏽‍♀ woman guard: medium skin tone
+1F482 1F3FE 200D 2640 FE0F ; fully-qualified # 💂🏾‍♀️ woman guard: medium-dark skin tone
+1F482 1F3FE 200D 2640 ; non-fully-qualified # 💂🏾‍♀ woman guard: medium-dark skin tone
+1F482 1F3FF 200D 2640 FE0F ; fully-qualified # 💂🏿‍♀️ woman guard: dark skin tone
+1F482 1F3FF 200D 2640 ; non-fully-qualified # 💂🏿‍♀ woman guard: dark skin tone
+1F477 ; fully-qualified # 👷 construction worker
+1F477 1F3FB ; fully-qualified # 👷🏻 construction worker: light skin tone
+1F477 1F3FC ; fully-qualified # 👷🏼 construction worker: medium-light skin tone
+1F477 1F3FD ; fully-qualified # 👷🏽 construction worker: medium skin tone
+1F477 1F3FE ; fully-qualified # 👷🏾 construction worker: medium-dark skin tone
+1F477 1F3FF ; fully-qualified # 👷🏿 construction worker: dark skin tone
+1F477 200D 2642 FE0F ; fully-qualified # 👷‍♂️ man construction worker
+1F477 200D 2642 ; non-fully-qualified # 👷‍♂ man construction worker
+1F477 1F3FB 200D 2642 FE0F ; fully-qualified # 👷🏻‍♂️ man construction worker: light skin tone
+1F477 1F3FB 200D 2642 ; non-fully-qualified # 👷🏻‍♂ man construction worker: light skin tone
+1F477 1F3FC 200D 2642 FE0F ; fully-qualified # 👷🏼‍♂️ man construction worker: medium-light skin tone
+1F477 1F3FC 200D 2642 ; non-fully-qualified # 👷🏼‍♂ man construction worker: medium-light skin tone
+1F477 1F3FD 200D 2642 FE0F ; fully-qualified # 👷🏽‍♂️ man construction worker: medium skin tone
+1F477 1F3FD 200D 2642 ; non-fully-qualified # 👷🏽‍♂ man construction worker: medium skin tone
+1F477 1F3FE 200D 2642 FE0F ; fully-qualified # 👷🏾‍♂️ man construction worker: medium-dark skin tone
+1F477 1F3FE 200D 2642 ; non-fully-qualified # 👷🏾‍♂ man construction worker: medium-dark skin tone
+1F477 1F3FF 200D 2642 FE0F ; fully-qualified # 👷🏿‍♂️ man construction worker: dark skin tone
+1F477 1F3FF 200D 2642 ; non-fully-qualified # 👷🏿‍♂ man construction worker: dark skin tone
+1F477 200D 2640 FE0F ; fully-qualified # 👷‍♀️ woman construction worker
+1F477 200D 2640 ; non-fully-qualified # 👷‍♀ woman construction worker
+1F477 1F3FB 200D 2640 FE0F ; fully-qualified # 👷🏻‍♀️ woman construction worker: light skin tone
+1F477 1F3FB 200D 2640 ; non-fully-qualified # 👷🏻‍♀ woman construction worker: light skin tone
+1F477 1F3FC 200D 2640 FE0F ; fully-qualified # 👷🏼‍♀️ woman construction worker: medium-light skin tone
+1F477 1F3FC 200D 2640 ; non-fully-qualified # 👷🏼‍♀ woman construction worker: medium-light skin tone
+1F477 1F3FD 200D 2640 FE0F ; fully-qualified # 👷🏽‍♀️ woman construction worker: medium skin tone
+1F477 1F3FD 200D 2640 ; non-fully-qualified # 👷🏽‍♀ woman construction worker: medium skin tone
+1F477 1F3FE 200D 2640 FE0F ; fully-qualified # 👷🏾‍♀️ woman construction worker: medium-dark skin tone
+1F477 1F3FE 200D 2640 ; non-fully-qualified # 👷🏾‍♀ woman construction worker: medium-dark skin tone
+1F477 1F3FF 200D 2640 FE0F ; fully-qualified # 👷🏿‍♀️ woman construction worker: dark skin tone
+1F477 1F3FF 200D 2640 ; non-fully-qualified # 👷🏿‍♀ woman construction worker: dark skin tone
+1F934 ; fully-qualified # 🤴 prince
+1F934 1F3FB ; fully-qualified # 🤴🏻 prince: light skin tone
+1F934 1F3FC ; fully-qualified # 🤴🏼 prince: medium-light skin tone
+1F934 1F3FD ; fully-qualified # 🤴🏽 prince: medium skin tone
+1F934 1F3FE ; fully-qualified # 🤴🏾 prince: medium-dark skin tone
+1F934 1F3FF ; fully-qualified # 🤴🏿 prince: dark skin tone
+1F478 ; fully-qualified # 👸 princess
+1F478 1F3FB ; fully-qualified # 👸🏻 princess: light skin tone
+1F478 1F3FC ; fully-qualified # 👸🏼 princess: medium-light skin tone
+1F478 1F3FD ; fully-qualified # 👸🏽 princess: medium skin tone
+1F478 1F3FE ; fully-qualified # 👸🏾 princess: medium-dark skin tone
+1F478 1F3FF ; fully-qualified # 👸🏿 princess: dark skin tone
+1F473 ; fully-qualified # 👳 person wearing turban
+1F473 1F3FB ; fully-qualified # 👳🏻 person wearing turban: light skin tone
+1F473 1F3FC ; fully-qualified # 👳🏼 person wearing turban: medium-light skin tone
+1F473 1F3FD ; fully-qualified # 👳🏽 person wearing turban: medium skin tone
+1F473 1F3FE ; fully-qualified # 👳🏾 person wearing turban: medium-dark skin tone
+1F473 1F3FF ; fully-qualified # 👳🏿 person wearing turban: dark skin tone
+1F473 200D 2642 FE0F ; fully-qualified # 👳‍♂️ man wearing turban
+1F473 200D 2642 ; non-fully-qualified # 👳‍♂ man wearing turban
+1F473 1F3FB 200D 2642 FE0F ; fully-qualified # 👳🏻‍♂️ man wearing turban: light skin tone
+1F473 1F3FB 200D 2642 ; non-fully-qualified # 👳🏻‍♂ man wearing turban: light skin tone
+1F473 1F3FC 200D 2642 FE0F ; fully-qualified # 👳🏼‍♂️ man wearing turban: medium-light skin tone
+1F473 1F3FC 200D 2642 ; non-fully-qualified # 👳🏼‍♂ man wearing turban: medium-light skin tone
+1F473 1F3FD 200D 2642 FE0F ; fully-qualified # 👳🏽‍♂️ man wearing turban: medium skin tone
+1F473 1F3FD 200D 2642 ; non-fully-qualified # 👳🏽‍♂ man wearing turban: medium skin tone
+1F473 1F3FE 200D 2642 FE0F ; fully-qualified # 👳🏾‍♂️ man wearing turban: medium-dark skin tone
+1F473 1F3FE 200D 2642 ; non-fully-qualified # 👳🏾‍♂ man wearing turban: medium-dark skin tone
+1F473 1F3FF 200D 2642 FE0F ; fully-qualified # 👳🏿‍♂️ man wearing turban: dark skin tone
+1F473 1F3FF 200D 2642 ; non-fully-qualified # 👳🏿‍♂ man wearing turban: dark skin tone
+1F473 200D 2640 FE0F ; fully-qualified # 👳‍♀️ woman wearing turban
+1F473 200D 2640 ; non-fully-qualified # 👳‍♀ woman wearing turban
+1F473 1F3FB 200D 2640 FE0F ; fully-qualified # 👳🏻‍♀️ woman wearing turban: light skin tone
+1F473 1F3FB 200D 2640 ; non-fully-qualified # 👳🏻‍♀ woman wearing turban: light skin tone
+1F473 1F3FC 200D 2640 FE0F ; fully-qualified # 👳🏼‍♀️ woman wearing turban: medium-light skin tone
+1F473 1F3FC 200D 2640 ; non-fully-qualified # 👳🏼‍♀ woman wearing turban: medium-light skin tone
+1F473 1F3FD 200D 2640 FE0F ; fully-qualified # 👳🏽‍♀️ woman wearing turban: medium skin tone
+1F473 1F3FD 200D 2640 ; non-fully-qualified # 👳🏽‍♀ woman wearing turban: medium skin tone
+1F473 1F3FE 200D 2640 FE0F ; fully-qualified # 👳🏾‍♀️ woman wearing turban: medium-dark skin tone
+1F473 1F3FE 200D 2640 ; non-fully-qualified # 👳🏾‍♀ woman wearing turban: medium-dark skin tone
+1F473 1F3FF 200D 2640 FE0F ; fully-qualified # 👳🏿‍♀️ woman wearing turban: dark skin tone
+1F473 1F3FF 200D 2640 ; non-fully-qualified # 👳🏿‍♀ woman wearing turban: dark skin tone
+1F472 ; fully-qualified # 👲 man with Chinese cap
+1F472 1F3FB ; fully-qualified # 👲🏻 man with Chinese cap: light skin tone
+1F472 1F3FC ; fully-qualified # 👲🏼 man with Chinese cap: medium-light skin tone
+1F472 1F3FD ; fully-qualified # 👲🏽 man with Chinese cap: medium skin tone
+1F472 1F3FE ; fully-qualified # 👲🏾 man with Chinese cap: medium-dark skin tone
+1F472 1F3FF ; fully-qualified # 👲🏿 man with Chinese cap: dark skin tone
+1F9D5 ; fully-qualified # 🧕 woman with headscarf
+1F9D5 1F3FB ; fully-qualified # 🧕🏻 woman with headscarf: light skin tone
+1F9D5 1F3FC ; fully-qualified # 🧕🏼 woman with headscarf: medium-light skin tone
+1F9D5 1F3FD ; fully-qualified # 🧕🏽 woman with headscarf: medium skin tone
+1F9D5 1F3FE ; fully-qualified # 🧕🏾 woman with headscarf: medium-dark skin tone
+1F9D5 1F3FF ; fully-qualified # 🧕🏿 woman with headscarf: dark skin tone
+1F9D4 ; fully-qualified # 🧔 bearded person
+1F9D4 1F3FB ; fully-qualified # 🧔🏻 bearded person: light skin tone
+1F9D4 1F3FC ; fully-qualified # 🧔🏼 bearded person: medium-light skin tone
+1F9D4 1F3FD ; fully-qualified # 🧔🏽 bearded person: medium skin tone
+1F9D4 1F3FE ; fully-qualified # 🧔🏾 bearded person: medium-dark skin tone
+1F9D4 1F3FF ; fully-qualified # 🧔🏿 bearded person: dark skin tone
+1F471 ; fully-qualified # 👱 blond-haired person
+1F471 1F3FB ; fully-qualified # 👱🏻 blond-haired person: light skin tone
+1F471 1F3FC ; fully-qualified # 👱🏼 blond-haired person: medium-light skin tone
+1F471 1F3FD ; fully-qualified # 👱🏽 blond-haired person: medium skin tone
+1F471 1F3FE ; fully-qualified # 👱🏾 blond-haired person: medium-dark skin tone
+1F471 1F3FF ; fully-qualified # 👱🏿 blond-haired person: dark skin tone
+1F471 200D 2642 FE0F ; fully-qualified # 👱‍♂️ blond-haired man
+1F471 200D 2642 ; non-fully-qualified # 👱‍♂ blond-haired man
+1F471 1F3FB 200D 2642 FE0F ; fully-qualified # 👱🏻‍♂️ blond-haired man: light skin tone
+1F471 1F3FB 200D 2642 ; non-fully-qualified # 👱🏻‍♂ blond-haired man: light skin tone
+1F471 1F3FC 200D 2642 FE0F ; fully-qualified # 👱🏼‍♂️ blond-haired man: medium-light skin tone
+1F471 1F3FC 200D 2642 ; non-fully-qualified # 👱🏼‍♂ blond-haired man: medium-light skin tone
+1F471 1F3FD 200D 2642 FE0F ; fully-qualified # 👱🏽‍♂️ blond-haired man: medium skin tone
+1F471 1F3FD 200D 2642 ; non-fully-qualified # 👱🏽‍♂ blond-haired man: medium skin tone
+1F471 1F3FE 200D 2642 FE0F ; fully-qualified # 👱🏾‍♂️ blond-haired man: medium-dark skin tone
+1F471 1F3FE 200D 2642 ; non-fully-qualified # 👱🏾‍♂ blond-haired man: medium-dark skin tone
+1F471 1F3FF 200D 2642 FE0F ; fully-qualified # 👱🏿‍♂️ blond-haired man: dark skin tone
+1F471 1F3FF 200D 2642 ; non-fully-qualified # 👱🏿‍♂ blond-haired man: dark skin tone
+1F471 200D 2640 FE0F ; fully-qualified # 👱‍♀️ blond-haired woman
+1F471 200D 2640 ; non-fully-qualified # 👱‍♀ blond-haired woman
+1F471 1F3FB 200D 2640 FE0F ; fully-qualified # 👱🏻‍♀️ blond-haired woman: light skin tone
+1F471 1F3FB 200D 2640 ; non-fully-qualified # 👱🏻‍♀ blond-haired woman: light skin tone
+1F471 1F3FC 200D 2640 FE0F ; fully-qualified # 👱🏼‍♀️ blond-haired woman: medium-light skin tone
+1F471 1F3FC 200D 2640 ; non-fully-qualified # 👱🏼‍♀ blond-haired woman: medium-light skin tone
+1F471 1F3FD 200D 2640 FE0F ; fully-qualified # 👱🏽‍♀️ blond-haired woman: medium skin tone
+1F471 1F3FD 200D 2640 ; non-fully-qualified # 👱🏽‍♀ blond-haired woman: medium skin tone
+1F471 1F3FE 200D 2640 FE0F ; fully-qualified # 👱🏾‍♀️ blond-haired woman: medium-dark skin tone
+1F471 1F3FE 200D 2640 ; non-fully-qualified # 👱🏾‍♀ blond-haired woman: medium-dark skin tone
+1F471 1F3FF 200D 2640 FE0F ; fully-qualified # 👱🏿‍♀️ blond-haired woman: dark skin tone
+1F471 1F3FF 200D 2640 ; non-fully-qualified # 👱🏿‍♀ blond-haired woman: dark skin tone
+1F468 200D 1F9B0 ; fully-qualified # 👨‍🦰 man, red haired
+1F468 1F3FB 200D 1F9B0 ; fully-qualified # 👨🏻‍🦰 man, red haired: light skin tone
+1F468 1F3FC 200D 1F9B0 ; fully-qualified # 👨🏼‍🦰 man, red haired: medium-light skin tone
+1F468 1F3FD 200D 1F9B0 ; fully-qualified # 👨🏽‍🦰 man, red haired: medium skin tone
+1F468 1F3FE 200D 1F9B0 ; fully-qualified # 👨🏾‍🦰 man, red haired: medium-dark skin tone
+1F468 1F3FF 200D 1F9B0 ; fully-qualified # 👨🏿‍🦰 man, red haired: dark skin tone
+1F469 200D 1F9B0 ; fully-qualified # 👩‍🦰 woman, red haired
+1F469 1F3FB 200D 1F9B0 ; fully-qualified # 👩🏻‍🦰 woman, red haired: light skin tone
+1F469 1F3FC 200D 1F9B0 ; fully-qualified # 👩🏼‍🦰 woman, red haired: medium-light skin tone
+1F469 1F3FD 200D 1F9B0 ; fully-qualified # 👩🏽‍🦰 woman, red haired: medium skin tone
+1F469 1F3FE 200D 1F9B0 ; fully-qualified # 👩🏾‍🦰 woman, red haired: medium-dark skin tone
+1F469 1F3FF 200D 1F9B0 ; fully-qualified # 👩🏿‍🦰 woman, red haired: dark skin tone
+1F468 200D 1F9B1 ; fully-qualified # 👨‍🦱 man, curly haired
+1F468 1F3FB 200D 1F9B1 ; fully-qualified # 👨🏻‍🦱 man, curly haired: light skin tone
+1F468 1F3FC 200D 1F9B1 ; fully-qualified # 👨🏼‍🦱 man, curly haired: medium-light skin tone
+1F468 1F3FD 200D 1F9B1 ; fully-qualified # 👨🏽‍🦱 man, curly haired: medium skin tone
+1F468 1F3FE 200D 1F9B1 ; fully-qualified # 👨🏾‍🦱 man, curly haired: medium-dark skin tone
+1F468 1F3FF 200D 1F9B1 ; fully-qualified # 👨🏿‍🦱 man, curly haired: dark skin tone
+1F469 200D 1F9B1 ; fully-qualified # 👩‍🦱 woman, curly haired
+1F469 1F3FB 200D 1F9B1 ; fully-qualified # 👩🏻‍🦱 woman, curly haired: light skin tone
+1F469 1F3FC 200D 1F9B1 ; fully-qualified # 👩🏼‍🦱 woman, curly haired: medium-light skin tone
+1F469 1F3FD 200D 1F9B1 ; fully-qualified # 👩🏽‍🦱 woman, curly haired: medium skin tone
+1F469 1F3FE 200D 1F9B1 ; fully-qualified # 👩🏾‍🦱 woman, curly haired: medium-dark skin tone
+1F469 1F3FF 200D 1F9B1 ; fully-qualified # 👩🏿‍🦱 woman, curly haired: dark skin tone
+1F468 200D 1F9B2 ; fully-qualified # 👨‍🦲 man, bald
+1F468 1F3FB 200D 1F9B2 ; fully-qualified # 👨🏻‍🦲 man, bald: light skin tone
+1F468 1F3FC 200D 1F9B2 ; fully-qualified # 👨🏼‍🦲 man, bald: medium-light skin tone
+1F468 1F3FD 200D 1F9B2 ; fully-qualified # 👨🏽‍🦲 man, bald: medium skin tone
+1F468 1F3FE 200D 1F9B2 ; fully-qualified # 👨🏾‍🦲 man, bald: medium-dark skin tone
+1F468 1F3FF 200D 1F9B2 ; fully-qualified # 👨🏿‍🦲 man, bald: dark skin tone
+1F469 200D 1F9B2 ; fully-qualified # 👩‍🦲 woman, bald
+1F469 1F3FB 200D 1F9B2 ; fully-qualified # 👩🏻‍🦲 woman, bald: light skin tone
+1F469 1F3FC 200D 1F9B2 ; fully-qualified # 👩🏼‍🦲 woman, bald: medium-light skin tone
+1F469 1F3FD 200D 1F9B2 ; fully-qualified # 👩🏽‍🦲 woman, bald: medium skin tone
+1F469 1F3FE 200D 1F9B2 ; fully-qualified # 👩🏾‍🦲 woman, bald: medium-dark skin tone
+1F469 1F3FF 200D 1F9B2 ; fully-qualified # 👩🏿‍🦲 woman, bald: dark skin tone
+1F468 200D 1F9B3 ; fully-qualified # 👨‍🦳 man, white haired
+1F468 1F3FB 200D 1F9B3 ; fully-qualified # 👨🏻‍🦳 man, white haired: light skin tone
+1F468 1F3FC 200D 1F9B3 ; fully-qualified # 👨🏼‍🦳 man, white haired: medium-light skin tone
+1F468 1F3FD 200D 1F9B3 ; fully-qualified # 👨🏽‍🦳 man, white haired: medium skin tone
+1F468 1F3FE 200D 1F9B3 ; fully-qualified # 👨🏾‍🦳 man, white haired: medium-dark skin tone
+1F468 1F3FF 200D 1F9B3 ; fully-qualified # 👨🏿‍🦳 man, white haired: dark skin tone
+1F469 200D 1F9B3 ; fully-qualified # 👩‍🦳 woman, white haired
+1F469 1F3FB 200D 1F9B3 ; fully-qualified # 👩🏻‍🦳 woman, white haired: light skin tone
+1F469 1F3FC 200D 1F9B3 ; fully-qualified # 👩🏼‍🦳 woman, white haired: medium-light skin tone
+1F469 1F3FD 200D 1F9B3 ; fully-qualified # 👩🏽‍🦳 woman, white haired: medium skin tone
+1F469 1F3FE 200D 1F9B3 ; fully-qualified # 👩🏾‍🦳 woman, white haired: medium-dark skin tone
+1F469 1F3FF 200D 1F9B3 ; fully-qualified # 👩🏿‍🦳 woman, white haired: dark skin tone
+1F935 ; fully-qualified # 🤵 man in tuxedo
+1F935 1F3FB ; fully-qualified # 🤵🏻 man in tuxedo: light skin tone
+1F935 1F3FC ; fully-qualified # 🤵🏼 man in tuxedo: medium-light skin tone
+1F935 1F3FD ; fully-qualified # 🤵🏽 man in tuxedo: medium skin tone
+1F935 1F3FE ; fully-qualified # 🤵🏾 man in tuxedo: medium-dark skin tone
+1F935 1F3FF ; fully-qualified # 🤵🏿 man in tuxedo: dark skin tone
+1F470 ; fully-qualified # 👰 bride with veil
+1F470 1F3FB ; fully-qualified # 👰🏻 bride with veil: light skin tone
+1F470 1F3FC ; fully-qualified # 👰🏼 bride with veil: medium-light skin tone
+1F470 1F3FD ; fully-qualified # 👰🏽 bride with veil: medium skin tone
+1F470 1F3FE ; fully-qualified # 👰🏾 bride with veil: medium-dark skin tone
+1F470 1F3FF ; fully-qualified # 👰🏿 bride with veil: dark skin tone
+1F930 ; fully-qualified # 🤰 pregnant woman
+1F930 1F3FB ; fully-qualified # 🤰🏻 pregnant woman: light skin tone
+1F930 1F3FC ; fully-qualified # 🤰🏼 pregnant woman: medium-light skin tone
+1F930 1F3FD ; fully-qualified # 🤰🏽 pregnant woman: medium skin tone
+1F930 1F3FE ; fully-qualified # 🤰🏾 pregnant woman: medium-dark skin tone
+1F930 1F3FF ; fully-qualified # 🤰🏿 pregnant woman: dark skin tone
+1F931 ; fully-qualified # 🤱 breast-feeding
+1F931 1F3FB ; fully-qualified # 🤱🏻 breast-feeding: light skin tone
+1F931 1F3FC ; fully-qualified # 🤱🏼 breast-feeding: medium-light skin tone
+1F931 1F3FD ; fully-qualified # 🤱🏽 breast-feeding: medium skin tone
+1F931 1F3FE ; fully-qualified # 🤱🏾 breast-feeding: medium-dark skin tone
+1F931 1F3FF ; fully-qualified # 🤱🏿 breast-feeding: dark skin tone
+
+# subgroup: person-fantasy
+1F47C ; fully-qualified # 👼 baby angel
+1F47C 1F3FB ; fully-qualified # 👼🏻 baby angel: light skin tone
+1F47C 1F3FC ; fully-qualified # 👼🏼 baby angel: medium-light skin tone
+1F47C 1F3FD ; fully-qualified # 👼🏽 baby angel: medium skin tone
+1F47C 1F3FE ; fully-qualified # 👼🏾 baby angel: medium-dark skin tone
+1F47C 1F3FF ; fully-qualified # 👼🏿 baby angel: dark skin tone
+1F385 ; fully-qualified # 🎅 Santa Claus
+1F385 1F3FB ; fully-qualified # 🎅🏻 Santa Claus: light skin tone
+1F385 1F3FC ; fully-qualified # 🎅🏼 Santa Claus: medium-light skin tone
+1F385 1F3FD ; fully-qualified # 🎅🏽 Santa Claus: medium skin tone
+1F385 1F3FE ; fully-qualified # 🎅🏾 Santa Claus: medium-dark skin tone
+1F385 1F3FF ; fully-qualified # 🎅🏿 Santa Claus: dark skin tone
+1F936 ; fully-qualified # 🤶 Mrs. Claus
+1F936 1F3FB ; fully-qualified # 🤶🏻 Mrs. Claus: light skin tone
+1F936 1F3FC ; fully-qualified # 🤶🏼 Mrs. Claus: medium-light skin tone
+1F936 1F3FD ; fully-qualified # 🤶🏽 Mrs. Claus: medium skin tone
+1F936 1F3FE ; fully-qualified # 🤶🏾 Mrs. Claus: medium-dark skin tone
+1F936 1F3FF ; fully-qualified # 🤶🏿 Mrs. Claus: dark skin tone
+1F9B8 ; fully-qualified # 🦸 superhero
+1F9B8 1F3FB ; fully-qualified # 🦸🏻 superhero: light skin tone
+1F9B8 1F3FC ; fully-qualified # 🦸🏼 superhero: medium-light skin tone
+1F9B8 1F3FD ; fully-qualified # 🦸🏽 superhero: medium skin tone
+1F9B8 1F3FE ; fully-qualified # 🦸🏾 superhero: medium-dark skin tone
+1F9B8 1F3FF ; fully-qualified # 🦸🏿 superhero: dark skin tone
+1F9B8 200D 2640 FE0F ; fully-qualified # 🦸‍♀️ woman superhero
+1F9B8 200D 2640 ; non-fully-qualified # 🦸‍♀ woman superhero
+1F9B8 1F3FB 200D 2640 FE0F ; fully-qualified # 🦸🏻‍♀️ woman superhero: light skin tone
+1F9B8 1F3FB 200D 2640 ; non-fully-qualified # 🦸🏻‍♀ woman superhero: light skin tone
+1F9B8 1F3FC 200D 2640 FE0F ; fully-qualified # 🦸🏼‍♀️ woman superhero: medium-light skin tone
+1F9B8 1F3FC 200D 2640 ; non-fully-qualified # 🦸🏼‍♀ woman superhero: medium-light skin tone
+1F9B8 1F3FD 200D 2640 FE0F ; fully-qualified # 🦸🏽‍♀️ woman superhero: medium skin tone
+1F9B8 1F3FD 200D 2640 ; non-fully-qualified # 🦸🏽‍♀ woman superhero: medium skin tone
+1F9B8 1F3FE 200D 2640 FE0F ; fully-qualified # 🦸🏾‍♀️ woman superhero: medium-dark skin tone
+1F9B8 1F3FE 200D 2640 ; non-fully-qualified # 🦸🏾‍♀ woman superhero: medium-dark skin tone
+1F9B8 1F3FF 200D 2640 FE0F ; fully-qualified # 🦸🏿‍♀️ woman superhero: dark skin tone
+1F9B8 1F3FF 200D 2640 ; non-fully-qualified # 🦸🏿‍♀ woman superhero: dark skin tone
+1F9B8 200D 2642 FE0F ; fully-qualified # 🦸‍♂️ man superhero
+1F9B8 200D 2642 ; non-fully-qualified # 🦸‍♂ man superhero
+1F9B8 1F3FB 200D 2642 FE0F ; fully-qualified # 🦸🏻‍♂️ man superhero: light skin tone
+1F9B8 1F3FB 200D 2642 ; non-fully-qualified # 🦸🏻‍♂ man superhero: light skin tone
+1F9B8 1F3FC 200D 2642 FE0F ; fully-qualified # 🦸🏼‍♂️ man superhero: medium-light skin tone
+1F9B8 1F3FC 200D 2642 ; non-fully-qualified # 🦸🏼‍♂ man superhero: medium-light skin tone
+1F9B8 1F3FD 200D 2642 FE0F ; fully-qualified # 🦸🏽‍♂️ man superhero: medium skin tone
+1F9B8 1F3FD 200D 2642 ; non-fully-qualified # 🦸🏽‍♂ man superhero: medium skin tone
+1F9B8 1F3FE 200D 2642 FE0F ; fully-qualified # 🦸🏾‍♂️ man superhero: medium-dark skin tone
+1F9B8 1F3FE 200D 2642 ; non-fully-qualified # 🦸🏾‍♂ man superhero: medium-dark skin tone
+1F9B8 1F3FF 200D 2642 FE0F ; fully-qualified # 🦸🏿‍♂️ man superhero: dark skin tone
+1F9B8 1F3FF 200D 2642 ; non-fully-qualified # 🦸🏿‍♂ man superhero: dark skin tone
+1F9B9 ; fully-qualified # 🦹 supervillain
+1F9B9 1F3FB ; fully-qualified # 🦹🏻 supervillain: light skin tone
+1F9B9 1F3FC ; fully-qualified # 🦹🏼 supervillain: medium-light skin tone
+1F9B9 1F3FD ; fully-qualified # 🦹🏽 supervillain: medium skin tone
+1F9B9 1F3FE ; fully-qualified # 🦹🏾 supervillain: medium-dark skin tone
+1F9B9 1F3FF ; fully-qualified # 🦹🏿 supervillain: dark skin tone
+1F9B9 200D 2640 FE0F ; fully-qualified # 🦹‍♀️ woman supervillain
+1F9B9 200D 2640 ; non-fully-qualified # 🦹‍♀ woman supervillain
+1F9B9 1F3FB 200D 2640 FE0F ; fully-qualified # 🦹🏻‍♀️ woman supervillain: light skin tone
+1F9B9 1F3FB 200D 2640 ; non-fully-qualified # 🦹🏻‍♀ woman supervillain: light skin tone
+1F9B9 1F3FC 200D 2640 FE0F ; fully-qualified # 🦹🏼‍♀️ woman supervillain: medium-light skin tone
+1F9B9 1F3FC 200D 2640 ; non-fully-qualified # 🦹🏼‍♀ woman supervillain: medium-light skin tone
+1F9B9 1F3FD 200D 2640 FE0F ; fully-qualified # 🦹🏽‍♀️ woman supervillain: medium skin tone
+1F9B9 1F3FD 200D 2640 ; non-fully-qualified # 🦹🏽‍♀ woman supervillain: medium skin tone
+1F9B9 1F3FE 200D 2640 FE0F ; fully-qualified # 🦹🏾‍♀️ woman supervillain: medium-dark skin tone
+1F9B9 1F3FE 200D 2640 ; non-fully-qualified # 🦹🏾‍♀ woman supervillain: medium-dark skin tone
+1F9B9 1F3FF 200D 2640 FE0F ; fully-qualified # 🦹🏿‍♀️ woman supervillain: dark skin tone
+1F9B9 1F3FF 200D 2640 ; non-fully-qualified # 🦹🏿‍♀ woman supervillain: dark skin tone
+1F9B9 200D 2642 FE0F ; fully-qualified # 🦹‍♂️ man supervillain
+1F9B9 200D 2642 ; non-fully-qualified # 🦹‍♂ man supervillain
+1F9B9 1F3FB 200D 2642 FE0F ; fully-qualified # 🦹🏻‍♂️ man supervillain: light skin tone
+1F9B9 1F3FB 200D 2642 ; non-fully-qualified # 🦹🏻‍♂ man supervillain: light skin tone
+1F9B9 1F3FC 200D 2642 FE0F ; fully-qualified # 🦹🏼‍♂️ man supervillain: medium-light skin tone
+1F9B9 1F3FC 200D 2642 ; non-fully-qualified # 🦹🏼‍♂ man supervillain: medium-light skin tone
+1F9B9 1F3FD 200D 2642 FE0F ; fully-qualified # 🦹🏽‍♂️ man supervillain: medium skin tone
+1F9B9 1F3FD 200D 2642 ; non-fully-qualified # 🦹🏽‍♂ man supervillain: medium skin tone
+1F9B9 1F3FE 200D 2642 FE0F ; fully-qualified # 🦹🏾‍♂️ man supervillain: medium-dark skin tone
+1F9B9 1F3FE 200D 2642 ; non-fully-qualified # 🦹🏾‍♂ man supervillain: medium-dark skin tone
+1F9B9 1F3FF 200D 2642 FE0F ; fully-qualified # 🦹🏿‍♂️ man supervillain: dark skin tone
+1F9B9 1F3FF 200D 2642 ; non-fully-qualified # 🦹🏿‍♂ man supervillain: dark skin tone
+1F9D9 ; fully-qualified # 🧙 mage
+1F9D9 1F3FB ; fully-qualified # 🧙🏻 mage: light skin tone
+1F9D9 1F3FC ; fully-qualified # 🧙🏼 mage: medium-light skin tone
+1F9D9 1F3FD ; fully-qualified # 🧙🏽 mage: medium skin tone
+1F9D9 1F3FE ; fully-qualified # 🧙🏾 mage: medium-dark skin tone
+1F9D9 1F3FF ; fully-qualified # 🧙🏿 mage: dark skin tone
+1F9D9 200D 2640 FE0F ; fully-qualified # 🧙‍♀️ woman mage
+1F9D9 200D 2640 ; non-fully-qualified # 🧙‍♀ woman mage
+1F9D9 1F3FB 200D 2640 FE0F ; fully-qualified # 🧙🏻‍♀️ woman mage: light skin tone
+1F9D9 1F3FB 200D 2640 ; non-fully-qualified # 🧙🏻‍♀ woman mage: light skin tone
+1F9D9 1F3FC 200D 2640 FE0F ; fully-qualified # 🧙🏼‍♀️ woman mage: medium-light skin tone
+1F9D9 1F3FC 200D 2640 ; non-fully-qualified # 🧙🏼‍♀ woman mage: medium-light skin tone
+1F9D9 1F3FD 200D 2640 FE0F ; fully-qualified # 🧙🏽‍♀️ woman mage: medium skin tone
+1F9D9 1F3FD 200D 2640 ; non-fully-qualified # 🧙🏽‍♀ woman mage: medium skin tone
+1F9D9 1F3FE 200D 2640 FE0F ; fully-qualified # 🧙🏾‍♀️ woman mage: medium-dark skin tone
+1F9D9 1F3FE 200D 2640 ; non-fully-qualified # 🧙🏾‍♀ woman mage: medium-dark skin tone
+1F9D9 1F3FF 200D 2640 FE0F ; fully-qualified # 🧙🏿‍♀️ woman mage: dark skin tone
+1F9D9 1F3FF 200D 2640 ; non-fully-qualified # 🧙🏿‍♀ woman mage: dark skin tone
+1F9D9 200D 2642 FE0F ; fully-qualified # 🧙‍♂️ man mage
+1F9D9 200D 2642 ; non-fully-qualified # 🧙‍♂ man mage
+1F9D9 1F3FB 200D 2642 FE0F ; fully-qualified # 🧙🏻‍♂️ man mage: light skin tone
+1F9D9 1F3FB 200D 2642 ; non-fully-qualified # 🧙🏻‍♂ man mage: light skin tone
+1F9D9 1F3FC 200D 2642 FE0F ; fully-qualified # 🧙🏼‍♂️ man mage: medium-light skin tone
+1F9D9 1F3FC 200D 2642 ; non-fully-qualified # 🧙🏼‍♂ man mage: medium-light skin tone
+1F9D9 1F3FD 200D 2642 FE0F ; fully-qualified # 🧙🏽‍♂️ man mage: medium skin tone
+1F9D9 1F3FD 200D 2642 ; non-fully-qualified # 🧙🏽‍♂ man mage: medium skin tone
+1F9D9 1F3FE 200D 2642 FE0F ; fully-qualified # 🧙🏾‍♂️ man mage: medium-dark skin tone
+1F9D9 1F3FE 200D 2642 ; non-fully-qualified # 🧙🏾‍♂ man mage: medium-dark skin tone
+1F9D9 1F3FF 200D 2642 FE0F ; fully-qualified # 🧙🏿‍♂️ man mage: dark skin tone
+1F9D9 1F3FF 200D 2642 ; non-fully-qualified # 🧙🏿‍♂ man mage: dark skin tone
+1F9DA ; fully-qualified # 🧚 fairy
+1F9DA 1F3FB ; fully-qualified # 🧚🏻 fairy: light skin tone
+1F9DA 1F3FC ; fully-qualified # 🧚🏼 fairy: medium-light skin tone
+1F9DA 1F3FD ; fully-qualified # 🧚🏽 fairy: medium skin tone
+1F9DA 1F3FE ; fully-qualified # 🧚🏾 fairy: medium-dark skin tone
+1F9DA 1F3FF ; fully-qualified # 🧚🏿 fairy: dark skin tone
+1F9DA 200D 2640 FE0F ; fully-qualified # 🧚‍♀️ woman fairy
+1F9DA 200D 2640 ; non-fully-qualified # 🧚‍♀ woman fairy
+1F9DA 1F3FB 200D 2640 FE0F ; fully-qualified # 🧚🏻‍♀️ woman fairy: light skin tone
+1F9DA 1F3FB 200D 2640 ; non-fully-qualified # 🧚🏻‍♀ woman fairy: light skin tone
+1F9DA 1F3FC 200D 2640 FE0F ; fully-qualified # 🧚🏼‍♀️ woman fairy: medium-light skin tone
+1F9DA 1F3FC 200D 2640 ; non-fully-qualified # 🧚🏼‍♀ woman fairy: medium-light skin tone
+1F9DA 1F3FD 200D 2640 FE0F ; fully-qualified # 🧚🏽‍♀️ woman fairy: medium skin tone
+1F9DA 1F3FD 200D 2640 ; non-fully-qualified # 🧚🏽‍♀ woman fairy: medium skin tone
+1F9DA 1F3FE 200D 2640 FE0F ; fully-qualified # 🧚🏾‍♀️ woman fairy: medium-dark skin tone
+1F9DA 1F3FE 200D 2640 ; non-fully-qualified # 🧚🏾‍♀ woman fairy: medium-dark skin tone
+1F9DA 1F3FF 200D 2640 FE0F ; fully-qualified # 🧚🏿‍♀️ woman fairy: dark skin tone
+1F9DA 1F3FF 200D 2640 ; non-fully-qualified # 🧚🏿‍♀ woman fairy: dark skin tone
+1F9DA 200D 2642 FE0F ; fully-qualified # 🧚‍♂️ man fairy
+1F9DA 200D 2642 ; non-fully-qualified # 🧚‍♂ man fairy
+1F9DA 1F3FB 200D 2642 FE0F ; fully-qualified # 🧚🏻‍♂️ man fairy: light skin tone
+1F9DA 1F3FB 200D 2642 ; non-fully-qualified # 🧚🏻‍♂ man fairy: light skin tone
+1F9DA 1F3FC 200D 2642 FE0F ; fully-qualified # 🧚🏼‍♂️ man fairy: medium-light skin tone
+1F9DA 1F3FC 200D 2642 ; non-fully-qualified # 🧚🏼‍♂ man fairy: medium-light skin tone
+1F9DA 1F3FD 200D 2642 FE0F ; fully-qualified # 🧚🏽‍♂️ man fairy: medium skin tone
+1F9DA 1F3FD 200D 2642 ; non-fully-qualified # 🧚🏽‍♂ man fairy: medium skin tone
+1F9DA 1F3FE 200D 2642 FE0F ; fully-qualified # 🧚🏾‍♂️ man fairy: medium-dark skin tone
+1F9DA 1F3FE 200D 2642 ; non-fully-qualified # 🧚🏾‍♂ man fairy: medium-dark skin tone
+1F9DA 1F3FF 200D 2642 FE0F ; fully-qualified # 🧚🏿‍♂️ man fairy: dark skin tone
+1F9DA 1F3FF 200D 2642 ; non-fully-qualified # 🧚🏿‍♂ man fairy: dark skin tone
+1F9DB ; fully-qualified # 🧛 vampire
+1F9DB 1F3FB ; fully-qualified # 🧛🏻 vampire: light skin tone
+1F9DB 1F3FC ; fully-qualified # 🧛🏼 vampire: medium-light skin tone
+1F9DB 1F3FD ; fully-qualified # 🧛🏽 vampire: medium skin tone
+1F9DB 1F3FE ; fully-qualified # 🧛🏾 vampire: medium-dark skin tone
+1F9DB 1F3FF ; fully-qualified # 🧛🏿 vampire: dark skin tone
+1F9DB 200D 2640 FE0F ; fully-qualified # 🧛‍♀️ woman vampire
+1F9DB 200D 2640 ; non-fully-qualified # 🧛‍♀ woman vampire
+1F9DB 1F3FB 200D 2640 FE0F ; fully-qualified # 🧛🏻‍♀️ woman vampire: light skin tone
+1F9DB 1F3FB 200D 2640 ; non-fully-qualified # 🧛🏻‍♀ woman vampire: light skin tone
+1F9DB 1F3FC 200D 2640 FE0F ; fully-qualified # 🧛🏼‍♀️ woman vampire: medium-light skin tone
+1F9DB 1F3FC 200D 2640 ; non-fully-qualified # 🧛🏼‍♀ woman vampire: medium-light skin tone
+1F9DB 1F3FD 200D 2640 FE0F ; fully-qualified # 🧛🏽‍♀️ woman vampire: medium skin tone
+1F9DB 1F3FD 200D 2640 ; non-fully-qualified # 🧛🏽‍♀ woman vampire: medium skin tone
+1F9DB 1F3FE 200D 2640 FE0F ; fully-qualified # 🧛🏾‍♀️ woman vampire: medium-dark skin tone
+1F9DB 1F3FE 200D 2640 ; non-fully-qualified # 🧛🏾‍♀ woman vampire: medium-dark skin tone
+1F9DB 1F3FF 200D 2640 FE0F ; fully-qualified # 🧛🏿‍♀️ woman vampire: dark skin tone
+1F9DB 1F3FF 200D 2640 ; non-fully-qualified # 🧛🏿‍♀ woman vampire: dark skin tone
+1F9DB 200D 2642 FE0F ; fully-qualified # 🧛‍♂️ man vampire
+1F9DB 200D 2642 ; non-fully-qualified # 🧛‍♂ man vampire
+1F9DB 1F3FB 200D 2642 FE0F ; fully-qualified # 🧛🏻‍♂️ man vampire: light skin tone
+1F9DB 1F3FB 200D 2642 ; non-fully-qualified # 🧛🏻‍♂ man vampire: light skin tone
+1F9DB 1F3FC 200D 2642 FE0F ; fully-qualified # 🧛🏼‍♂️ man vampire: medium-light skin tone
+1F9DB 1F3FC 200D 2642 ; non-fully-qualified # 🧛🏼‍♂ man vampire: medium-light skin tone
+1F9DB 1F3FD 200D 2642 FE0F ; fully-qualified # 🧛🏽‍♂️ man vampire: medium skin tone
+1F9DB 1F3FD 200D 2642 ; non-fully-qualified # 🧛🏽‍♂ man vampire: medium skin tone
+1F9DB 1F3FE 200D 2642 FE0F ; fully-qualified # 🧛🏾‍♂️ man vampire: medium-dark skin tone
+1F9DB 1F3FE 200D 2642 ; non-fully-qualified # 🧛🏾‍♂ man vampire: medium-dark skin tone
+1F9DB 1F3FF 200D 2642 FE0F ; fully-qualified # 🧛🏿‍♂️ man vampire: dark skin tone
+1F9DB 1F3FF 200D 2642 ; non-fully-qualified # 🧛🏿‍♂ man vampire: dark skin tone
+1F9DC ; fully-qualified # 🧜 merperson
+1F9DC 1F3FB ; fully-qualified # 🧜🏻 merperson: light skin tone
+1F9DC 1F3FC ; fully-qualified # 🧜🏼 merperson: medium-light skin tone
+1F9DC 1F3FD ; fully-qualified # 🧜🏽 merperson: medium skin tone
+1F9DC 1F3FE ; fully-qualified # 🧜🏾 merperson: medium-dark skin tone
+1F9DC 1F3FF ; fully-qualified # 🧜🏿 merperson: dark skin tone
+1F9DC 200D 2640 FE0F ; fully-qualified # 🧜‍♀️ mermaid
+1F9DC 200D 2640 ; non-fully-qualified # 🧜‍♀ mermaid
+1F9DC 1F3FB 200D 2640 FE0F ; fully-qualified # 🧜🏻‍♀️ mermaid: light skin tone
+1F9DC 1F3FB 200D 2640 ; non-fully-qualified # 🧜🏻‍♀ mermaid: light skin tone
+1F9DC 1F3FC 200D 2640 FE0F ; fully-qualified # 🧜🏼‍♀️ mermaid: medium-light skin tone
+1F9DC 1F3FC 200D 2640 ; non-fully-qualified # 🧜🏼‍♀ mermaid: medium-light skin tone
+1F9DC 1F3FD 200D 2640 FE0F ; fully-qualified # 🧜🏽‍♀️ mermaid: medium skin tone
+1F9DC 1F3FD 200D 2640 ; non-fully-qualified # 🧜🏽‍♀ mermaid: medium skin tone
+1F9DC 1F3FE 200D 2640 FE0F ; fully-qualified # 🧜🏾‍♀️ mermaid: medium-dark skin tone
+1F9DC 1F3FE 200D 2640 ; non-fully-qualified # 🧜🏾‍♀ mermaid: medium-dark skin tone
+1F9DC 1F3FF 200D 2640 FE0F ; fully-qualified # 🧜🏿‍♀️ mermaid: dark skin tone
+1F9DC 1F3FF 200D 2640 ; non-fully-qualified # 🧜🏿‍♀ mermaid: dark skin tone
+1F9DC 200D 2642 FE0F ; fully-qualified # 🧜‍♂️ merman
+1F9DC 200D 2642 ; non-fully-qualified # 🧜‍♂ merman
+1F9DC 1F3FB 200D 2642 FE0F ; fully-qualified # 🧜🏻‍♂️ merman: light skin tone
+1F9DC 1F3FB 200D 2642 ; non-fully-qualified # 🧜🏻‍♂ merman: light skin tone
+1F9DC 1F3FC 200D 2642 FE0F ; fully-qualified # 🧜🏼‍♂️ merman: medium-light skin tone
+1F9DC 1F3FC 200D 2642 ; non-fully-qualified # 🧜🏼‍♂ merman: medium-light skin tone
+1F9DC 1F3FD 200D 2642 FE0F ; fully-qualified # 🧜🏽‍♂️ merman: medium skin tone
+1F9DC 1F3FD 200D 2642 ; non-fully-qualified # 🧜🏽‍♂ merman: medium skin tone
+1F9DC 1F3FE 200D 2642 FE0F ; fully-qualified # 🧜🏾‍♂️ merman: medium-dark skin tone
+1F9DC 1F3FE 200D 2642 ; non-fully-qualified # 🧜🏾‍♂ merman: medium-dark skin tone
+1F9DC 1F3FF 200D 2642 FE0F ; fully-qualified # 🧜🏿‍♂️ merman: dark skin tone
+1F9DC 1F3FF 200D 2642 ; non-fully-qualified # 🧜🏿‍♂ merman: dark skin tone
+1F9DD ; fully-qualified # 🧝 elf
+1F9DD 1F3FB ; fully-qualified # 🧝🏻 elf: light skin tone
+1F9DD 1F3FC ; fully-qualified # 🧝🏼 elf: medium-light skin tone
+1F9DD 1F3FD ; fully-qualified # 🧝🏽 elf: medium skin tone
+1F9DD 1F3FE ; fully-qualified # 🧝🏾 elf: medium-dark skin tone
+1F9DD 1F3FF ; fully-qualified # 🧝🏿 elf: dark skin tone
+1F9DD 200D 2640 FE0F ; fully-qualified # 🧝‍♀️ woman elf
+1F9DD 200D 2640 ; non-fully-qualified # 🧝‍♀ woman elf
+1F9DD 1F3FB 200D 2640 FE0F ; fully-qualified # 🧝🏻‍♀️ woman elf: light skin tone
+1F9DD 1F3FB 200D 2640 ; non-fully-qualified # 🧝🏻‍♀ woman elf: light skin tone
+1F9DD 1F3FC 200D 2640 FE0F ; fully-qualified # 🧝🏼‍♀️ woman elf: medium-light skin tone
+1F9DD 1F3FC 200D 2640 ; non-fully-qualified # 🧝🏼‍♀ woman elf: medium-light skin tone
+1F9DD 1F3FD 200D 2640 FE0F ; fully-qualified # 🧝🏽‍♀️ woman elf: medium skin tone
+1F9DD 1F3FD 200D 2640 ; non-fully-qualified # 🧝🏽‍♀ woman elf: medium skin tone
+1F9DD 1F3FE 200D 2640 FE0F ; fully-qualified # 🧝🏾‍♀️ woman elf: medium-dark skin tone
+1F9DD 1F3FE 200D 2640 ; non-fully-qualified # 🧝🏾‍♀ woman elf: medium-dark skin tone
+1F9DD 1F3FF 200D 2640 FE0F ; fully-qualified # 🧝🏿‍♀️ woman elf: dark skin tone
+1F9DD 1F3FF 200D 2640 ; non-fully-qualified # 🧝🏿‍♀ woman elf: dark skin tone
+1F9DD 200D 2642 FE0F ; fully-qualified # 🧝‍♂️ man elf
+1F9DD 200D 2642 ; non-fully-qualified # 🧝‍♂ man elf
+1F9DD 1F3FB 200D 2642 FE0F ; fully-qualified # 🧝🏻‍♂️ man elf: light skin tone
+1F9DD 1F3FB 200D 2642 ; non-fully-qualified # 🧝🏻‍♂ man elf: light skin tone
+1F9DD 1F3FC 200D 2642 FE0F ; fully-qualified # 🧝🏼‍♂️ man elf: medium-light skin tone
+1F9DD 1F3FC 200D 2642 ; non-fully-qualified # 🧝🏼‍♂ man elf: medium-light skin tone
+1F9DD 1F3FD 200D 2642 FE0F ; fully-qualified # 🧝🏽‍♂️ man elf: medium skin tone
+1F9DD 1F3FD 200D 2642 ; non-fully-qualified # 🧝🏽‍♂ man elf: medium skin tone
+1F9DD 1F3FE 200D 2642 FE0F ; fully-qualified # 🧝🏾‍♂️ man elf: medium-dark skin tone
+1F9DD 1F3FE 200D 2642 ; non-fully-qualified # 🧝🏾‍♂ man elf: medium-dark skin tone
+1F9DD 1F3FF 200D 2642 FE0F ; fully-qualified # 🧝🏿‍♂️ man elf: dark skin tone
+1F9DD 1F3FF 200D 2642 ; non-fully-qualified # 🧝🏿‍♂ man elf: dark skin tone
+1F9DE ; fully-qualified # 🧞 genie
+1F9DE 200D 2640 FE0F ; fully-qualified # 🧞‍♀️ woman genie
+1F9DE 200D 2640 ; non-fully-qualified # 🧞‍♀ woman genie
+1F9DE 200D 2642 FE0F ; fully-qualified # 🧞‍♂️ man genie
+1F9DE 200D 2642 ; non-fully-qualified # 🧞‍♂ man genie
+1F9DF ; fully-qualified # 🧟 zombie
+1F9DF 200D 2640 FE0F ; fully-qualified # 🧟‍♀️ woman zombie
+1F9DF 200D 2640 ; non-fully-qualified # 🧟‍♀ woman zombie
+1F9DF 200D 2642 FE0F ; fully-qualified # 🧟‍♂️ man zombie
+1F9DF 200D 2642 ; non-fully-qualified # 🧟‍♂ man zombie
+
+# subgroup: person-gesture
+1F64D ; fully-qualified # 🙍 person frowning
+1F64D 1F3FB ; fully-qualified # 🙍🏻 person frowning: light skin tone
+1F64D 1F3FC ; fully-qualified # 🙍🏼 person frowning: medium-light skin tone
+1F64D 1F3FD ; fully-qualified # 🙍🏽 person frowning: medium skin tone
+1F64D 1F3FE ; fully-qualified # 🙍🏾 person frowning: medium-dark skin tone
+1F64D 1F3FF ; fully-qualified # 🙍🏿 person frowning: dark skin tone
+1F64D 200D 2642 FE0F ; fully-qualified # 🙍‍♂️ man frowning
+1F64D 200D 2642 ; non-fully-qualified # 🙍‍♂ man frowning
+1F64D 1F3FB 200D 2642 FE0F ; fully-qualified # 🙍🏻‍♂️ man frowning: light skin tone
+1F64D 1F3FB 200D 2642 ; non-fully-qualified # 🙍🏻‍♂ man frowning: light skin tone
+1F64D 1F3FC 200D 2642 FE0F ; fully-qualified # 🙍🏼‍♂️ man frowning: medium-light skin tone
+1F64D 1F3FC 200D 2642 ; non-fully-qualified # 🙍🏼‍♂ man frowning: medium-light skin tone
+1F64D 1F3FD 200D 2642 FE0F ; fully-qualified # 🙍🏽‍♂️ man frowning: medium skin tone
+1F64D 1F3FD 200D 2642 ; non-fully-qualified # 🙍🏽‍♂ man frowning: medium skin tone
+1F64D 1F3FE 200D 2642 FE0F ; fully-qualified # 🙍🏾‍♂️ man frowning: medium-dark skin tone
+1F64D 1F3FE 200D 2642 ; non-fully-qualified # 🙍🏾‍♂ man frowning: medium-dark skin tone
+1F64D 1F3FF 200D 2642 FE0F ; fully-qualified # 🙍🏿‍♂️ man frowning: dark skin tone
+1F64D 1F3FF 200D 2642 ; non-fully-qualified # 🙍🏿‍♂ man frowning: dark skin tone
+1F64D 200D 2640 FE0F ; fully-qualified # 🙍‍♀️ woman frowning
+1F64D 200D 2640 ; non-fully-qualified # 🙍‍♀ woman frowning
+1F64D 1F3FB 200D 2640 FE0F ; fully-qualified # 🙍🏻‍♀️ woman frowning: light skin tone
+1F64D 1F3FB 200D 2640 ; non-fully-qualified # 🙍🏻‍♀ woman frowning: light skin tone
+1F64D 1F3FC 200D 2640 FE0F ; fully-qualified # 🙍🏼‍♀️ woman frowning: medium-light skin tone
+1F64D 1F3FC 200D 2640 ; non-fully-qualified # 🙍🏼‍♀ woman frowning: medium-light skin tone
+1F64D 1F3FD 200D 2640 FE0F ; fully-qualified # 🙍🏽‍♀️ woman frowning: medium skin tone
+1F64D 1F3FD 200D 2640 ; non-fully-qualified # 🙍🏽‍♀ woman frowning: medium skin tone
+1F64D 1F3FE 200D 2640 FE0F ; fully-qualified # 🙍🏾‍♀️ woman frowning: medium-dark skin tone
+1F64D 1F3FE 200D 2640 ; non-fully-qualified # 🙍🏾‍♀ woman frowning: medium-dark skin tone
+1F64D 1F3FF 200D 2640 FE0F ; fully-qualified # 🙍🏿‍♀️ woman frowning: dark skin tone
+1F64D 1F3FF 200D 2640 ; non-fully-qualified # 🙍🏿‍♀ woman frowning: dark skin tone
+1F64E ; fully-qualified # 🙎 person pouting
+1F64E 1F3FB ; fully-qualified # 🙎🏻 person pouting: light skin tone
+1F64E 1F3FC ; fully-qualified # 🙎🏼 person pouting: medium-light skin tone
+1F64E 1F3FD ; fully-qualified # 🙎🏽 person pouting: medium skin tone
+1F64E 1F3FE ; fully-qualified # 🙎🏾 person pouting: medium-dark skin tone
+1F64E 1F3FF ; fully-qualified # 🙎🏿 person pouting: dark skin tone
+1F64E 200D 2642 FE0F ; fully-qualified # 🙎‍♂️ man pouting
+1F64E 200D 2642 ; non-fully-qualified # 🙎‍♂ man pouting
+1F64E 1F3FB 200D 2642 FE0F ; fully-qualified # 🙎🏻‍♂️ man pouting: light skin tone
+1F64E 1F3FB 200D 2642 ; non-fully-qualified # 🙎🏻‍♂ man pouting: light skin tone
+1F64E 1F3FC 200D 2642 FE0F ; fully-qualified # 🙎🏼‍♂️ man pouting: medium-light skin tone
+1F64E 1F3FC 200D 2642 ; non-fully-qualified # 🙎🏼‍♂ man pouting: medium-light skin tone
+1F64E 1F3FD 200D 2642 FE0F ; fully-qualified # 🙎🏽‍♂️ man pouting: medium skin tone
+1F64E 1F3FD 200D 2642 ; non-fully-qualified # 🙎🏽‍♂ man pouting: medium skin tone
+1F64E 1F3FE 200D 2642 FE0F ; fully-qualified # 🙎🏾‍♂️ man pouting: medium-dark skin tone
+1F64E 1F3FE 200D 2642 ; non-fully-qualified # 🙎🏾‍♂ man pouting: medium-dark skin tone
+1F64E 1F3FF 200D 2642 FE0F ; fully-qualified # 🙎🏿‍♂️ man pouting: dark skin tone
+1F64E 1F3FF 200D 2642 ; non-fully-qualified # 🙎🏿‍♂ man pouting: dark skin tone
+1F64E 200D 2640 FE0F ; fully-qualified # 🙎‍♀️ woman pouting
+1F64E 200D 2640 ; non-fully-qualified # 🙎‍♀ woman pouting
+1F64E 1F3FB 200D 2640 FE0F ; fully-qualified # 🙎🏻‍♀️ woman pouting: light skin tone
+1F64E 1F3FB 200D 2640 ; non-fully-qualified # 🙎🏻‍♀ woman pouting: light skin tone
+1F64E 1F3FC 200D 2640 FE0F ; fully-qualified # 🙎🏼‍♀️ woman pouting: medium-light skin tone
+1F64E 1F3FC 200D 2640 ; non-fully-qualified # 🙎🏼‍♀ woman pouting: medium-light skin tone
+1F64E 1F3FD 200D 2640 FE0F ; fully-qualified # 🙎🏽‍♀️ woman pouting: medium skin tone
+1F64E 1F3FD 200D 2640 ; non-fully-qualified # 🙎🏽‍♀ woman pouting: medium skin tone
+1F64E 1F3FE 200D 2640 FE0F ; fully-qualified # 🙎🏾‍♀️ woman pouting: medium-dark skin tone
+1F64E 1F3FE 200D 2640 ; non-fully-qualified # 🙎🏾‍♀ woman pouting: medium-dark skin tone
+1F64E 1F3FF 200D 2640 FE0F ; fully-qualified # 🙎🏿‍♀️ woman pouting: dark skin tone
+1F64E 1F3FF 200D 2640 ; non-fully-qualified # 🙎🏿‍♀ woman pouting: dark skin tone
+1F645 ; fully-qualified # 🙅 person gesturing NO
+1F645 1F3FB ; fully-qualified # 🙅🏻 person gesturing NO: light skin tone
+1F645 1F3FC ; fully-qualified # 🙅🏼 person gesturing NO: medium-light skin tone
+1F645 1F3FD ; fully-qualified # 🙅🏽 person gesturing NO: medium skin tone
+1F645 1F3FE ; fully-qualified # 🙅🏾 person gesturing NO: medium-dark skin tone
+1F645 1F3FF ; fully-qualified # 🙅🏿 person gesturing NO: dark skin tone
+1F645 200D 2642 FE0F ; fully-qualified # 🙅‍♂️ man gesturing NO
+1F645 200D 2642 ; non-fully-qualified # 🙅‍♂ man gesturing NO
+1F645 1F3FB 200D 2642 FE0F ; fully-qualified # 🙅🏻‍♂️ man gesturing NO: light skin tone
+1F645 1F3FB 200D 2642 ; non-fully-qualified # 🙅🏻‍♂ man gesturing NO: light skin tone
+1F645 1F3FC 200D 2642 FE0F ; fully-qualified # 🙅🏼‍♂️ man gesturing NO: medium-light skin tone
+1F645 1F3FC 200D 2642 ; non-fully-qualified # 🙅🏼‍♂ man gesturing NO: medium-light skin tone
+1F645 1F3FD 200D 2642 FE0F ; fully-qualified # 🙅🏽‍♂️ man gesturing NO: medium skin tone
+1F645 1F3FD 200D 2642 ; non-fully-qualified # 🙅🏽‍♂ man gesturing NO: medium skin tone
+1F645 1F3FE 200D 2642 FE0F ; fully-qualified # 🙅🏾‍♂️ man gesturing NO: medium-dark skin tone
+1F645 1F3FE 200D 2642 ; non-fully-qualified # 🙅🏾‍♂ man gesturing NO: medium-dark skin tone
+1F645 1F3FF 200D 2642 FE0F ; fully-qualified # 🙅🏿‍♂️ man gesturing NO: dark skin tone
+1F645 1F3FF 200D 2642 ; non-fully-qualified # 🙅🏿‍♂ man gesturing NO: dark skin tone
+1F645 200D 2640 FE0F ; fully-qualified # 🙅‍♀️ woman gesturing NO
+1F645 200D 2640 ; non-fully-qualified # 🙅‍♀ woman gesturing NO
+1F645 1F3FB 200D 2640 FE0F ; fully-qualified # 🙅🏻‍♀️ woman gesturing NO: light skin tone
+1F645 1F3FB 200D 2640 ; non-fully-qualified # 🙅🏻‍♀ woman gesturing NO: light skin tone
+1F645 1F3FC 200D 2640 FE0F ; fully-qualified # 🙅🏼‍♀️ woman gesturing NO: medium-light skin tone
+1F645 1F3FC 200D 2640 ; non-fully-qualified # 🙅🏼‍♀ woman gesturing NO: medium-light skin tone
+1F645 1F3FD 200D 2640 FE0F ; fully-qualified # 🙅🏽‍♀️ woman gesturing NO: medium skin tone
+1F645 1F3FD 200D 2640 ; non-fully-qualified # 🙅🏽‍♀ woman gesturing NO: medium skin tone
+1F645 1F3FE 200D 2640 FE0F ; fully-qualified # 🙅🏾‍♀️ woman gesturing NO: medium-dark skin tone
+1F645 1F3FE 200D 2640 ; non-fully-qualified # 🙅🏾‍♀ woman gesturing NO: medium-dark skin tone
+1F645 1F3FF 200D 2640 FE0F ; fully-qualified # 🙅🏿‍♀️ woman gesturing NO: dark skin tone
+1F645 1F3FF 200D 2640 ; non-fully-qualified # 🙅🏿‍♀ woman gesturing NO: dark skin tone
+1F646 ; fully-qualified # 🙆 person gesturing OK
+1F646 1F3FB ; fully-qualified # 🙆🏻 person gesturing OK: light skin tone
+1F646 1F3FC ; fully-qualified # 🙆🏼 person gesturing OK: medium-light skin tone
+1F646 1F3FD ; fully-qualified # 🙆🏽 person gesturing OK: medium skin tone
+1F646 1F3FE ; fully-qualified # 🙆🏾 person gesturing OK: medium-dark skin tone
+1F646 1F3FF ; fully-qualified # 🙆🏿 person gesturing OK: dark skin tone
+1F646 200D 2642 FE0F ; fully-qualified # 🙆‍♂️ man gesturing OK
+1F646 200D 2642 ; non-fully-qualified # 🙆‍♂ man gesturing OK
+1F646 1F3FB 200D 2642 FE0F ; fully-qualified # 🙆🏻‍♂️ man gesturing OK: light skin tone
+1F646 1F3FB 200D 2642 ; non-fully-qualified # 🙆🏻‍♂ man gesturing OK: light skin tone
+1F646 1F3FC 200D 2642 FE0F ; fully-qualified # 🙆🏼‍♂️ man gesturing OK: medium-light skin tone
+1F646 1F3FC 200D 2642 ; non-fully-qualified # 🙆🏼‍♂ man gesturing OK: medium-light skin tone
+1F646 1F3FD 200D 2642 FE0F ; fully-qualified # 🙆🏽‍♂️ man gesturing OK: medium skin tone
+1F646 1F3FD 200D 2642 ; non-fully-qualified # 🙆🏽‍♂ man gesturing OK: medium skin tone
+1F646 1F3FE 200D 2642 FE0F ; fully-qualified # 🙆🏾‍♂️ man gesturing OK: medium-dark skin tone
+1F646 1F3FE 200D 2642 ; non-fully-qualified # 🙆🏾‍♂ man gesturing OK: medium-dark skin tone
+1F646 1F3FF 200D 2642 FE0F ; fully-qualified # 🙆🏿‍♂️ man gesturing OK: dark skin tone
+1F646 1F3FF 200D 2642 ; non-fully-qualified # 🙆🏿‍♂ man gesturing OK: dark skin tone
+1F646 200D 2640 FE0F ; fully-qualified # 🙆‍♀️ woman gesturing OK
+1F646 200D 2640 ; non-fully-qualified # 🙆‍♀ woman gesturing OK
+1F646 1F3FB 200D 2640 FE0F ; fully-qualified # 🙆🏻‍♀️ woman gesturing OK: light skin tone
+1F646 1F3FB 200D 2640 ; non-fully-qualified # 🙆🏻‍♀ woman gesturing OK: light skin tone
+1F646 1F3FC 200D 2640 FE0F ; fully-qualified # 🙆🏼‍♀️ woman gesturing OK: medium-light skin tone
+1F646 1F3FC 200D 2640 ; non-fully-qualified # 🙆🏼‍♀ woman gesturing OK: medium-light skin tone
+1F646 1F3FD 200D 2640 FE0F ; fully-qualified # 🙆🏽‍♀️ woman gesturing OK: medium skin tone
+1F646 1F3FD 200D 2640 ; non-fully-qualified # 🙆🏽‍♀ woman gesturing OK: medium skin tone
+1F646 1F3FE 200D 2640 FE0F ; fully-qualified # 🙆🏾‍♀️ woman gesturing OK: medium-dark skin tone
+1F646 1F3FE 200D 2640 ; non-fully-qualified # 🙆🏾‍♀ woman gesturing OK: medium-dark skin tone
+1F646 1F3FF 200D 2640 FE0F ; fully-qualified # 🙆🏿‍♀️ woman gesturing OK: dark skin tone
+1F646 1F3FF 200D 2640 ; non-fully-qualified # 🙆🏿‍♀ woman gesturing OK: dark skin tone
+1F481 ; fully-qualified # 💁 person tipping hand
+1F481 1F3FB ; fully-qualified # 💁🏻 person tipping hand: light skin tone
+1F481 1F3FC ; fully-qualified # 💁🏼 person tipping hand: medium-light skin tone
+1F481 1F3FD ; fully-qualified # 💁🏽 person tipping hand: medium skin tone
+1F481 1F3FE ; fully-qualified # 💁🏾 person tipping hand: medium-dark skin tone
+1F481 1F3FF ; fully-qualified # 💁🏿 person tipping hand: dark skin tone
+1F481 200D 2642 FE0F ; fully-qualified # 💁‍♂️ man tipping hand
+1F481 200D 2642 ; non-fully-qualified # 💁‍♂ man tipping hand
+1F481 1F3FB 200D 2642 FE0F ; fully-qualified # 💁🏻‍♂️ man tipping hand: light skin tone
+1F481 1F3FB 200D 2642 ; non-fully-qualified # 💁🏻‍♂ man tipping hand: light skin tone
+1F481 1F3FC 200D 2642 FE0F ; fully-qualified # 💁🏼‍♂️ man tipping hand: medium-light skin tone
+1F481 1F3FC 200D 2642 ; non-fully-qualified # 💁🏼‍♂ man tipping hand: medium-light skin tone
+1F481 1F3FD 200D 2642 FE0F ; fully-qualified # 💁🏽‍♂️ man tipping hand: medium skin tone
+1F481 1F3FD 200D 2642 ; non-fully-qualified # 💁🏽‍♂ man tipping hand: medium skin tone
+1F481 1F3FE 200D 2642 FE0F ; fully-qualified # 💁🏾‍♂️ man tipping hand: medium-dark skin tone
+1F481 1F3FE 200D 2642 ; non-fully-qualified # 💁🏾‍♂ man tipping hand: medium-dark skin tone
+1F481 1F3FF 200D 2642 FE0F ; fully-qualified # 💁🏿‍♂️ man tipping hand: dark skin tone
+1F481 1F3FF 200D 2642 ; non-fully-qualified # 💁🏿‍♂ man tipping hand: dark skin tone
+1F481 200D 2640 FE0F ; fully-qualified # 💁‍♀️ woman tipping hand
+1F481 200D 2640 ; non-fully-qualified # 💁‍♀ woman tipping hand
+1F481 1F3FB 200D 2640 FE0F ; fully-qualified # 💁🏻‍♀️ woman tipping hand: light skin tone
+1F481 1F3FB 200D 2640 ; non-fully-qualified # 💁🏻‍♀ woman tipping hand: light skin tone
+1F481 1F3FC 200D 2640 FE0F ; fully-qualified # 💁🏼‍♀️ woman tipping hand: medium-light skin tone
+1F481 1F3FC 200D 2640 ; non-fully-qualified # 💁🏼‍♀ woman tipping hand: medium-light skin tone
+1F481 1F3FD 200D 2640 FE0F ; fully-qualified # 💁🏽‍♀️ woman tipping hand: medium skin tone
+1F481 1F3FD 200D 2640 ; non-fully-qualified # 💁🏽‍♀ woman tipping hand: medium skin tone
+1F481 1F3FE 200D 2640 FE0F ; fully-qualified # 💁🏾‍♀️ woman tipping hand: medium-dark skin tone
+1F481 1F3FE 200D 2640 ; non-fully-qualified # 💁🏾‍♀ woman tipping hand: medium-dark skin tone
+1F481 1F3FF 200D 2640 FE0F ; fully-qualified # 💁🏿‍♀️ woman tipping hand: dark skin tone
+1F481 1F3FF 200D 2640 ; non-fully-qualified # 💁🏿‍♀ woman tipping hand: dark skin tone
+1F64B ; fully-qualified # 🙋 person raising hand
+1F64B 1F3FB ; fully-qualified # 🙋🏻 person raising hand: light skin tone
+1F64B 1F3FC ; fully-qualified # 🙋🏼 person raising hand: medium-light skin tone
+1F64B 1F3FD ; fully-qualified # 🙋🏽 person raising hand: medium skin tone
+1F64B 1F3FE ; fully-qualified # 🙋🏾 person raising hand: medium-dark skin tone
+1F64B 1F3FF ; fully-qualified # 🙋🏿 person raising hand: dark skin tone
+1F64B 200D 2642 FE0F ; fully-qualified # 🙋‍♂️ man raising hand
+1F64B 200D 2642 ; non-fully-qualified # 🙋‍♂ man raising hand
+1F64B 1F3FB 200D 2642 FE0F ; fully-qualified # 🙋🏻‍♂️ man raising hand: light skin tone
+1F64B 1F3FB 200D 2642 ; non-fully-qualified # 🙋🏻‍♂ man raising hand: light skin tone
+1F64B 1F3FC 200D 2642 FE0F ; fully-qualified # 🙋🏼‍♂️ man raising hand: medium-light skin tone
+1F64B 1F3FC 200D 2642 ; non-fully-qualified # 🙋🏼‍♂ man raising hand: medium-light skin tone
+1F64B 1F3FD 200D 2642 FE0F ; fully-qualified # 🙋🏽‍♂️ man raising hand: medium skin tone
+1F64B 1F3FD 200D 2642 ; non-fully-qualified # 🙋🏽‍♂ man raising hand: medium skin tone
+1F64B 1F3FE 200D 2642 FE0F ; fully-qualified # 🙋🏾‍♂️ man raising hand: medium-dark skin tone
+1F64B 1F3FE 200D 2642 ; non-fully-qualified # 🙋🏾‍♂ man raising hand: medium-dark skin tone
+1F64B 1F3FF 200D 2642 FE0F ; fully-qualified # 🙋🏿‍♂️ man raising hand: dark skin tone
+1F64B 1F3FF 200D 2642 ; non-fully-qualified # 🙋🏿‍♂ man raising hand: dark skin tone
+1F64B 200D 2640 FE0F ; fully-qualified # 🙋‍♀️ woman raising hand
+1F64B 200D 2640 ; non-fully-qualified # 🙋‍♀ woman raising hand
+1F64B 1F3FB 200D 2640 FE0F ; fully-qualified # 🙋🏻‍♀️ woman raising hand: light skin tone
+1F64B 1F3FB 200D 2640 ; non-fully-qualified # 🙋🏻‍♀ woman raising hand: light skin tone
+1F64B 1F3FC 200D 2640 FE0F ; fully-qualified # 🙋🏼‍♀️ woman raising hand: medium-light skin tone
+1F64B 1F3FC 200D 2640 ; non-fully-qualified # 🙋🏼‍♀ woman raising hand: medium-light skin tone
+1F64B 1F3FD 200D 2640 FE0F ; fully-qualified # 🙋🏽‍♀️ woman raising hand: medium skin tone
+1F64B 1F3FD 200D 2640 ; non-fully-qualified # 🙋🏽‍♀ woman raising hand: medium skin tone
+1F64B 1F3FE 200D 2640 FE0F ; fully-qualified # 🙋🏾‍♀️ woman raising hand: medium-dark skin tone
+1F64B 1F3FE 200D 2640 ; non-fully-qualified # 🙋🏾‍♀ woman raising hand: medium-dark skin tone
+1F64B 1F3FF 200D 2640 FE0F ; fully-qualified # 🙋🏿‍♀️ woman raising hand: dark skin tone
+1F64B 1F3FF 200D 2640 ; non-fully-qualified # 🙋🏿‍♀ woman raising hand: dark skin tone
+1F647 ; fully-qualified # 🙇 person bowing
+1F647 1F3FB ; fully-qualified # 🙇🏻 person bowing: light skin tone
+1F647 1F3FC ; fully-qualified # 🙇🏼 person bowing: medium-light skin tone
+1F647 1F3FD ; fully-qualified # 🙇🏽 person bowing: medium skin tone
+1F647 1F3FE ; fully-qualified # 🙇🏾 person bowing: medium-dark skin tone
+1F647 1F3FF ; fully-qualified # 🙇🏿 person bowing: dark skin tone
+1F647 200D 2642 FE0F ; fully-qualified # 🙇‍♂️ man bowing
+1F647 200D 2642 ; non-fully-qualified # 🙇‍♂ man bowing
+1F647 1F3FB 200D 2642 FE0F ; fully-qualified # 🙇🏻‍♂️ man bowing: light skin tone
+1F647 1F3FB 200D 2642 ; non-fully-qualified # 🙇🏻‍♂ man bowing: light skin tone
+1F647 1F3FC 200D 2642 FE0F ; fully-qualified # 🙇🏼‍♂️ man bowing: medium-light skin tone
+1F647 1F3FC 200D 2642 ; non-fully-qualified # 🙇🏼‍♂ man bowing: medium-light skin tone
+1F647 1F3FD 200D 2642 FE0F ; fully-qualified # 🙇🏽‍♂️ man bowing: medium skin tone
+1F647 1F3FD 200D 2642 ; non-fully-qualified # 🙇🏽‍♂ man bowing: medium skin tone
+1F647 1F3FE 200D 2642 FE0F ; fully-qualified # 🙇🏾‍♂️ man bowing: medium-dark skin tone
+1F647 1F3FE 200D 2642 ; non-fully-qualified # 🙇🏾‍♂ man bowing: medium-dark skin tone
+1F647 1F3FF 200D 2642 FE0F ; fully-qualified # 🙇🏿‍♂️ man bowing: dark skin tone
+1F647 1F3FF 200D 2642 ; non-fully-qualified # 🙇🏿‍♂ man bowing: dark skin tone
+1F647 200D 2640 FE0F ; fully-qualified # 🙇‍♀️ woman bowing
+1F647 200D 2640 ; non-fully-qualified # 🙇‍♀ woman bowing
+1F647 1F3FB 200D 2640 FE0F ; fully-qualified # 🙇🏻‍♀️ woman bowing: light skin tone
+1F647 1F3FB 200D 2640 ; non-fully-qualified # 🙇🏻‍♀ woman bowing: light skin tone
+1F647 1F3FC 200D 2640 FE0F ; fully-qualified # 🙇🏼‍♀️ woman bowing: medium-light skin tone
+1F647 1F3FC 200D 2640 ; non-fully-qualified # 🙇🏼‍♀ woman bowing: medium-light skin tone
+1F647 1F3FD 200D 2640 FE0F ; fully-qualified # 🙇🏽‍♀️ woman bowing: medium skin tone
+1F647 1F3FD 200D 2640 ; non-fully-qualified # 🙇🏽‍♀ woman bowing: medium skin tone
+1F647 1F3FE 200D 2640 FE0F ; fully-qualified # 🙇🏾‍♀️ woman bowing: medium-dark skin tone
+1F647 1F3FE 200D 2640 ; non-fully-qualified # 🙇🏾‍♀ woman bowing: medium-dark skin tone
+1F647 1F3FF 200D 2640 FE0F ; fully-qualified # 🙇🏿‍♀️ woman bowing: dark skin tone
+1F647 1F3FF 200D 2640 ; non-fully-qualified # 🙇🏿‍♀ woman bowing: dark skin tone
+1F926 ; fully-qualified # 🤦 person facepalming
+1F926 1F3FB ; fully-qualified # 🤦🏻 person facepalming: light skin tone
+1F926 1F3FC ; fully-qualified # 🤦🏼 person facepalming: medium-light skin tone
+1F926 1F3FD ; fully-qualified # 🤦🏽 person facepalming: medium skin tone
+1F926 1F3FE ; fully-qualified # 🤦🏾 person facepalming: medium-dark skin tone
+1F926 1F3FF ; fully-qualified # 🤦🏿 person facepalming: dark skin tone
+1F926 200D 2642 FE0F ; fully-qualified # 🤦‍♂️ man facepalming
+1F926 200D 2642 ; non-fully-qualified # 🤦‍♂ man facepalming
+1F926 1F3FB 200D 2642 FE0F ; fully-qualified # 🤦🏻‍♂️ man facepalming: light skin tone
+1F926 1F3FB 200D 2642 ; non-fully-qualified # 🤦🏻‍♂ man facepalming: light skin tone
+1F926 1F3FC 200D 2642 FE0F ; fully-qualified # 🤦🏼‍♂️ man facepalming: medium-light skin tone
+1F926 1F3FC 200D 2642 ; non-fully-qualified # 🤦🏼‍♂ man facepalming: medium-light skin tone
+1F926 1F3FD 200D 2642 FE0F ; fully-qualified # 🤦🏽‍♂️ man facepalming: medium skin tone
+1F926 1F3FD 200D 2642 ; non-fully-qualified # 🤦🏽‍♂ man facepalming: medium skin tone
+1F926 1F3FE 200D 2642 FE0F ; fully-qualified # 🤦🏾‍♂️ man facepalming: medium-dark skin tone
+1F926 1F3FE 200D 2642 ; non-fully-qualified # 🤦🏾‍♂ man facepalming: medium-dark skin tone
+1F926 1F3FF 200D 2642 FE0F ; fully-qualified # 🤦🏿‍♂️ man facepalming: dark skin tone
+1F926 1F3FF 200D 2642 ; non-fully-qualified # 🤦🏿‍♂ man facepalming: dark skin tone
+1F926 200D 2640 FE0F ; fully-qualified # 🤦‍♀️ woman facepalming
+1F926 200D 2640 ; non-fully-qualified # 🤦‍♀ woman facepalming
+1F926 1F3FB 200D 2640 FE0F ; fully-qualified # 🤦🏻‍♀️ woman facepalming: light skin tone
+1F926 1F3FB 200D 2640 ; non-fully-qualified # 🤦🏻‍♀ woman facepalming: light skin tone
+1F926 1F3FC 200D 2640 FE0F ; fully-qualified # 🤦🏼‍♀️ woman facepalming: medium-light skin tone
+1F926 1F3FC 200D 2640 ; non-fully-qualified # 🤦🏼‍♀ woman facepalming: medium-light skin tone
+1F926 1F3FD 200D 2640 FE0F ; fully-qualified # 🤦🏽‍♀️ woman facepalming: medium skin tone
+1F926 1F3FD 200D 2640 ; non-fully-qualified # 🤦🏽‍♀ woman facepalming: medium skin tone
+1F926 1F3FE 200D 2640 FE0F ; fully-qualified # 🤦🏾‍♀️ woman facepalming: medium-dark skin tone
+1F926 1F3FE 200D 2640 ; non-fully-qualified # 🤦🏾‍♀ woman facepalming: medium-dark skin tone
+1F926 1F3FF 200D 2640 FE0F ; fully-qualified # 🤦🏿‍♀️ woman facepalming: dark skin tone
+1F926 1F3FF 200D 2640 ; non-fully-qualified # 🤦🏿‍♀ woman facepalming: dark skin tone
+1F937 ; fully-qualified # 🤷 person shrugging
+1F937 1F3FB ; fully-qualified # 🤷🏻 person shrugging: light skin tone
+1F937 1F3FC ; fully-qualified # 🤷🏼 person shrugging: medium-light skin tone
+1F937 1F3FD ; fully-qualified # 🤷🏽 person shrugging: medium skin tone
+1F937 1F3FE ; fully-qualified # 🤷🏾 person shrugging: medium-dark skin tone
+1F937 1F3FF ; fully-qualified # 🤷🏿 person shrugging: dark skin tone
+1F937 200D 2642 FE0F ; fully-qualified # 🤷‍♂️ man shrugging
+1F937 200D 2642 ; non-fully-qualified # 🤷‍♂ man shrugging
+1F937 1F3FB 200D 2642 FE0F ; fully-qualified # 🤷🏻‍♂️ man shrugging: light skin tone
+1F937 1F3FB 200D 2642 ; non-fully-qualified # 🤷🏻‍♂ man shrugging: light skin tone
+1F937 1F3FC 200D 2642 FE0F ; fully-qualified # 🤷🏼‍♂️ man shrugging: medium-light skin tone
+1F937 1F3FC 200D 2642 ; non-fully-qualified # 🤷🏼‍♂ man shrugging: medium-light skin tone
+1F937 1F3FD 200D 2642 FE0F ; fully-qualified # 🤷🏽‍♂️ man shrugging: medium skin tone
+1F937 1F3FD 200D 2642 ; non-fully-qualified # 🤷🏽‍♂ man shrugging: medium skin tone
+1F937 1F3FE 200D 2642 FE0F ; fully-qualified # 🤷🏾‍♂️ man shrugging: medium-dark skin tone
+1F937 1F3FE 200D 2642 ; non-fully-qualified # 🤷🏾‍♂ man shrugging: medium-dark skin tone
+1F937 1F3FF 200D 2642 FE0F ; fully-qualified # 🤷🏿‍♂️ man shrugging: dark skin tone
+1F937 1F3FF 200D 2642 ; non-fully-qualified # 🤷🏿‍♂ man shrugging: dark skin tone
+1F937 200D 2640 FE0F ; fully-qualified # 🤷‍♀️ woman shrugging
+1F937 200D 2640 ; non-fully-qualified # 🤷‍♀ woman shrugging
+1F937 1F3FB 200D 2640 FE0F ; fully-qualified # 🤷🏻‍♀️ woman shrugging: light skin tone
+1F937 1F3FB 200D 2640 ; non-fully-qualified # 🤷🏻‍♀ woman shrugging: light skin tone
+1F937 1F3FC 200D 2640 FE0F ; fully-qualified # 🤷🏼‍♀️ woman shrugging: medium-light skin tone
+1F937 1F3FC 200D 2640 ; non-fully-qualified # 🤷🏼‍♀ woman shrugging: medium-light skin tone
+1F937 1F3FD 200D 2640 FE0F ; fully-qualified # 🤷🏽‍♀️ woman shrugging: medium skin tone
+1F937 1F3FD 200D 2640 ; non-fully-qualified # 🤷🏽‍♀ woman shrugging: medium skin tone
+1F937 1F3FE 200D 2640 FE0F ; fully-qualified # 🤷🏾‍♀️ woman shrugging: medium-dark skin tone
+1F937 1F3FE 200D 2640 ; non-fully-qualified # 🤷🏾‍♀ woman shrugging: medium-dark skin tone
+1F937 1F3FF 200D 2640 FE0F ; fully-qualified # 🤷🏿‍♀️ woman shrugging: dark skin tone
+1F937 1F3FF 200D 2640 ; non-fully-qualified # 🤷🏿‍♀ woman shrugging: dark skin tone
+
+# subgroup: person-activity
+1F486 ; fully-qualified # 💆 person getting massage
+1F486 1F3FB ; fully-qualified # 💆🏻 person getting massage: light skin tone
+1F486 1F3FC ; fully-qualified # 💆🏼 person getting massage: medium-light skin tone
+1F486 1F3FD ; fully-qualified # 💆🏽 person getting massage: medium skin tone
+1F486 1F3FE ; fully-qualified # 💆🏾 person getting massage: medium-dark skin tone
+1F486 1F3FF ; fully-qualified # 💆🏿 person getting massage: dark skin tone
+1F486 200D 2642 FE0F ; fully-qualified # 💆‍♂️ man getting massage
+1F486 200D 2642 ; non-fully-qualified # 💆‍♂ man getting massage
+1F486 1F3FB 200D 2642 FE0F ; fully-qualified # 💆🏻‍♂️ man getting massage: light skin tone
+1F486 1F3FB 200D 2642 ; non-fully-qualified # 💆🏻‍♂ man getting massage: light skin tone
+1F486 1F3FC 200D 2642 FE0F ; fully-qualified # 💆🏼‍♂️ man getting massage: medium-light skin tone
+1F486 1F3FC 200D 2642 ; non-fully-qualified # 💆🏼‍♂ man getting massage: medium-light skin tone
+1F486 1F3FD 200D 2642 FE0F ; fully-qualified # 💆🏽‍♂️ man getting massage: medium skin tone
+1F486 1F3FD 200D 2642 ; non-fully-qualified # 💆🏽‍♂ man getting massage: medium skin tone
+1F486 1F3FE 200D 2642 FE0F ; fully-qualified # 💆🏾‍♂️ man getting massage: medium-dark skin tone
+1F486 1F3FE 200D 2642 ; non-fully-qualified # 💆🏾‍♂ man getting massage: medium-dark skin tone
+1F486 1F3FF 200D 2642 FE0F ; fully-qualified # 💆🏿‍♂️ man getting massage: dark skin tone
+1F486 1F3FF 200D 2642 ; non-fully-qualified # 💆🏿‍♂ man getting massage: dark skin tone
+1F486 200D 2640 FE0F ; fully-qualified # 💆‍♀️ woman getting massage
+1F486 200D 2640 ; non-fully-qualified # 💆‍♀ woman getting massage
+1F486 1F3FB 200D 2640 FE0F ; fully-qualified # 💆🏻‍♀️ woman getting massage: light skin tone
+1F486 1F3FB 200D 2640 ; non-fully-qualified # 💆🏻‍♀ woman getting massage: light skin tone
+1F486 1F3FC 200D 2640 FE0F ; fully-qualified # 💆🏼‍♀️ woman getting massage: medium-light skin tone
+1F486 1F3FC 200D 2640 ; non-fully-qualified # 💆🏼‍♀ woman getting massage: medium-light skin tone
+1F486 1F3FD 200D 2640 FE0F ; fully-qualified # 💆🏽‍♀️ woman getting massage: medium skin tone
+1F486 1F3FD 200D 2640 ; non-fully-qualified # 💆🏽‍♀ woman getting massage: medium skin tone
+1F486 1F3FE 200D 2640 FE0F ; fully-qualified # 💆🏾‍♀️ woman getting massage: medium-dark skin tone
+1F486 1F3FE 200D 2640 ; non-fully-qualified # 💆🏾‍♀ woman getting massage: medium-dark skin tone
+1F486 1F3FF 200D 2640 FE0F ; fully-qualified # 💆🏿‍♀️ woman getting massage: dark skin tone
+1F486 1F3FF 200D 2640 ; non-fully-qualified # 💆🏿‍♀ woman getting massage: dark skin tone
+1F487 ; fully-qualified # 💇 person getting haircut
+1F487 1F3FB ; fully-qualified # 💇🏻 person getting haircut: light skin tone
+1F487 1F3FC ; fully-qualified # 💇🏼 person getting haircut: medium-light skin tone
+1F487 1F3FD ; fully-qualified # 💇🏽 person getting haircut: medium skin tone
+1F487 1F3FE ; fully-qualified # 💇🏾 person getting haircut: medium-dark skin tone
+1F487 1F3FF ; fully-qualified # 💇🏿 person getting haircut: dark skin tone
+1F487 200D 2642 FE0F ; fully-qualified # 💇‍♂️ man getting haircut
+1F487 200D 2642 ; non-fully-qualified # 💇‍♂ man getting haircut
+1F487 1F3FB 200D 2642 FE0F ; fully-qualified # 💇🏻‍♂️ man getting haircut: light skin tone
+1F487 1F3FB 200D 2642 ; non-fully-qualified # 💇🏻‍♂ man getting haircut: light skin tone
+1F487 1F3FC 200D 2642 FE0F ; fully-qualified # 💇🏼‍♂️ man getting haircut: medium-light skin tone
+1F487 1F3FC 200D 2642 ; non-fully-qualified # 💇🏼‍♂ man getting haircut: medium-light skin tone
+1F487 1F3FD 200D 2642 FE0F ; fully-qualified # 💇🏽‍♂️ man getting haircut: medium skin tone
+1F487 1F3FD 200D 2642 ; non-fully-qualified # 💇🏽‍♂ man getting haircut: medium skin tone
+1F487 1F3FE 200D 2642 FE0F ; fully-qualified # 💇🏾‍♂️ man getting haircut: medium-dark skin tone
+1F487 1F3FE 200D 2642 ; non-fully-qualified # 💇🏾‍♂ man getting haircut: medium-dark skin tone
+1F487 1F3FF 200D 2642 FE0F ; fully-qualified # 💇🏿‍♂️ man getting haircut: dark skin tone
+1F487 1F3FF 200D 2642 ; non-fully-qualified # 💇🏿‍♂ man getting haircut: dark skin tone
+1F487 200D 2640 FE0F ; fully-qualified # 💇‍♀️ woman getting haircut
+1F487 200D 2640 ; non-fully-qualified # 💇‍♀ woman getting haircut
+1F487 1F3FB 200D 2640 FE0F ; fully-qualified # 💇🏻‍♀️ woman getting haircut: light skin tone
+1F487 1F3FB 200D 2640 ; non-fully-qualified # 💇🏻‍♀ woman getting haircut: light skin tone
+1F487 1F3FC 200D 2640 FE0F ; fully-qualified # 💇🏼‍♀️ woman getting haircut: medium-light skin tone
+1F487 1F3FC 200D 2640 ; non-fully-qualified # 💇🏼‍♀ woman getting haircut: medium-light skin tone
+1F487 1F3FD 200D 2640 FE0F ; fully-qualified # 💇🏽‍♀️ woman getting haircut: medium skin tone
+1F487 1F3FD 200D 2640 ; non-fully-qualified # 💇🏽‍♀ woman getting haircut: medium skin tone
+1F487 1F3FE 200D 2640 FE0F ; fully-qualified # 💇🏾‍♀️ woman getting haircut: medium-dark skin tone
+1F487 1F3FE 200D 2640 ; non-fully-qualified # 💇🏾‍♀ woman getting haircut: medium-dark skin tone
+1F487 1F3FF 200D 2640 FE0F ; fully-qualified # 💇🏿‍♀️ woman getting haircut: dark skin tone
+1F487 1F3FF 200D 2640 ; non-fully-qualified # 💇🏿‍♀ woman getting haircut: dark skin tone
+1F6B6 ; fully-qualified # 🚶 person walking
+1F6B6 1F3FB ; fully-qualified # 🚶🏻 person walking: light skin tone
+1F6B6 1F3FC ; fully-qualified # 🚶🏼 person walking: medium-light skin tone
+1F6B6 1F3FD ; fully-qualified # 🚶🏽 person walking: medium skin tone
+1F6B6 1F3FE ; fully-qualified # 🚶🏾 person walking: medium-dark skin tone
+1F6B6 1F3FF ; fully-qualified # 🚶🏿 person walking: dark skin tone
+1F6B6 200D 2642 FE0F ; fully-qualified # 🚶‍♂️ man walking
+1F6B6 200D 2642 ; non-fully-qualified # 🚶‍♂ man walking
+1F6B6 1F3FB 200D 2642 FE0F ; fully-qualified # 🚶🏻‍♂️ man walking: light skin tone
+1F6B6 1F3FB 200D 2642 ; non-fully-qualified # 🚶🏻‍♂ man walking: light skin tone
+1F6B6 1F3FC 200D 2642 FE0F ; fully-qualified # 🚶🏼‍♂️ man walking: medium-light skin tone
+1F6B6 1F3FC 200D 2642 ; non-fully-qualified # 🚶🏼‍♂ man walking: medium-light skin tone
+1F6B6 1F3FD 200D 2642 FE0F ; fully-qualified # 🚶🏽‍♂️ man walking: medium skin tone
+1F6B6 1F3FD 200D 2642 ; non-fully-qualified # 🚶🏽‍♂ man walking: medium skin tone
+1F6B6 1F3FE 200D 2642 FE0F ; fully-qualified # 🚶🏾‍♂️ man walking: medium-dark skin tone
+1F6B6 1F3FE 200D 2642 ; non-fully-qualified # 🚶🏾‍♂ man walking: medium-dark skin tone
+1F6B6 1F3FF 200D 2642 FE0F ; fully-qualified # 🚶🏿‍♂️ man walking: dark skin tone
+1F6B6 1F3FF 200D 2642 ; non-fully-qualified # 🚶🏿‍♂ man walking: dark skin tone
+1F6B6 200D 2640 FE0F ; fully-qualified # 🚶‍♀️ woman walking
+1F6B6 200D 2640 ; non-fully-qualified # 🚶‍♀ woman walking
+1F6B6 1F3FB 200D 2640 FE0F ; fully-qualified # 🚶🏻‍♀️ woman walking: light skin tone
+1F6B6 1F3FB 200D 2640 ; non-fully-qualified # 🚶🏻‍♀ woman walking: light skin tone
+1F6B6 1F3FC 200D 2640 FE0F ; fully-qualified # 🚶🏼‍♀️ woman walking: medium-light skin tone
+1F6B6 1F3FC 200D 2640 ; non-fully-qualified # 🚶🏼‍♀ woman walking: medium-light skin tone
+1F6B6 1F3FD 200D 2640 FE0F ; fully-qualified # 🚶🏽‍♀️ woman walking: medium skin tone
+1F6B6 1F3FD 200D 2640 ; non-fully-qualified # 🚶🏽‍♀ woman walking: medium skin tone
+1F6B6 1F3FE 200D 2640 FE0F ; fully-qualified # 🚶🏾‍♀️ woman walking: medium-dark skin tone
+1F6B6 1F3FE 200D 2640 ; non-fully-qualified # 🚶🏾‍♀ woman walking: medium-dark skin tone
+1F6B6 1F3FF 200D 2640 FE0F ; fully-qualified # 🚶🏿‍♀️ woman walking: dark skin tone
+1F6B6 1F3FF 200D 2640 ; non-fully-qualified # 🚶🏿‍♀ woman walking: dark skin tone
+1F3C3 ; fully-qualified # 🏃 person running
+1F3C3 1F3FB ; fully-qualified # 🏃🏻 person running: light skin tone
+1F3C3 1F3FC ; fully-qualified # 🏃🏼 person running: medium-light skin tone
+1F3C3 1F3FD ; fully-qualified # 🏃🏽 person running: medium skin tone
+1F3C3 1F3FE ; fully-qualified # 🏃🏾 person running: medium-dark skin tone
+1F3C3 1F3FF ; fully-qualified # 🏃🏿 person running: dark skin tone
+1F3C3 200D 2642 FE0F ; fully-qualified # 🏃‍♂️ man running
+1F3C3 200D 2642 ; non-fully-qualified # 🏃‍♂ man running
+1F3C3 1F3FB 200D 2642 FE0F ; fully-qualified # 🏃🏻‍♂️ man running: light skin tone
+1F3C3 1F3FB 200D 2642 ; non-fully-qualified # 🏃🏻‍♂ man running: light skin tone
+1F3C3 1F3FC 200D 2642 FE0F ; fully-qualified # 🏃🏼‍♂️ man running: medium-light skin tone
+1F3C3 1F3FC 200D 2642 ; non-fully-qualified # 🏃🏼‍♂ man running: medium-light skin tone
+1F3C3 1F3FD 200D 2642 FE0F ; fully-qualified # 🏃🏽‍♂️ man running: medium skin tone
+1F3C3 1F3FD 200D 2642 ; non-fully-qualified # 🏃🏽‍♂ man running: medium skin tone
+1F3C3 1F3FE 200D 2642 FE0F ; fully-qualified # 🏃🏾‍♂️ man running: medium-dark skin tone
+1F3C3 1F3FE 200D 2642 ; non-fully-qualified # 🏃🏾‍♂ man running: medium-dark skin tone
+1F3C3 1F3FF 200D 2642 FE0F ; fully-qualified # 🏃🏿‍♂️ man running: dark skin tone
+1F3C3 1F3FF 200D 2642 ; non-fully-qualified # 🏃🏿‍♂ man running: dark skin tone
+1F3C3 200D 2640 FE0F ; fully-qualified # 🏃‍♀️ woman running
+1F3C3 200D 2640 ; non-fully-qualified # 🏃‍♀ woman running
+1F3C3 1F3FB 200D 2640 FE0F ; fully-qualified # 🏃🏻‍♀️ woman running: light skin tone
+1F3C3 1F3FB 200D 2640 ; non-fully-qualified # 🏃🏻‍♀ woman running: light skin tone
+1F3C3 1F3FC 200D 2640 FE0F ; fully-qualified # 🏃🏼‍♀️ woman running: medium-light skin tone
+1F3C3 1F3FC 200D 2640 ; non-fully-qualified # 🏃🏼‍♀ woman running: medium-light skin tone
+1F3C3 1F3FD 200D 2640 FE0F ; fully-qualified # 🏃🏽‍♀️ woman running: medium skin tone
+1F3C3 1F3FD 200D 2640 ; non-fully-qualified # 🏃🏽‍♀ woman running: medium skin tone
+1F3C3 1F3FE 200D 2640 FE0F ; fully-qualified # 🏃🏾‍♀️ woman running: medium-dark skin tone
+1F3C3 1F3FE 200D 2640 ; non-fully-qualified # 🏃🏾‍♀ woman running: medium-dark skin tone
+1F3C3 1F3FF 200D 2640 FE0F ; fully-qualified # 🏃🏿‍♀️ woman running: dark skin tone
+1F3C3 1F3FF 200D 2640 ; non-fully-qualified # 🏃🏿‍♀ woman running: dark skin tone
+1F483 ; fully-qualified # 💃 woman dancing
+1F483 1F3FB ; fully-qualified # 💃🏻 woman dancing: light skin tone
+1F483 1F3FC ; fully-qualified # 💃🏼 woman dancing: medium-light skin tone
+1F483 1F3FD ; fully-qualified # 💃🏽 woman dancing: medium skin tone
+1F483 1F3FE ; fully-qualified # 💃🏾 woman dancing: medium-dark skin tone
+1F483 1F3FF ; fully-qualified # 💃🏿 woman dancing: dark skin tone
+1F57A ; fully-qualified # 🕺 man dancing
+1F57A 1F3FB ; fully-qualified # 🕺🏻 man dancing: light skin tone
+1F57A 1F3FC ; fully-qualified # 🕺🏼 man dancing: medium-light skin tone
+1F57A 1F3FD ; fully-qualified # 🕺🏽 man dancing: medium skin tone
+1F57A 1F3FE ; fully-qualified # 🕺🏾 man dancing: medium-dark skin tone
+1F57A 1F3FF ; fully-qualified # 🕺🏿 man dancing: dark skin tone
+1F46F ; fully-qualified # 👯 people with bunny ears
+1F46F 200D 2642 FE0F ; fully-qualified # 👯‍♂️ men with bunny ears
+1F46F 200D 2642 ; non-fully-qualified # 👯‍♂ men with bunny ears
+1F46F 200D 2640 FE0F ; fully-qualified # 👯‍♀️ women with bunny ears
+1F46F 200D 2640 ; non-fully-qualified # 👯‍♀ women with bunny ears
+1F9D6 ; fully-qualified # 🧖 person in steamy room
+1F9D6 1F3FB ; fully-qualified # 🧖🏻 person in steamy room: light skin tone
+1F9D6 1F3FC ; fully-qualified # 🧖🏼 person in steamy room: medium-light skin tone
+1F9D6 1F3FD ; fully-qualified # 🧖🏽 person in steamy room: medium skin tone
+1F9D6 1F3FE ; fully-qualified # 🧖🏾 person in steamy room: medium-dark skin tone
+1F9D6 1F3FF ; fully-qualified # 🧖🏿 person in steamy room: dark skin tone
+1F9D6 200D 2640 FE0F ; fully-qualified # 🧖‍♀️ woman in steamy room
+1F9D6 200D 2640 ; non-fully-qualified # 🧖‍♀ woman in steamy room
+1F9D6 1F3FB 200D 2640 FE0F ; fully-qualified # 🧖🏻‍♀️ woman in steamy room: light skin tone
+1F9D6 1F3FB 200D 2640 ; non-fully-qualified # 🧖🏻‍♀ woman in steamy room: light skin tone
+1F9D6 1F3FC 200D 2640 FE0F ; fully-qualified # 🧖🏼‍♀️ woman in steamy room: medium-light skin tone
+1F9D6 1F3FC 200D 2640 ; non-fully-qualified # 🧖🏼‍♀ woman in steamy room: medium-light skin tone
+1F9D6 1F3FD 200D 2640 FE0F ; fully-qualified # 🧖🏽‍♀️ woman in steamy room: medium skin tone
+1F9D6 1F3FD 200D 2640 ; non-fully-qualified # 🧖🏽‍♀ woman in steamy room: medium skin tone
+1F9D6 1F3FE 200D 2640 FE0F ; fully-qualified # 🧖🏾‍♀️ woman in steamy room: medium-dark skin tone
+1F9D6 1F3FE 200D 2640 ; non-fully-qualified # 🧖🏾‍♀ woman in steamy room: medium-dark skin tone
+1F9D6 1F3FF 200D 2640 FE0F ; fully-qualified # 🧖🏿‍♀️ woman in steamy room: dark skin tone
+1F9D6 1F3FF 200D 2640 ; non-fully-qualified # 🧖🏿‍♀ woman in steamy room: dark skin tone
+1F9D6 200D 2642 FE0F ; fully-qualified # 🧖‍♂️ man in steamy room
+1F9D6 200D 2642 ; non-fully-qualified # 🧖‍♂ man in steamy room
+1F9D6 1F3FB 200D 2642 FE0F ; fully-qualified # 🧖🏻‍♂️ man in steamy room: light skin tone
+1F9D6 1F3FB 200D 2642 ; non-fully-qualified # 🧖🏻‍♂ man in steamy room: light skin tone
+1F9D6 1F3FC 200D 2642 FE0F ; fully-qualified # 🧖🏼‍♂️ man in steamy room: medium-light skin tone
+1F9D6 1F3FC 200D 2642 ; non-fully-qualified # 🧖🏼‍♂ man in steamy room: medium-light skin tone
+1F9D6 1F3FD 200D 2642 FE0F ; fully-qualified # 🧖🏽‍♂️ man in steamy room: medium skin tone
+1F9D6 1F3FD 200D 2642 ; non-fully-qualified # 🧖🏽‍♂ man in steamy room: medium skin tone
+1F9D6 1F3FE 200D 2642 FE0F ; fully-qualified # 🧖🏾‍♂️ man in steamy room: medium-dark skin tone
+1F9D6 1F3FE 200D 2642 ; non-fully-qualified # 🧖🏾‍♂ man in steamy room: medium-dark skin tone
+1F9D6 1F3FF 200D 2642 FE0F ; fully-qualified # 🧖🏿‍♂️ man in steamy room: dark skin tone
+1F9D6 1F3FF 200D 2642 ; non-fully-qualified # 🧖🏿‍♂ man in steamy room: dark skin tone
+1F9D7 ; fully-qualified # 🧗 person climbing
+1F9D7 1F3FB ; fully-qualified # 🧗🏻 person climbing: light skin tone
+1F9D7 1F3FC ; fully-qualified # 🧗🏼 person climbing: medium-light skin tone
+1F9D7 1F3FD ; fully-qualified # 🧗🏽 person climbing: medium skin tone
+1F9D7 1F3FE ; fully-qualified # 🧗🏾 person climbing: medium-dark skin tone
+1F9D7 1F3FF ; fully-qualified # 🧗🏿 person climbing: dark skin tone
+1F9D7 200D 2640 FE0F ; fully-qualified # 🧗‍♀️ woman climbing
+1F9D7 200D 2640 ; non-fully-qualified # 🧗‍♀ woman climbing
+1F9D7 1F3FB 200D 2640 FE0F ; fully-qualified # 🧗🏻‍♀️ woman climbing: light skin tone
+1F9D7 1F3FB 200D 2640 ; non-fully-qualified # 🧗🏻‍♀ woman climbing: light skin tone
+1F9D7 1F3FC 200D 2640 FE0F ; fully-qualified # 🧗🏼‍♀️ woman climbing: medium-light skin tone
+1F9D7 1F3FC 200D 2640 ; non-fully-qualified # 🧗🏼‍♀ woman climbing: medium-light skin tone
+1F9D7 1F3FD 200D 2640 FE0F ; fully-qualified # 🧗🏽‍♀️ woman climbing: medium skin tone
+1F9D7 1F3FD 200D 2640 ; non-fully-qualified # 🧗🏽‍♀ woman climbing: medium skin tone
+1F9D7 1F3FE 200D 2640 FE0F ; fully-qualified # 🧗🏾‍♀️ woman climbing: medium-dark skin tone
+1F9D7 1F3FE 200D 2640 ; non-fully-qualified # 🧗🏾‍♀ woman climbing: medium-dark skin tone
+1F9D7 1F3FF 200D 2640 FE0F ; fully-qualified # 🧗🏿‍♀️ woman climbing: dark skin tone
+1F9D7 1F3FF 200D 2640 ; non-fully-qualified # 🧗🏿‍♀ woman climbing: dark skin tone
+1F9D7 200D 2642 FE0F ; fully-qualified # 🧗‍♂️ man climbing
+1F9D7 200D 2642 ; non-fully-qualified # 🧗‍♂ man climbing
+1F9D7 1F3FB 200D 2642 FE0F ; fully-qualified # 🧗🏻‍♂️ man climbing: light skin tone
+1F9D7 1F3FB 200D 2642 ; non-fully-qualified # 🧗🏻‍♂ man climbing: light skin tone
+1F9D7 1F3FC 200D 2642 FE0F ; fully-qualified # 🧗🏼‍♂️ man climbing: medium-light skin tone
+1F9D7 1F3FC 200D 2642 ; non-fully-qualified # 🧗🏼‍♂ man climbing: medium-light skin tone
+1F9D7 1F3FD 200D 2642 FE0F ; fully-qualified # 🧗🏽‍♂️ man climbing: medium skin tone
+1F9D7 1F3FD 200D 2642 ; non-fully-qualified # 🧗🏽‍♂ man climbing: medium skin tone
+1F9D7 1F3FE 200D 2642 FE0F ; fully-qualified # 🧗🏾‍♂️ man climbing: medium-dark skin tone
+1F9D7 1F3FE 200D 2642 ; non-fully-qualified # 🧗🏾‍♂ man climbing: medium-dark skin tone
+1F9D7 1F3FF 200D 2642 FE0F ; fully-qualified # 🧗🏿‍♂️ man climbing: dark skin tone
+1F9D7 1F3FF 200D 2642 ; non-fully-qualified # 🧗🏿‍♂ man climbing: dark skin tone
+1F9D8 ; fully-qualified # 🧘 person in lotus position
+1F9D8 1F3FB ; fully-qualified # 🧘🏻 person in lotus position: light skin tone
+1F9D8 1F3FC ; fully-qualified # 🧘🏼 person in lotus position: medium-light skin tone
+1F9D8 1F3FD ; fully-qualified # 🧘🏽 person in lotus position: medium skin tone
+1F9D8 1F3FE ; fully-qualified # 🧘🏾 person in lotus position: medium-dark skin tone
+1F9D8 1F3FF ; fully-qualified # 🧘🏿 person in lotus position: dark skin tone
+1F9D8 200D 2640 FE0F ; fully-qualified # 🧘‍♀️ woman in lotus position
+1F9D8 200D 2640 ; non-fully-qualified # 🧘‍♀ woman in lotus position
+1F9D8 1F3FB 200D 2640 FE0F ; fully-qualified # 🧘🏻‍♀️ woman in lotus position: light skin tone
+1F9D8 1F3FB 200D 2640 ; non-fully-qualified # 🧘🏻‍♀ woman in lotus position: light skin tone
+1F9D8 1F3FC 200D 2640 FE0F ; fully-qualified # 🧘🏼‍♀️ woman in lotus position: medium-light skin tone
+1F9D8 1F3FC 200D 2640 ; non-fully-qualified # 🧘🏼‍♀ woman in lotus position: medium-light skin tone
+1F9D8 1F3FD 200D 2640 FE0F ; fully-qualified # 🧘🏽‍♀️ woman in lotus position: medium skin tone
+1F9D8 1F3FD 200D 2640 ; non-fully-qualified # 🧘🏽‍♀ woman in lotus position: medium skin tone
+1F9D8 1F3FE 200D 2640 FE0F ; fully-qualified # 🧘🏾‍♀️ woman in lotus position: medium-dark skin tone
+1F9D8 1F3FE 200D 2640 ; non-fully-qualified # 🧘🏾‍♀ woman in lotus position: medium-dark skin tone
+1F9D8 1F3FF 200D 2640 FE0F ; fully-qualified # 🧘🏿‍♀️ woman in lotus position: dark skin tone
+1F9D8 1F3FF 200D 2640 ; non-fully-qualified # 🧘🏿‍♀ woman in lotus position: dark skin tone
+1F9D8 200D 2642 FE0F ; fully-qualified # 🧘‍♂️ man in lotus position
+1F9D8 200D 2642 ; non-fully-qualified # 🧘‍♂ man in lotus position
+1F9D8 1F3FB 200D 2642 FE0F ; fully-qualified # 🧘🏻‍♂️ man in lotus position: light skin tone
+1F9D8 1F3FB 200D 2642 ; non-fully-qualified # 🧘🏻‍♂ man in lotus position: light skin tone
+1F9D8 1F3FC 200D 2642 FE0F ; fully-qualified # 🧘🏼‍♂️ man in lotus position: medium-light skin tone
+1F9D8 1F3FC 200D 2642 ; non-fully-qualified # 🧘🏼‍♂ man in lotus position: medium-light skin tone
+1F9D8 1F3FD 200D 2642 FE0F ; fully-qualified # 🧘🏽‍♂️ man in lotus position: medium skin tone
+1F9D8 1F3FD 200D 2642 ; non-fully-qualified # 🧘🏽‍♂ man in lotus position: medium skin tone
+1F9D8 1F3FE 200D 2642 FE0F ; fully-qualified # 🧘🏾‍♂️ man in lotus position: medium-dark skin tone
+1F9D8 1F3FE 200D 2642 ; non-fully-qualified # 🧘🏾‍♂ man in lotus position: medium-dark skin tone
+1F9D8 1F3FF 200D 2642 FE0F ; fully-qualified # 🧘🏿‍♂️ man in lotus position: dark skin tone
+1F9D8 1F3FF 200D 2642 ; non-fully-qualified # 🧘🏿‍♂ man in lotus position: dark skin tone
+1F6C0 ; fully-qualified # 🛀 person taking bath
+1F6C0 1F3FB ; fully-qualified # 🛀🏻 person taking bath: light skin tone
+1F6C0 1F3FC ; fully-qualified # 🛀🏼 person taking bath: medium-light skin tone
+1F6C0 1F3FD ; fully-qualified # 🛀🏽 person taking bath: medium skin tone
+1F6C0 1F3FE ; fully-qualified # 🛀🏾 person taking bath: medium-dark skin tone
+1F6C0 1F3FF ; fully-qualified # 🛀🏿 person taking bath: dark skin tone
+1F6CC ; fully-qualified # 🛌 person in bed
+1F6CC 1F3FB ; fully-qualified # 🛌🏻 person in bed: light skin tone
+1F6CC 1F3FC ; fully-qualified # 🛌🏼 person in bed: medium-light skin tone
+1F6CC 1F3FD ; fully-qualified # 🛌🏽 person in bed: medium skin tone
+1F6CC 1F3FE ; fully-qualified # 🛌🏾 person in bed: medium-dark skin tone
+1F6CC 1F3FF ; fully-qualified # 🛌🏿 person in bed: dark skin tone
+1F574 FE0F ; fully-qualified # 🕴️ man in suit levitating
+1F574 ; non-fully-qualified # 🕴 man in suit levitating
+1F574 1F3FB ; fully-qualified # 🕴🏻 man in suit levitating: light skin tone
+1F574 1F3FC ; fully-qualified # 🕴🏼 man in suit levitating: medium-light skin tone
+1F574 1F3FD ; fully-qualified # 🕴🏽 man in suit levitating: medium skin tone
+1F574 1F3FE ; fully-qualified # 🕴🏾 man in suit levitating: medium-dark skin tone
+1F574 1F3FF ; fully-qualified # 🕴🏿 man in suit levitating: dark skin tone
+1F5E3 FE0F ; fully-qualified # 🗣️ speaking head
+1F5E3 ; non-fully-qualified # 🗣 speaking head
+1F464 ; fully-qualified # 👤 bust in silhouette
+1F465 ; fully-qualified # 👥 busts in silhouette
+
+# subgroup: person-sport
+1F93A ; fully-qualified # 🤺 person fencing
+1F3C7 ; fully-qualified # 🏇 horse racing
+1F3C7 1F3FB ; fully-qualified # 🏇🏻 horse racing: light skin tone
+1F3C7 1F3FC ; fully-qualified # 🏇🏼 horse racing: medium-light skin tone
+1F3C7 1F3FD ; fully-qualified # 🏇🏽 horse racing: medium skin tone
+1F3C7 1F3FE ; fully-qualified # 🏇🏾 horse racing: medium-dark skin tone
+1F3C7 1F3FF ; fully-qualified # 🏇🏿 horse racing: dark skin tone
+26F7 FE0F ; fully-qualified # ⛷️ skier
+26F7 ; non-fully-qualified # ⛷ skier
+1F3C2 ; fully-qualified # 🏂 snowboarder
+1F3C2 1F3FB ; fully-qualified # 🏂🏻 snowboarder: light skin tone
+1F3C2 1F3FC ; fully-qualified # 🏂🏼 snowboarder: medium-light skin tone
+1F3C2 1F3FD ; fully-qualified # 🏂🏽 snowboarder: medium skin tone
+1F3C2 1F3FE ; fully-qualified # 🏂🏾 snowboarder: medium-dark skin tone
+1F3C2 1F3FF ; fully-qualified # 🏂🏿 snowboarder: dark skin tone
+1F3CC FE0F ; fully-qualified # 🏌️ person golfing
+1F3CC ; non-fully-qualified # 🏌 person golfing
+1F3CC 1F3FB ; fully-qualified # 🏌🏻 person golfing: light skin tone
+1F3CC 1F3FC ; fully-qualified # 🏌🏼 person golfing: medium-light skin tone
+1F3CC 1F3FD ; fully-qualified # 🏌🏽 person golfing: medium skin tone
+1F3CC 1F3FE ; fully-qualified # 🏌🏾 person golfing: medium-dark skin tone
+1F3CC 1F3FF ; fully-qualified # 🏌🏿 person golfing: dark skin tone
+1F3CC FE0F 200D 2642 FE0F ; fully-qualified # 🏌️‍♂️ man golfing
+1F3CC 200D 2642 FE0F ; non-fully-qualified # 🏌‍♂️ man golfing
+1F3CC FE0F 200D 2642 ; non-fully-qualified # 🏌️‍♂ man golfing
+1F3CC 200D 2642 ; non-fully-qualified # 🏌‍♂ man golfing
+1F3CC 1F3FB 200D 2642 FE0F ; fully-qualified # 🏌🏻‍♂️ man golfing: light skin tone
+1F3CC 1F3FB 200D 2642 ; non-fully-qualified # 🏌🏻‍♂ man golfing: light skin tone
+1F3CC 1F3FC 200D 2642 FE0F ; fully-qualified # 🏌🏼‍♂️ man golfing: medium-light skin tone
+1F3CC 1F3FC 200D 2642 ; non-fully-qualified # 🏌🏼‍♂ man golfing: medium-light skin tone
+1F3CC 1F3FD 200D 2642 FE0F ; fully-qualified # 🏌🏽‍♂️ man golfing: medium skin tone
+1F3CC 1F3FD 200D 2642 ; non-fully-qualified # 🏌🏽‍♂ man golfing: medium skin tone
+1F3CC 1F3FE 200D 2642 FE0F ; fully-qualified # 🏌🏾‍♂️ man golfing: medium-dark skin tone
+1F3CC 1F3FE 200D 2642 ; non-fully-qualified # 🏌🏾‍♂ man golfing: medium-dark skin tone
+1F3CC 1F3FF 200D 2642 FE0F ; fully-qualified # 🏌🏿‍♂️ man golfing: dark skin tone
+1F3CC 1F3FF 200D 2642 ; non-fully-qualified # 🏌🏿‍♂ man golfing: dark skin tone
+1F3CC FE0F 200D 2640 FE0F ; fully-qualified # 🏌️‍♀️ woman golfing
+1F3CC 200D 2640 FE0F ; non-fully-qualified # 🏌‍♀️ woman golfing
+1F3CC FE0F 200D 2640 ; non-fully-qualified # 🏌️‍♀ woman golfing
+1F3CC 200D 2640 ; non-fully-qualified # 🏌‍♀ woman golfing
+1F3CC 1F3FB 200D 2640 FE0F ; fully-qualified # 🏌🏻‍♀️ woman golfing: light skin tone
+1F3CC 1F3FB 200D 2640 ; non-fully-qualified # 🏌🏻‍♀ woman golfing: light skin tone
+1F3CC 1F3FC 200D 2640 FE0F ; fully-qualified # 🏌🏼‍♀️ woman golfing: medium-light skin tone
+1F3CC 1F3FC 200D 2640 ; non-fully-qualified # 🏌🏼‍♀ woman golfing: medium-light skin tone
+1F3CC 1F3FD 200D 2640 FE0F ; fully-qualified # 🏌🏽‍♀️ woman golfing: medium skin tone
+1F3CC 1F3FD 200D 2640 ; non-fully-qualified # 🏌🏽‍♀ woman golfing: medium skin tone
+1F3CC 1F3FE 200D 2640 FE0F ; fully-qualified # 🏌🏾‍♀️ woman golfing: medium-dark skin tone
+1F3CC 1F3FE 200D 2640 ; non-fully-qualified # 🏌🏾‍♀ woman golfing: medium-dark skin tone
+1F3CC 1F3FF 200D 2640 FE0F ; fully-qualified # 🏌🏿‍♀️ woman golfing: dark skin tone
+1F3CC 1F3FF 200D 2640 ; non-fully-qualified # 🏌🏿‍♀ woman golfing: dark skin tone
+1F3C4 ; fully-qualified # 🏄 person surfing
+1F3C4 1F3FB ; fully-qualified # 🏄🏻 person surfing: light skin tone
+1F3C4 1F3FC ; fully-qualified # 🏄🏼 person surfing: medium-light skin tone
+1F3C4 1F3FD ; fully-qualified # 🏄🏽 person surfing: medium skin tone
+1F3C4 1F3FE ; fully-qualified # 🏄🏾 person surfing: medium-dark skin tone
+1F3C4 1F3FF ; fully-qualified # 🏄🏿 person surfing: dark skin tone
+1F3C4 200D 2642 FE0F ; fully-qualified # 🏄‍♂️ man surfing
+1F3C4 200D 2642 ; non-fully-qualified # 🏄‍♂ man surfing
+1F3C4 1F3FB 200D 2642 FE0F ; fully-qualified # 🏄🏻‍♂️ man surfing: light skin tone
+1F3C4 1F3FB 200D 2642 ; non-fully-qualified # 🏄🏻‍♂ man surfing: light skin tone
+1F3C4 1F3FC 200D 2642 FE0F ; fully-qualified # 🏄🏼‍♂️ man surfing: medium-light skin tone
+1F3C4 1F3FC 200D 2642 ; non-fully-qualified # 🏄🏼‍♂ man surfing: medium-light skin tone
+1F3C4 1F3FD 200D 2642 FE0F ; fully-qualified # 🏄🏽‍♂️ man surfing: medium skin tone
+1F3C4 1F3FD 200D 2642 ; non-fully-qualified # 🏄🏽‍♂ man surfing: medium skin tone
+1F3C4 1F3FE 200D 2642 FE0F ; fully-qualified # 🏄🏾‍♂️ man surfing: medium-dark skin tone
+1F3C4 1F3FE 200D 2642 ; non-fully-qualified # 🏄🏾‍♂ man surfing: medium-dark skin tone
+1F3C4 1F3FF 200D 2642 FE0F ; fully-qualified # 🏄🏿‍♂️ man surfing: dark skin tone
+1F3C4 1F3FF 200D 2642 ; non-fully-qualified # 🏄🏿‍♂ man surfing: dark skin tone
+1F3C4 200D 2640 FE0F ; fully-qualified # 🏄‍♀️ woman surfing
+1F3C4 200D 2640 ; non-fully-qualified # 🏄‍♀ woman surfing
+1F3C4 1F3FB 200D 2640 FE0F ; fully-qualified # 🏄🏻‍♀️ woman surfing: light skin tone
+1F3C4 1F3FB 200D 2640 ; non-fully-qualified # 🏄🏻‍♀ woman surfing: light skin tone
+1F3C4 1F3FC 200D 2640 FE0F ; fully-qualified # 🏄🏼‍♀️ woman surfing: medium-light skin tone
+1F3C4 1F3FC 200D 2640 ; non-fully-qualified # 🏄🏼‍♀ woman surfing: medium-light skin tone
+1F3C4 1F3FD 200D 2640 FE0F ; fully-qualified # 🏄🏽‍♀️ woman surfing: medium skin tone
+1F3C4 1F3FD 200D 2640 ; non-fully-qualified # 🏄🏽‍♀ woman surfing: medium skin tone
+1F3C4 1F3FE 200D 2640 FE0F ; fully-qualified # 🏄🏾‍♀️ woman surfing: medium-dark skin tone
+1F3C4 1F3FE 200D 2640 ; non-fully-qualified # 🏄🏾‍♀ woman surfing: medium-dark skin tone
+1F3C4 1F3FF 200D 2640 FE0F ; fully-qualified # 🏄🏿‍♀️ woman surfing: dark skin tone
+1F3C4 1F3FF 200D 2640 ; non-fully-qualified # 🏄🏿‍♀ woman surfing: dark skin tone
+1F6A3 ; fully-qualified # 🚣 person rowing boat
+1F6A3 1F3FB ; fully-qualified # 🚣🏻 person rowing boat: light skin tone
+1F6A3 1F3FC ; fully-qualified # 🚣🏼 person rowing boat: medium-light skin tone
+1F6A3 1F3FD ; fully-qualified # 🚣🏽 person rowing boat: medium skin tone
+1F6A3 1F3FE ; fully-qualified # 🚣🏾 person rowing boat: medium-dark skin tone
+1F6A3 1F3FF ; fully-qualified # 🚣🏿 person rowing boat: dark skin tone
+1F6A3 200D 2642 FE0F ; fully-qualified # 🚣‍♂️ man rowing boat
+1F6A3 200D 2642 ; non-fully-qualified # 🚣‍♂ man rowing boat
+1F6A3 1F3FB 200D 2642 FE0F ; fully-qualified # 🚣🏻‍♂️ man rowing boat: light skin tone
+1F6A3 1F3FB 200D 2642 ; non-fully-qualified # 🚣🏻‍♂ man rowing boat: light skin tone
+1F6A3 1F3FC 200D 2642 FE0F ; fully-qualified # 🚣🏼‍♂️ man rowing boat: medium-light skin tone
+1F6A3 1F3FC 200D 2642 ; non-fully-qualified # 🚣🏼‍♂ man rowing boat: medium-light skin tone
+1F6A3 1F3FD 200D 2642 FE0F ; fully-qualified # 🚣🏽‍♂️ man rowing boat: medium skin tone
+1F6A3 1F3FD 200D 2642 ; non-fully-qualified # 🚣🏽‍♂ man rowing boat: medium skin tone
+1F6A3 1F3FE 200D 2642 FE0F ; fully-qualified # 🚣🏾‍♂️ man rowing boat: medium-dark skin tone
+1F6A3 1F3FE 200D 2642 ; non-fully-qualified # 🚣🏾‍♂ man rowing boat: medium-dark skin tone
+1F6A3 1F3FF 200D 2642 FE0F ; fully-qualified # 🚣🏿‍♂️ man rowing boat: dark skin tone
+1F6A3 1F3FF 200D 2642 ; non-fully-qualified # 🚣🏿‍♂ man rowing boat: dark skin tone
+1F6A3 200D 2640 FE0F ; fully-qualified # 🚣‍♀️ woman rowing boat
+1F6A3 200D 2640 ; non-fully-qualified # 🚣‍♀ woman rowing boat
+1F6A3 1F3FB 200D 2640 FE0F ; fully-qualified # 🚣🏻‍♀️ woman rowing boat: light skin tone
+1F6A3 1F3FB 200D 2640 ; non-fully-qualified # 🚣🏻‍♀ woman rowing boat: light skin tone
+1F6A3 1F3FC 200D 2640 FE0F ; fully-qualified # 🚣🏼‍♀️ woman rowing boat: medium-light skin tone
+1F6A3 1F3FC 200D 2640 ; non-fully-qualified # 🚣🏼‍♀ woman rowing boat: medium-light skin tone
+1F6A3 1F3FD 200D 2640 FE0F ; fully-qualified # 🚣🏽‍♀️ woman rowing boat: medium skin tone
+1F6A3 1F3FD 200D 2640 ; non-fully-qualified # 🚣🏽‍♀ woman rowing boat: medium skin tone
+1F6A3 1F3FE 200D 2640 FE0F ; fully-qualified # 🚣🏾‍♀️ woman rowing boat: medium-dark skin tone
+1F6A3 1F3FE 200D 2640 ; non-fully-qualified # 🚣🏾‍♀ woman rowing boat: medium-dark skin tone
+1F6A3 1F3FF 200D 2640 FE0F ; fully-qualified # 🚣🏿‍♀️ woman rowing boat: dark skin tone
+1F6A3 1F3FF 200D 2640 ; non-fully-qualified # 🚣🏿‍♀ woman rowing boat: dark skin tone
+1F3CA ; fully-qualified # 🏊 person swimming
+1F3CA 1F3FB ; fully-qualified # 🏊🏻 person swimming: light skin tone
+1F3CA 1F3FC ; fully-qualified # 🏊🏼 person swimming: medium-light skin tone
+1F3CA 1F3FD ; fully-qualified # 🏊🏽 person swimming: medium skin tone
+1F3CA 1F3FE ; fully-qualified # 🏊🏾 person swimming: medium-dark skin tone
+1F3CA 1F3FF ; fully-qualified # 🏊🏿 person swimming: dark skin tone
+1F3CA 200D 2642 FE0F ; fully-qualified # 🏊‍♂️ man swimming
+1F3CA 200D 2642 ; non-fully-qualified # 🏊‍♂ man swimming
+1F3CA 1F3FB 200D 2642 FE0F ; fully-qualified # 🏊🏻‍♂️ man swimming: light skin tone
+1F3CA 1F3FB 200D 2642 ; non-fully-qualified # 🏊🏻‍♂ man swimming: light skin tone
+1F3CA 1F3FC 200D 2642 FE0F ; fully-qualified # 🏊🏼‍♂️ man swimming: medium-light skin tone
+1F3CA 1F3FC 200D 2642 ; non-fully-qualified # 🏊🏼‍♂ man swimming: medium-light skin tone
+1F3CA 1F3FD 200D 2642 FE0F ; fully-qualified # 🏊🏽‍♂️ man swimming: medium skin tone
+1F3CA 1F3FD 200D 2642 ; non-fully-qualified # 🏊🏽‍♂ man swimming: medium skin tone
+1F3CA 1F3FE 200D 2642 FE0F ; fully-qualified # 🏊🏾‍♂️ man swimming: medium-dark skin tone
+1F3CA 1F3FE 200D 2642 ; non-fully-qualified # 🏊🏾‍♂ man swimming: medium-dark skin tone
+1F3CA 1F3FF 200D 2642 FE0F ; fully-qualified # 🏊🏿‍♂️ man swimming: dark skin tone
+1F3CA 1F3FF 200D 2642 ; non-fully-qualified # 🏊🏿‍♂ man swimming: dark skin tone
+1F3CA 200D 2640 FE0F ; fully-qualified # 🏊‍♀️ woman swimming
+1F3CA 200D 2640 ; non-fully-qualified # 🏊‍♀ woman swimming
+1F3CA 1F3FB 200D 2640 FE0F ; fully-qualified # 🏊🏻‍♀️ woman swimming: light skin tone
+1F3CA 1F3FB 200D 2640 ; non-fully-qualified # 🏊🏻‍♀ woman swimming: light skin tone
+1F3CA 1F3FC 200D 2640 FE0F ; fully-qualified # 🏊🏼‍♀️ woman swimming: medium-light skin tone
+1F3CA 1F3FC 200D 2640 ; non-fully-qualified # 🏊🏼‍♀ woman swimming: medium-light skin tone
+1F3CA 1F3FD 200D 2640 FE0F ; fully-qualified # 🏊🏽‍♀️ woman swimming: medium skin tone
+1F3CA 1F3FD 200D 2640 ; non-fully-qualified # 🏊🏽‍♀ woman swimming: medium skin tone
+1F3CA 1F3FE 200D 2640 FE0F ; fully-qualified # 🏊🏾‍♀️ woman swimming: medium-dark skin tone
+1F3CA 1F3FE 200D 2640 ; non-fully-qualified # 🏊🏾‍♀ woman swimming: medium-dark skin tone
+1F3CA 1F3FF 200D 2640 FE0F ; fully-qualified # 🏊🏿‍♀️ woman swimming: dark skin tone
+1F3CA 1F3FF 200D 2640 ; non-fully-qualified # 🏊🏿‍♀ woman swimming: dark skin tone
+26F9 FE0F ; fully-qualified # ⛹️ person bouncing ball
+26F9 ; non-fully-qualified # ⛹ person bouncing ball
+26F9 1F3FB ; fully-qualified # ⛹🏻 person bouncing ball: light skin tone
+26F9 1F3FC ; fully-qualified # ⛹🏼 person bouncing ball: medium-light skin tone
+26F9 1F3FD ; fully-qualified # ⛹🏽 person bouncing ball: medium skin tone
+26F9 1F3FE ; fully-qualified # ⛹🏾 person bouncing ball: medium-dark skin tone
+26F9 1F3FF ; fully-qualified # ⛹🏿 person bouncing ball: dark skin tone
+26F9 FE0F 200D 2642 FE0F ; fully-qualified # ⛹️‍♂️ man bouncing ball
+26F9 200D 2642 FE0F ; non-fully-qualified # ⛹‍♂️ man bouncing ball
+26F9 FE0F 200D 2642 ; non-fully-qualified # ⛹️‍♂ man bouncing ball
+26F9 200D 2642 ; non-fully-qualified # ⛹‍♂ man bouncing ball
+26F9 1F3FB 200D 2642 FE0F ; fully-qualified # ⛹🏻‍♂️ man bouncing ball: light skin tone
+26F9 1F3FB 200D 2642 ; non-fully-qualified # ⛹🏻‍♂ man bouncing ball: light skin tone
+26F9 1F3FC 200D 2642 FE0F ; fully-qualified # ⛹🏼‍♂️ man bouncing ball: medium-light skin tone
+26F9 1F3FC 200D 2642 ; non-fully-qualified # ⛹🏼‍♂ man bouncing ball: medium-light skin tone
+26F9 1F3FD 200D 2642 FE0F ; fully-qualified # ⛹🏽‍♂️ man bouncing ball: medium skin tone
+26F9 1F3FD 200D 2642 ; non-fully-qualified # ⛹🏽‍♂ man bouncing ball: medium skin tone
+26F9 1F3FE 200D 2642 FE0F ; fully-qualified # ⛹🏾‍♂️ man bouncing ball: medium-dark skin tone
+26F9 1F3FE 200D 2642 ; non-fully-qualified # ⛹🏾‍♂ man bouncing ball: medium-dark skin tone
+26F9 1F3FF 200D 2642 FE0F ; fully-qualified # ⛹🏿‍♂️ man bouncing ball: dark skin tone
+26F9 1F3FF 200D 2642 ; non-fully-qualified # ⛹🏿‍♂ man bouncing ball: dark skin tone
+26F9 FE0F 200D 2640 FE0F ; fully-qualified # ⛹️‍♀️ woman bouncing ball
+26F9 200D 2640 FE0F ; non-fully-qualified # ⛹‍♀️ woman bouncing ball
+26F9 FE0F 200D 2640 ; non-fully-qualified # ⛹️‍♀ woman bouncing ball
+26F9 200D 2640 ; non-fully-qualified # ⛹‍♀ woman bouncing ball
+26F9 1F3FB 200D 2640 FE0F ; fully-qualified # ⛹🏻‍♀️ woman bouncing ball: light skin tone
+26F9 1F3FB 200D 2640 ; non-fully-qualified # ⛹🏻‍♀ woman bouncing ball: light skin tone
+26F9 1F3FC 200D 2640 FE0F ; fully-qualified # ⛹🏼‍♀️ woman bouncing ball: medium-light skin tone
+26F9 1F3FC 200D 2640 ; non-fully-qualified # ⛹🏼‍♀ woman bouncing ball: medium-light skin tone
+26F9 1F3FD 200D 2640 FE0F ; fully-qualified # ⛹🏽‍♀️ woman bouncing ball: medium skin tone
+26F9 1F3FD 200D 2640 ; non-fully-qualified # ⛹🏽‍♀ woman bouncing ball: medium skin tone
+26F9 1F3FE 200D 2640 FE0F ; fully-qualified # ⛹🏾‍♀️ woman bouncing ball: medium-dark skin tone
+26F9 1F3FE 200D 2640 ; non-fully-qualified # ⛹🏾‍♀ woman bouncing ball: medium-dark skin tone
+26F9 1F3FF 200D 2640 FE0F ; fully-qualified # ⛹🏿‍♀️ woman bouncing ball: dark skin tone
+26F9 1F3FF 200D 2640 ; non-fully-qualified # ⛹🏿‍♀ woman bouncing ball: dark skin tone
+1F3CB FE0F ; fully-qualified # 🏋️ person lifting weights
+1F3CB ; non-fully-qualified # 🏋 person lifting weights
+1F3CB 1F3FB ; fully-qualified # 🏋🏻 person lifting weights: light skin tone
+1F3CB 1F3FC ; fully-qualified # 🏋🏼 person lifting weights: medium-light skin tone
+1F3CB 1F3FD ; fully-qualified # 🏋🏽 person lifting weights: medium skin tone
+1F3CB 1F3FE ; fully-qualified # 🏋🏾 person lifting weights: medium-dark skin tone
+1F3CB 1F3FF ; fully-qualified # 🏋🏿 person lifting weights: dark skin tone
+1F3CB FE0F 200D 2642 FE0F ; fully-qualified # 🏋️‍♂️ man lifting weights
+1F3CB 200D 2642 FE0F ; non-fully-qualified # 🏋‍♂️ man lifting weights
+1F3CB FE0F 200D 2642 ; non-fully-qualified # 🏋️‍♂ man lifting weights
+1F3CB 200D 2642 ; non-fully-qualified # 🏋‍♂ man lifting weights
+1F3CB 1F3FB 200D 2642 FE0F ; fully-qualified # 🏋🏻‍♂️ man lifting weights: light skin tone
+1F3CB 1F3FB 200D 2642 ; non-fully-qualified # 🏋🏻‍♂ man lifting weights: light skin tone
+1F3CB 1F3FC 200D 2642 FE0F ; fully-qualified # 🏋🏼‍♂️ man lifting weights: medium-light skin tone
+1F3CB 1F3FC 200D 2642 ; non-fully-qualified # 🏋🏼‍♂ man lifting weights: medium-light skin tone
+1F3CB 1F3FD 200D 2642 FE0F ; fully-qualified # 🏋🏽‍♂️ man lifting weights: medium skin tone
+1F3CB 1F3FD 200D 2642 ; non-fully-qualified # 🏋🏽‍♂ man lifting weights: medium skin tone
+1F3CB 1F3FE 200D 2642 FE0F ; fully-qualified # 🏋🏾‍♂️ man lifting weights: medium-dark skin tone
+1F3CB 1F3FE 200D 2642 ; non-fully-qualified # 🏋🏾‍♂ man lifting weights: medium-dark skin tone
+1F3CB 1F3FF 200D 2642 FE0F ; fully-qualified # 🏋🏿‍♂️ man lifting weights: dark skin tone
+1F3CB 1F3FF 200D 2642 ; non-fully-qualified # 🏋🏿‍♂ man lifting weights: dark skin tone
+1F3CB FE0F 200D 2640 FE0F ; fully-qualified # 🏋️‍♀️ woman lifting weights
+1F3CB 200D 2640 FE0F ; non-fully-qualified # 🏋‍♀️ woman lifting weights
+1F3CB FE0F 200D 2640 ; non-fully-qualified # 🏋️‍♀ woman lifting weights
+1F3CB 200D 2640 ; non-fully-qualified # 🏋‍♀ woman lifting weights
+1F3CB 1F3FB 200D 2640 FE0F ; fully-qualified # 🏋🏻‍♀️ woman lifting weights: light skin tone
+1F3CB 1F3FB 200D 2640 ; non-fully-qualified # 🏋🏻‍♀ woman lifting weights: light skin tone
+1F3CB 1F3FC 200D 2640 FE0F ; fully-qualified # 🏋🏼‍♀️ woman lifting weights: medium-light skin tone
+1F3CB 1F3FC 200D 2640 ; non-fully-qualified # 🏋🏼‍♀ woman lifting weights: medium-light skin tone
+1F3CB 1F3FD 200D 2640 FE0F ; fully-qualified # 🏋🏽‍♀️ woman lifting weights: medium skin tone
+1F3CB 1F3FD 200D 2640 ; non-fully-qualified # 🏋🏽‍♀ woman lifting weights: medium skin tone
+1F3CB 1F3FE 200D 2640 FE0F ; fully-qualified # 🏋🏾‍♀️ woman lifting weights: medium-dark skin tone
+1F3CB 1F3FE 200D 2640 ; non-fully-qualified # 🏋🏾‍♀ woman lifting weights: medium-dark skin tone
+1F3CB 1F3FF 200D 2640 FE0F ; fully-qualified # 🏋🏿‍♀️ woman lifting weights: dark skin tone
+1F3CB 1F3FF 200D 2640 ; non-fully-qualified # 🏋🏿‍♀ woman lifting weights: dark skin tone
+1F6B4 ; fully-qualified # 🚴 person biking
+1F6B4 1F3FB ; fully-qualified # 🚴🏻 person biking: light skin tone
+1F6B4 1F3FC ; fully-qualified # 🚴🏼 person biking: medium-light skin tone
+1F6B4 1F3FD ; fully-qualified # 🚴🏽 person biking: medium skin tone
+1F6B4 1F3FE ; fully-qualified # 🚴🏾 person biking: medium-dark skin tone
+1F6B4 1F3FF ; fully-qualified # 🚴🏿 person biking: dark skin tone
+1F6B4 200D 2642 FE0F ; fully-qualified # 🚴‍♂️ man biking
+1F6B4 200D 2642 ; non-fully-qualified # 🚴‍♂ man biking
+1F6B4 1F3FB 200D 2642 FE0F ; fully-qualified # 🚴🏻‍♂️ man biking: light skin tone
+1F6B4 1F3FB 200D 2642 ; non-fully-qualified # 🚴🏻‍♂ man biking: light skin tone
+1F6B4 1F3FC 200D 2642 FE0F ; fully-qualified # 🚴🏼‍♂️ man biking: medium-light skin tone
+1F6B4 1F3FC 200D 2642 ; non-fully-qualified # 🚴🏼‍♂ man biking: medium-light skin tone
+1F6B4 1F3FD 200D 2642 FE0F ; fully-qualified # 🚴🏽‍♂️ man biking: medium skin tone
+1F6B4 1F3FD 200D 2642 ; non-fully-qualified # 🚴🏽‍♂ man biking: medium skin tone
+1F6B4 1F3FE 200D 2642 FE0F ; fully-qualified # 🚴🏾‍♂️ man biking: medium-dark skin tone
+1F6B4 1F3FE 200D 2642 ; non-fully-qualified # 🚴🏾‍♂ man biking: medium-dark skin tone
+1F6B4 1F3FF 200D 2642 FE0F ; fully-qualified # 🚴🏿‍♂️ man biking: dark skin tone
+1F6B4 1F3FF 200D 2642 ; non-fully-qualified # 🚴🏿‍♂ man biking: dark skin tone
+1F6B4 200D 2640 FE0F ; fully-qualified # 🚴‍♀️ woman biking
+1F6B4 200D 2640 ; non-fully-qualified # 🚴‍♀ woman biking
+1F6B4 1F3FB 200D 2640 FE0F ; fully-qualified # 🚴🏻‍♀️ woman biking: light skin tone
+1F6B4 1F3FB 200D 2640 ; non-fully-qualified # 🚴🏻‍♀ woman biking: light skin tone
+1F6B4 1F3FC 200D 2640 FE0F ; fully-qualified # 🚴🏼‍♀️ woman biking: medium-light skin tone
+1F6B4 1F3FC 200D 2640 ; non-fully-qualified # 🚴🏼‍♀ woman biking: medium-light skin tone
+1F6B4 1F3FD 200D 2640 FE0F ; fully-qualified # 🚴🏽‍♀️ woman biking: medium skin tone
+1F6B4 1F3FD 200D 2640 ; non-fully-qualified # 🚴🏽‍♀ woman biking: medium skin tone
+1F6B4 1F3FE 200D 2640 FE0F ; fully-qualified # 🚴🏾‍♀️ woman biking: medium-dark skin tone
+1F6B4 1F3FE 200D 2640 ; non-fully-qualified # 🚴🏾‍♀ woman biking: medium-dark skin tone
+1F6B4 1F3FF 200D 2640 FE0F ; fully-qualified # 🚴🏿‍♀️ woman biking: dark skin tone
+1F6B4 1F3FF 200D 2640 ; non-fully-qualified # 🚴🏿‍♀ woman biking: dark skin tone
+1F6B5 ; fully-qualified # 🚵 person mountain biking
+1F6B5 1F3FB ; fully-qualified # 🚵🏻 person mountain biking: light skin tone
+1F6B5 1F3FC ; fully-qualified # 🚵🏼 person mountain biking: medium-light skin tone
+1F6B5 1F3FD ; fully-qualified # 🚵🏽 person mountain biking: medium skin tone
+1F6B5 1F3FE ; fully-qualified # 🚵🏾 person mountain biking: medium-dark skin tone
+1F6B5 1F3FF ; fully-qualified # 🚵🏿 person mountain biking: dark skin tone
+1F6B5 200D 2642 FE0F ; fully-qualified # 🚵‍♂️ man mountain biking
+1F6B5 200D 2642 ; non-fully-qualified # 🚵‍♂ man mountain biking
+1F6B5 1F3FB 200D 2642 FE0F ; fully-qualified # 🚵🏻‍♂️ man mountain biking: light skin tone
+1F6B5 1F3FB 200D 2642 ; non-fully-qualified # 🚵🏻‍♂ man mountain biking: light skin tone
+1F6B5 1F3FC 200D 2642 FE0F ; fully-qualified # 🚵🏼‍♂️ man mountain biking: medium-light skin tone
+1F6B5 1F3FC 200D 2642 ; non-fully-qualified # 🚵🏼‍♂ man mountain biking: medium-light skin tone
+1F6B5 1F3FD 200D 2642 FE0F ; fully-qualified # 🚵🏽‍♂️ man mountain biking: medium skin tone
+1F6B5 1F3FD 200D 2642 ; non-fully-qualified # 🚵🏽‍♂ man mountain biking: medium skin tone
+1F6B5 1F3FE 200D 2642 FE0F ; fully-qualified # 🚵🏾‍♂️ man mountain biking: medium-dark skin tone
+1F6B5 1F3FE 200D 2642 ; non-fully-qualified # 🚵🏾‍♂ man mountain biking: medium-dark skin tone
+1F6B5 1F3FF 200D 2642 FE0F ; fully-qualified # 🚵🏿‍♂️ man mountain biking: dark skin tone
+1F6B5 1F3FF 200D 2642 ; non-fully-qualified # 🚵🏿‍♂ man mountain biking: dark skin tone
+1F6B5 200D 2640 FE0F ; fully-qualified # 🚵‍♀️ woman mountain biking
+1F6B5 200D 2640 ; non-fully-qualified # 🚵‍♀ woman mountain biking
+1F6B5 1F3FB 200D 2640 FE0F ; fully-qualified # 🚵🏻‍♀️ woman mountain biking: light skin tone
+1F6B5 1F3FB 200D 2640 ; non-fully-qualified # 🚵🏻‍♀ woman mountain biking: light skin tone
+1F6B5 1F3FC 200D 2640 FE0F ; fully-qualified # 🚵🏼‍♀️ woman mountain biking: medium-light skin tone
+1F6B5 1F3FC 200D 2640 ; non-fully-qualified # 🚵🏼‍♀ woman mountain biking: medium-light skin tone
+1F6B5 1F3FD 200D 2640 FE0F ; fully-qualified # 🚵🏽‍♀️ woman mountain biking: medium skin tone
+1F6B5 1F3FD 200D 2640 ; non-fully-qualified # 🚵🏽‍♀ woman mountain biking: medium skin tone
+1F6B5 1F3FE 200D 2640 FE0F ; fully-qualified # 🚵🏾‍♀️ woman mountain biking: medium-dark skin tone
+1F6B5 1F3FE 200D 2640 ; non-fully-qualified # 🚵🏾‍♀ woman mountain biking: medium-dark skin tone
+1F6B5 1F3FF 200D 2640 FE0F ; fully-qualified # 🚵🏿‍♀️ woman mountain biking: dark skin tone
+1F6B5 1F3FF 200D 2640 ; non-fully-qualified # 🚵🏿‍♀ woman mountain biking: dark skin tone
+1F3CE FE0F ; fully-qualified # 🏎️ racing car
+1F3CE ; non-fully-qualified # 🏎 racing car
+1F3CD FE0F ; fully-qualified # 🏍️ motorcycle
+1F3CD ; non-fully-qualified # 🏍 motorcycle
+1F938 ; fully-qualified # 🤸 person cartwheeling
+1F938 1F3FB ; fully-qualified # 🤸🏻 person cartwheeling: light skin tone
+1F938 1F3FC ; fully-qualified # 🤸🏼 person cartwheeling: medium-light skin tone
+1F938 1F3FD ; fully-qualified # 🤸🏽 person cartwheeling: medium skin tone
+1F938 1F3FE ; fully-qualified # 🤸🏾 person cartwheeling: medium-dark skin tone
+1F938 1F3FF ; fully-qualified # 🤸🏿 person cartwheeling: dark skin tone
+1F938 200D 2642 FE0F ; fully-qualified # 🤸‍♂️ man cartwheeling
+1F938 200D 2642 ; non-fully-qualified # 🤸‍♂ man cartwheeling
+1F938 1F3FB 200D 2642 FE0F ; fully-qualified # 🤸🏻‍♂️ man cartwheeling: light skin tone
+1F938 1F3FB 200D 2642 ; non-fully-qualified # 🤸🏻‍♂ man cartwheeling: light skin tone
+1F938 1F3FC 200D 2642 FE0F ; fully-qualified # 🤸🏼‍♂️ man cartwheeling: medium-light skin tone
+1F938 1F3FC 200D 2642 ; non-fully-qualified # 🤸🏼‍♂ man cartwheeling: medium-light skin tone
+1F938 1F3FD 200D 2642 FE0F ; fully-qualified # 🤸🏽‍♂️ man cartwheeling: medium skin tone
+1F938 1F3FD 200D 2642 ; non-fully-qualified # 🤸🏽‍♂ man cartwheeling: medium skin tone
+1F938 1F3FE 200D 2642 FE0F ; fully-qualified # 🤸🏾‍♂️ man cartwheeling: medium-dark skin tone
+1F938 1F3FE 200D 2642 ; non-fully-qualified # 🤸🏾‍♂ man cartwheeling: medium-dark skin tone
+1F938 1F3FF 200D 2642 FE0F ; fully-qualified # 🤸🏿‍♂️ man cartwheeling: dark skin tone
+1F938 1F3FF 200D 2642 ; non-fully-qualified # 🤸🏿‍♂ man cartwheeling: dark skin tone
+1F938 200D 2640 FE0F ; fully-qualified # 🤸‍♀️ woman cartwheeling
+1F938 200D 2640 ; non-fully-qualified # 🤸‍♀ woman cartwheeling
+1F938 1F3FB 200D 2640 FE0F ; fully-qualified # 🤸🏻‍♀️ woman cartwheeling: light skin tone
+1F938 1F3FB 200D 2640 ; non-fully-qualified # 🤸🏻‍♀ woman cartwheeling: light skin tone
+1F938 1F3FC 200D 2640 FE0F ; fully-qualified # 🤸🏼‍♀️ woman cartwheeling: medium-light skin tone
+1F938 1F3FC 200D 2640 ; non-fully-qualified # 🤸🏼‍♀ woman cartwheeling: medium-light skin tone
+1F938 1F3FD 200D 2640 FE0F ; fully-qualified # 🤸🏽‍♀️ woman cartwheeling: medium skin tone
+1F938 1F3FD 200D 2640 ; non-fully-qualified # 🤸🏽‍♀ woman cartwheeling: medium skin tone
+1F938 1F3FE 200D 2640 FE0F ; fully-qualified # 🤸🏾‍♀️ woman cartwheeling: medium-dark skin tone
+1F938 1F3FE 200D 2640 ; non-fully-qualified # 🤸🏾‍♀ woman cartwheeling: medium-dark skin tone
+1F938 1F3FF 200D 2640 FE0F ; fully-qualified # 🤸🏿‍♀️ woman cartwheeling: dark skin tone
+1F938 1F3FF 200D 2640 ; non-fully-qualified # 🤸🏿‍♀ woman cartwheeling: dark skin tone
+1F93C ; fully-qualified # 🤼 people wrestling
+1F93C 200D 2642 FE0F ; fully-qualified # 🤼‍♂️ men wrestling
+1F93C 200D 2642 ; non-fully-qualified # 🤼‍♂ men wrestling
+1F93C 200D 2640 FE0F ; fully-qualified # 🤼‍♀️ women wrestling
+1F93C 200D 2640 ; non-fully-qualified # 🤼‍♀ women wrestling
+1F93D ; fully-qualified # 🤽 person playing water polo
+1F93D 1F3FB ; fully-qualified # 🤽🏻 person playing water polo: light skin tone
+1F93D 1F3FC ; fully-qualified # 🤽🏼 person playing water polo: medium-light skin tone
+1F93D 1F3FD ; fully-qualified # 🤽🏽 person playing water polo: medium skin tone
+1F93D 1F3FE ; fully-qualified # 🤽🏾 person playing water polo: medium-dark skin tone
+1F93D 1F3FF ; fully-qualified # 🤽🏿 person playing water polo: dark skin tone
+1F93D 200D 2642 FE0F ; fully-qualified # 🤽‍♂️ man playing water polo
+1F93D 200D 2642 ; non-fully-qualified # 🤽‍♂ man playing water polo
+1F93D 1F3FB 200D 2642 FE0F ; fully-qualified # 🤽🏻‍♂️ man playing water polo: light skin tone
+1F93D 1F3FB 200D 2642 ; non-fully-qualified # 🤽🏻‍♂ man playing water polo: light skin tone
+1F93D 1F3FC 200D 2642 FE0F ; fully-qualified # 🤽🏼‍♂️ man playing water polo: medium-light skin tone
+1F93D 1F3FC 200D 2642 ; non-fully-qualified # 🤽🏼‍♂ man playing water polo: medium-light skin tone
+1F93D 1F3FD 200D 2642 FE0F ; fully-qualified # 🤽🏽‍♂️ man playing water polo: medium skin tone
+1F93D 1F3FD 200D 2642 ; non-fully-qualified # 🤽🏽‍♂ man playing water polo: medium skin tone
+1F93D 1F3FE 200D 2642 FE0F ; fully-qualified # 🤽🏾‍♂️ man playing water polo: medium-dark skin tone
+1F93D 1F3FE 200D 2642 ; non-fully-qualified # 🤽🏾‍♂ man playing water polo: medium-dark skin tone
+1F93D 1F3FF 200D 2642 FE0F ; fully-qualified # 🤽🏿‍♂️ man playing water polo: dark skin tone
+1F93D 1F3FF 200D 2642 ; non-fully-qualified # 🤽🏿‍♂ man playing water polo: dark skin tone
+1F93D 200D 2640 FE0F ; fully-qualified # 🤽‍♀️ woman playing water polo
+1F93D 200D 2640 ; non-fully-qualified # 🤽‍♀ woman playing water polo
+1F93D 1F3FB 200D 2640 FE0F ; fully-qualified # 🤽🏻‍♀️ woman playing water polo: light skin tone
+1F93D 1F3FB 200D 2640 ; non-fully-qualified # 🤽🏻‍♀ woman playing water polo: light skin tone
+1F93D 1F3FC 200D 2640 FE0F ; fully-qualified # 🤽🏼‍♀️ woman playing water polo: medium-light skin tone
+1F93D 1F3FC 200D 2640 ; non-fully-qualified # 🤽🏼‍♀ woman playing water polo: medium-light skin tone
+1F93D 1F3FD 200D 2640 FE0F ; fully-qualified # 🤽🏽‍♀️ woman playing water polo: medium skin tone
+1F93D 1F3FD 200D 2640 ; non-fully-qualified # 🤽🏽‍♀ woman playing water polo: medium skin tone
+1F93D 1F3FE 200D 2640 FE0F ; fully-qualified # 🤽🏾‍♀️ woman playing water polo: medium-dark skin tone
+1F93D 1F3FE 200D 2640 ; non-fully-qualified # 🤽🏾‍♀ woman playing water polo: medium-dark skin tone
+1F93D 1F3FF 200D 2640 FE0F ; fully-qualified # 🤽🏿‍♀️ woman playing water polo: dark skin tone
+1F93D 1F3FF 200D 2640 ; non-fully-qualified # 🤽🏿‍♀ woman playing water polo: dark skin tone
+1F93E ; fully-qualified # 🤾 person playing handball
+1F93E 1F3FB ; fully-qualified # 🤾🏻 person playing handball: light skin tone
+1F93E 1F3FC ; fully-qualified # 🤾🏼 person playing handball: medium-light skin tone
+1F93E 1F3FD ; fully-qualified # 🤾🏽 person playing handball: medium skin tone
+1F93E 1F3FE ; fully-qualified # 🤾🏾 person playing handball: medium-dark skin tone
+1F93E 1F3FF ; fully-qualified # 🤾🏿 person playing handball: dark skin tone
+1F93E 200D 2642 FE0F ; fully-qualified # 🤾‍♂️ man playing handball
+1F93E 200D 2642 ; non-fully-qualified # 🤾‍♂ man playing handball
+1F93E 1F3FB 200D 2642 FE0F ; fully-qualified # 🤾🏻‍♂️ man playing handball: light skin tone
+1F93E 1F3FB 200D 2642 ; non-fully-qualified # 🤾🏻‍♂ man playing handball: light skin tone
+1F93E 1F3FC 200D 2642 FE0F ; fully-qualified # 🤾🏼‍♂️ man playing handball: medium-light skin tone
+1F93E 1F3FC 200D 2642 ; non-fully-qualified # 🤾🏼‍♂ man playing handball: medium-light skin tone
+1F93E 1F3FD 200D 2642 FE0F ; fully-qualified # 🤾🏽‍♂️ man playing handball: medium skin tone
+1F93E 1F3FD 200D 2642 ; non-fully-qualified # 🤾🏽‍♂ man playing handball: medium skin tone
+1F93E 1F3FE 200D 2642 FE0F ; fully-qualified # 🤾🏾‍♂️ man playing handball: medium-dark skin tone
+1F93E 1F3FE 200D 2642 ; non-fully-qualified # 🤾🏾‍♂ man playing handball: medium-dark skin tone
+1F93E 1F3FF 200D 2642 FE0F ; fully-qualified # 🤾🏿‍♂️ man playing handball: dark skin tone
+1F93E 1F3FF 200D 2642 ; non-fully-qualified # 🤾🏿‍♂ man playing handball: dark skin tone
+1F93E 200D 2640 FE0F ; fully-qualified # 🤾‍♀️ woman playing handball
+1F93E 200D 2640 ; non-fully-qualified # 🤾‍♀ woman playing handball
+1F93E 1F3FB 200D 2640 FE0F ; fully-qualified # 🤾🏻‍♀️ woman playing handball: light skin tone
+1F93E 1F3FB 200D 2640 ; non-fully-qualified # 🤾🏻‍♀ woman playing handball: light skin tone
+1F93E 1F3FC 200D 2640 FE0F ; fully-qualified # 🤾🏼‍♀️ woman playing handball: medium-light skin tone
+1F93E 1F3FC 200D 2640 ; non-fully-qualified # 🤾🏼‍♀ woman playing handball: medium-light skin tone
+1F93E 1F3FD 200D 2640 FE0F ; fully-qualified # 🤾🏽‍♀️ woman playing handball: medium skin tone
+1F93E 1F3FD 200D 2640 ; non-fully-qualified # 🤾🏽‍♀ woman playing handball: medium skin tone
+1F93E 1F3FE 200D 2640 FE0F ; fully-qualified # 🤾🏾‍♀️ woman playing handball: medium-dark skin tone
+1F93E 1F3FE 200D 2640 ; non-fully-qualified # 🤾🏾‍♀ woman playing handball: medium-dark skin tone
+1F93E 1F3FF 200D 2640 FE0F ; fully-qualified # 🤾🏿‍♀️ woman playing handball: dark skin tone
+1F93E 1F3FF 200D 2640 ; non-fully-qualified # 🤾🏿‍♀ woman playing handball: dark skin tone
+1F939 ; fully-qualified # 🤹 person juggling
+1F939 1F3FB ; fully-qualified # 🤹🏻 person juggling: light skin tone
+1F939 1F3FC ; fully-qualified # 🤹🏼 person juggling: medium-light skin tone
+1F939 1F3FD ; fully-qualified # 🤹🏽 person juggling: medium skin tone
+1F939 1F3FE ; fully-qualified # 🤹🏾 person juggling: medium-dark skin tone
+1F939 1F3FF ; fully-qualified # 🤹🏿 person juggling: dark skin tone
+1F939 200D 2642 FE0F ; fully-qualified # 🤹‍♂️ man juggling
+1F939 200D 2642 ; non-fully-qualified # 🤹‍♂ man juggling
+1F939 1F3FB 200D 2642 FE0F ; fully-qualified # 🤹🏻‍♂️ man juggling: light skin tone
+1F939 1F3FB 200D 2642 ; non-fully-qualified # 🤹🏻‍♂ man juggling: light skin tone
+1F939 1F3FC 200D 2642 FE0F ; fully-qualified # 🤹🏼‍♂️ man juggling: medium-light skin tone
+1F939 1F3FC 200D 2642 ; non-fully-qualified # 🤹🏼‍♂ man juggling: medium-light skin tone
+1F939 1F3FD 200D 2642 FE0F ; fully-qualified # 🤹🏽‍♂️ man juggling: medium skin tone
+1F939 1F3FD 200D 2642 ; non-fully-qualified # 🤹🏽‍♂ man juggling: medium skin tone
+1F939 1F3FE 200D 2642 FE0F ; fully-qualified # 🤹🏾‍♂️ man juggling: medium-dark skin tone
+1F939 1F3FE 200D 2642 ; non-fully-qualified # 🤹🏾‍♂ man juggling: medium-dark skin tone
+1F939 1F3FF 200D 2642 FE0F ; fully-qualified # 🤹🏿‍♂️ man juggling: dark skin tone
+1F939 1F3FF 200D 2642 ; non-fully-qualified # 🤹🏿‍♂ man juggling: dark skin tone
+1F939 200D 2640 FE0F ; fully-qualified # 🤹‍♀️ woman juggling
+1F939 200D 2640 ; non-fully-qualified # 🤹‍♀ woman juggling
+1F939 1F3FB 200D 2640 FE0F ; fully-qualified # 🤹🏻‍♀️ woman juggling: light skin tone
+1F939 1F3FB 200D 2640 ; non-fully-qualified # 🤹🏻‍♀ woman juggling: light skin tone
+1F939 1F3FC 200D 2640 FE0F ; fully-qualified # 🤹🏼‍♀️ woman juggling: medium-light skin tone
+1F939 1F3FC 200D 2640 ; non-fully-qualified # 🤹🏼‍♀ woman juggling: medium-light skin tone
+1F939 1F3FD 200D 2640 FE0F ; fully-qualified # 🤹🏽‍♀️ woman juggling: medium skin tone
+1F939 1F3FD 200D 2640 ; non-fully-qualified # 🤹🏽‍♀ woman juggling: medium skin tone
+1F939 1F3FE 200D 2640 FE0F ; fully-qualified # 🤹🏾‍♀️ woman juggling: medium-dark skin tone
+1F939 1F3FE 200D 2640 ; non-fully-qualified # 🤹🏾‍♀ woman juggling: medium-dark skin tone
+1F939 1F3FF 200D 2640 FE0F ; fully-qualified # 🤹🏿‍♀️ woman juggling: dark skin tone
+1F939 1F3FF 200D 2640 ; non-fully-qualified # 🤹🏿‍♀ woman juggling: dark skin tone
+
+# subgroup: family
+1F46B ; fully-qualified # 👫 man and woman holding hands
+1F46C ; fully-qualified # 👬 two men holding hands
+1F46D ; fully-qualified # 👭 two women holding hands
+1F48F ; fully-qualified # 💏 kiss
+1F469 200D 2764 FE0F 200D 1F48B 200D 1F468 ; fully-qualified # 👩‍❤️‍💋‍👨 kiss: woman, man
+1F469 200D 2764 200D 1F48B 200D 1F468 ; non-fully-qualified # 👩‍❤‍💋‍👨 kiss: woman, man
+1F468 200D 2764 FE0F 200D 1F48B 200D 1F468 ; fully-qualified # 👨‍❤️‍💋‍👨 kiss: man, man
+1F468 200D 2764 200D 1F48B 200D 1F468 ; non-fully-qualified # 👨‍❤‍💋‍👨 kiss: man, man
+1F469 200D 2764 FE0F 200D 1F48B 200D 1F469 ; fully-qualified # 👩‍❤️‍💋‍👩 kiss: woman, woman
+1F469 200D 2764 200D 1F48B 200D 1F469 ; non-fully-qualified # 👩‍❤‍💋‍👩 kiss: woman, woman
+1F491 ; fully-qualified # 💑 couple with heart
+1F469 200D 2764 FE0F 200D 1F468 ; fully-qualified # 👩‍❤️‍👨 couple with heart: woman, man
+1F469 200D 2764 200D 1F468 ; non-fully-qualified # 👩‍❤‍👨 couple with heart: woman, man
+1F468 200D 2764 FE0F 200D 1F468 ; fully-qualified # 👨‍❤️‍👨 couple with heart: man, man
+1F468 200D 2764 200D 1F468 ; non-fully-qualified # 👨‍❤‍👨 couple with heart: man, man
+1F469 200D 2764 FE0F 200D 1F469 ; fully-qualified # 👩‍❤️‍👩 couple with heart: woman, woman
+1F469 200D 2764 200D 1F469 ; non-fully-qualified # 👩‍❤‍👩 couple with heart: woman, woman
+1F46A ; fully-qualified # 👪 family
+1F468 200D 1F469 200D 1F466 ; fully-qualified # 👨‍👩‍👦 family: man, woman, boy
+1F468 200D 1F469 200D 1F467 ; fully-qualified # 👨‍👩‍👧 family: man, woman, girl
+1F468 200D 1F469 200D 1F467 200D 1F466 ; fully-qualified # 👨‍👩‍👧‍👦 family: man, woman, girl, boy
+1F468 200D 1F469 200D 1F466 200D 1F466 ; fully-qualified # 👨‍👩‍👦‍👦 family: man, woman, boy, boy
+1F468 200D 1F469 200D 1F467 200D 1F467 ; fully-qualified # 👨‍👩‍👧‍👧 family: man, woman, girl, girl
+1F468 200D 1F468 200D 1F466 ; fully-qualified # 👨‍👨‍👦 family: man, man, boy
+1F468 200D 1F468 200D 1F467 ; fully-qualified # 👨‍👨‍👧 family: man, man, girl
+1F468 200D 1F468 200D 1F467 200D 1F466 ; fully-qualified # 👨‍👨‍👧‍👦 family: man, man, girl, boy
+1F468 200D 1F468 200D 1F466 200D 1F466 ; fully-qualified # 👨‍👨‍👦‍👦 family: man, man, boy, boy
+1F468 200D 1F468 200D 1F467 200D 1F467 ; fully-qualified # 👨‍👨‍👧‍👧 family: man, man, girl, girl
+1F469 200D 1F469 200D 1F466 ; fully-qualified # 👩‍👩‍👦 family: woman, woman, boy
+1F469 200D 1F469 200D 1F467 ; fully-qualified # 👩‍👩‍👧 family: woman, woman, girl
+1F469 200D 1F469 200D 1F467 200D 1F466 ; fully-qualified # 👩‍👩‍👧‍👦 family: woman, woman, girl, boy
+1F469 200D 1F469 200D 1F466 200D 1F466 ; fully-qualified # 👩‍👩‍👦‍👦 family: woman, woman, boy, boy
+1F469 200D 1F469 200D 1F467 200D 1F467 ; fully-qualified # 👩‍👩‍👧‍👧 family: woman, woman, girl, girl
+1F468 200D 1F466 ; fully-qualified # 👨‍👦 family: man, boy
+1F468 200D 1F466 200D 1F466 ; fully-qualified # 👨‍👦‍👦 family: man, boy, boy
+1F468 200D 1F467 ; fully-qualified # 👨‍👧 family: man, girl
+1F468 200D 1F467 200D 1F466 ; fully-qualified # 👨‍👧‍👦 family: man, girl, boy
+1F468 200D 1F467 200D 1F467 ; fully-qualified # 👨‍👧‍👧 family: man, girl, girl
+1F469 200D 1F466 ; fully-qualified # 👩‍👦 family: woman, boy
+1F469 200D 1F466 200D 1F466 ; fully-qualified # 👩‍👦‍👦 family: woman, boy, boy
+1F469 200D 1F467 ; fully-qualified # 👩‍👧 family: woman, girl
+1F469 200D 1F467 200D 1F466 ; fully-qualified # 👩‍👧‍👦 family: woman, girl, boy
+1F469 200D 1F467 200D 1F467 ; fully-qualified # 👩‍👧‍👧 family: woman, girl, girl
+
+# subgroup: body
+1F933 ; fully-qualified # 🤳 selfie
+1F933 1F3FB ; fully-qualified # 🤳🏻 selfie: light skin tone
+1F933 1F3FC ; fully-qualified # 🤳🏼 selfie: medium-light skin tone
+1F933 1F3FD ; fully-qualified # 🤳🏽 selfie: medium skin tone
+1F933 1F3FE ; fully-qualified # 🤳🏾 selfie: medium-dark skin tone
+1F933 1F3FF ; fully-qualified # 🤳🏿 selfie: dark skin tone
+1F4AA ; fully-qualified # 💪 flexed biceps
+1F4AA 1F3FB ; fully-qualified # 💪🏻 flexed biceps: light skin tone
+1F4AA 1F3FC ; fully-qualified # 💪🏼 flexed biceps: medium-light skin tone
+1F4AA 1F3FD ; fully-qualified # 💪🏽 flexed biceps: medium skin tone
+1F4AA 1F3FE ; fully-qualified # 💪🏾 flexed biceps: medium-dark skin tone
+1F4AA 1F3FF ; fully-qualified # 💪🏿 flexed biceps: dark skin tone
+1F9B5 ; fully-qualified # 🦵 leg
+1F9B5 1F3FB ; fully-qualified # 🦵🏻 leg: light skin tone
+1F9B5 1F3FC ; fully-qualified # 🦵🏼 leg: medium-light skin tone
+1F9B5 1F3FD ; fully-qualified # 🦵🏽 leg: medium skin tone
+1F9B5 1F3FE ; fully-qualified # 🦵🏾 leg: medium-dark skin tone
+1F9B5 1F3FF ; fully-qualified # 🦵🏿 leg: dark skin tone
+1F9B6 ; fully-qualified # 🦶 foot
+1F9B6 1F3FB ; fully-qualified # 🦶🏻 foot: light skin tone
+1F9B6 1F3FC ; fully-qualified # 🦶🏼 foot: medium-light skin tone
+1F9B6 1F3FD ; fully-qualified # 🦶🏽 foot: medium skin tone
+1F9B6 1F3FE ; fully-qualified # 🦶🏾 foot: medium-dark skin tone
+1F9B6 1F3FF ; fully-qualified # 🦶🏿 foot: dark skin tone
+1F448 ; fully-qualified # 👈 backhand index pointing left
+1F448 1F3FB ; fully-qualified # 👈🏻 backhand index pointing left: light skin tone
+1F448 1F3FC ; fully-qualified # 👈🏼 backhand index pointing left: medium-light skin tone
+1F448 1F3FD ; fully-qualified # 👈🏽 backhand index pointing left: medium skin tone
+1F448 1F3FE ; fully-qualified # 👈🏾 backhand index pointing left: medium-dark skin tone
+1F448 1F3FF ; fully-qualified # 👈🏿 backhand index pointing left: dark skin tone
+1F449 ; fully-qualified # 👉 backhand index pointing right
+1F449 1F3FB ; fully-qualified # 👉🏻 backhand index pointing right: light skin tone
+1F449 1F3FC ; fully-qualified # 👉🏼 backhand index pointing right: medium-light skin tone
+1F449 1F3FD ; fully-qualified # 👉🏽 backhand index pointing right: medium skin tone
+1F449 1F3FE ; fully-qualified # 👉🏾 backhand index pointing right: medium-dark skin tone
+1F449 1F3FF ; fully-qualified # 👉🏿 backhand index pointing right: dark skin tone
+261D FE0F ; fully-qualified # ☝️ index pointing up
+261D ; non-fully-qualified # ☝ index pointing up
+261D 1F3FB ; fully-qualified # ☝🏻 index pointing up: light skin tone
+261D 1F3FC ; fully-qualified # ☝🏼 index pointing up: medium-light skin tone
+261D 1F3FD ; fully-qualified # ☝🏽 index pointing up: medium skin tone
+261D 1F3FE ; fully-qualified # ☝🏾 index pointing up: medium-dark skin tone
+261D 1F3FF ; fully-qualified # ☝🏿 index pointing up: dark skin tone
+1F446 ; fully-qualified # 👆 backhand index pointing up
+1F446 1F3FB ; fully-qualified # 👆🏻 backhand index pointing up: light skin tone
+1F446 1F3FC ; fully-qualified # 👆🏼 backhand index pointing up: medium-light skin tone
+1F446 1F3FD ; fully-qualified # 👆🏽 backhand index pointing up: medium skin tone
+1F446 1F3FE ; fully-qualified # 👆🏾 backhand index pointing up: medium-dark skin tone
+1F446 1F3FF ; fully-qualified # 👆🏿 backhand index pointing up: dark skin tone
+1F595 ; fully-qualified # 🖕 middle finger
+1F595 1F3FB ; fully-qualified # 🖕🏻 middle finger: light skin tone
+1F595 1F3FC ; fully-qualified # 🖕🏼 middle finger: medium-light skin tone
+1F595 1F3FD ; fully-qualified # 🖕🏽 middle finger: medium skin tone
+1F595 1F3FE ; fully-qualified # 🖕🏾 middle finger: medium-dark skin tone
+1F595 1F3FF ; fully-qualified # 🖕🏿 middle finger: dark skin tone
+1F447 ; fully-qualified # 👇 backhand index pointing down
+1F447 1F3FB ; fully-qualified # 👇🏻 backhand index pointing down: light skin tone
+1F447 1F3FC ; fully-qualified # 👇🏼 backhand index pointing down: medium-light skin tone
+1F447 1F3FD ; fully-qualified # 👇🏽 backhand index pointing down: medium skin tone
+1F447 1F3FE ; fully-qualified # 👇🏾 backhand index pointing down: medium-dark skin tone
+1F447 1F3FF ; fully-qualified # 👇🏿 backhand index pointing down: dark skin tone
+270C FE0F ; fully-qualified # ✌️ victory hand
+270C ; non-fully-qualified # ✌ victory hand
+270C 1F3FB ; fully-qualified # ✌🏻 victory hand: light skin tone
+270C 1F3FC ; fully-qualified # ✌🏼 victory hand: medium-light skin tone
+270C 1F3FD ; fully-qualified # ✌🏽 victory hand: medium skin tone
+270C 1F3FE ; fully-qualified # ✌🏾 victory hand: medium-dark skin tone
+270C 1F3FF ; fully-qualified # ✌🏿 victory hand: dark skin tone
+1F91E ; fully-qualified # 🤞 crossed fingers
+1F91E 1F3FB ; fully-qualified # 🤞🏻 crossed fingers: light skin tone
+1F91E 1F3FC ; fully-qualified # 🤞🏼 crossed fingers: medium-light skin tone
+1F91E 1F3FD ; fully-qualified # 🤞🏽 crossed fingers: medium skin tone
+1F91E 1F3FE ; fully-qualified # 🤞🏾 crossed fingers: medium-dark skin tone
+1F91E 1F3FF ; fully-qualified # 🤞🏿 crossed fingers: dark skin tone
+1F596 ; fully-qualified # 🖖 vulcan salute
+1F596 1F3FB ; fully-qualified # 🖖🏻 vulcan salute: light skin tone
+1F596 1F3FC ; fully-qualified # 🖖🏼 vulcan salute: medium-light skin tone
+1F596 1F3FD ; fully-qualified # 🖖🏽 vulcan salute: medium skin tone
+1F596 1F3FE ; fully-qualified # 🖖🏾 vulcan salute: medium-dark skin tone
+1F596 1F3FF ; fully-qualified # 🖖🏿 vulcan salute: dark skin tone
+1F918 ; fully-qualified # 🤘 sign of the horns
+1F918 1F3FB ; fully-qualified # 🤘🏻 sign of the horns: light skin tone
+1F918 1F3FC ; fully-qualified # 🤘🏼 sign of the horns: medium-light skin tone
+1F918 1F3FD ; fully-qualified # 🤘🏽 sign of the horns: medium skin tone
+1F918 1F3FE ; fully-qualified # 🤘🏾 sign of the horns: medium-dark skin tone
+1F918 1F3FF ; fully-qualified # 🤘🏿 sign of the horns: dark skin tone
+1F919 ; fully-qualified # 🤙 call me hand
+1F919 1F3FB ; fully-qualified # 🤙🏻 call me hand: light skin tone
+1F919 1F3FC ; fully-qualified # 🤙🏼 call me hand: medium-light skin tone
+1F919 1F3FD ; fully-qualified # 🤙🏽 call me hand: medium skin tone
+1F919 1F3FE ; fully-qualified # 🤙🏾 call me hand: medium-dark skin tone
+1F919 1F3FF ; fully-qualified # 🤙🏿 call me hand: dark skin tone
+1F590 FE0F ; fully-qualified # 🖐️ hand with fingers splayed
+1F590 ; non-fully-qualified # 🖐 hand with fingers splayed
+1F590 1F3FB ; fully-qualified # 🖐🏻 hand with fingers splayed: light skin tone
+1F590 1F3FC ; fully-qualified # 🖐🏼 hand with fingers splayed: medium-light skin tone
+1F590 1F3FD ; fully-qualified # 🖐🏽 hand with fingers splayed: medium skin tone
+1F590 1F3FE ; fully-qualified # 🖐🏾 hand with fingers splayed: medium-dark skin tone
+1F590 1F3FF ; fully-qualified # 🖐🏿 hand with fingers splayed: dark skin tone
+270B ; fully-qualified # ✋ raised hand
+270B 1F3FB ; fully-qualified # ✋🏻 raised hand: light skin tone
+270B 1F3FC ; fully-qualified # ✋🏼 raised hand: medium-light skin tone
+270B 1F3FD ; fully-qualified # ✋🏽 raised hand: medium skin tone
+270B 1F3FE ; fully-qualified # ✋🏾 raised hand: medium-dark skin tone
+270B 1F3FF ; fully-qualified # ✋🏿 raised hand: dark skin tone
+1F44C ; fully-qualified # 👌 OK hand
+1F44C 1F3FB ; fully-qualified # 👌🏻 OK hand: light skin tone
+1F44C 1F3FC ; fully-qualified # 👌🏼 OK hand: medium-light skin tone
+1F44C 1F3FD ; fully-qualified # 👌🏽 OK hand: medium skin tone
+1F44C 1F3FE ; fully-qualified # 👌🏾 OK hand: medium-dark skin tone
+1F44C 1F3FF ; fully-qualified # 👌🏿 OK hand: dark skin tone
+1F44D ; fully-qualified # 👍 thumbs up
+1F44D 1F3FB ; fully-qualified # 👍🏻 thumbs up: light skin tone
+1F44D 1F3FC ; fully-qualified # 👍🏼 thumbs up: medium-light skin tone
+1F44D 1F3FD ; fully-qualified # 👍🏽 thumbs up: medium skin tone
+1F44D 1F3FE ; fully-qualified # 👍🏾 thumbs up: medium-dark skin tone
+1F44D 1F3FF ; fully-qualified # 👍🏿 thumbs up: dark skin tone
+1F44E ; fully-qualified # 👎 thumbs down
+1F44E 1F3FB ; fully-qualified # 👎🏻 thumbs down: light skin tone
+1F44E 1F3FC ; fully-qualified # 👎🏼 thumbs down: medium-light skin tone
+1F44E 1F3FD ; fully-qualified # 👎🏽 thumbs down: medium skin tone
+1F44E 1F3FE ; fully-qualified # 👎🏾 thumbs down: medium-dark skin tone
+1F44E 1F3FF ; fully-qualified # 👎🏿 thumbs down: dark skin tone
+270A ; fully-qualified # ✊ raised fist
+270A 1F3FB ; fully-qualified # ✊🏻 raised fist: light skin tone
+270A 1F3FC ; fully-qualified # ✊🏼 raised fist: medium-light skin tone
+270A 1F3FD ; fully-qualified # ✊🏽 raised fist: medium skin tone
+270A 1F3FE ; fully-qualified # ✊🏾 raised fist: medium-dark skin tone
+270A 1F3FF ; fully-qualified # ✊🏿 raised fist: dark skin tone
+1F44A ; fully-qualified # 👊 oncoming fist
+1F44A 1F3FB ; fully-qualified # 👊🏻 oncoming fist: light skin tone
+1F44A 1F3FC ; fully-qualified # 👊🏼 oncoming fist: medium-light skin tone
+1F44A 1F3FD ; fully-qualified # 👊🏽 oncoming fist: medium skin tone
+1F44A 1F3FE ; fully-qualified # 👊🏾 oncoming fist: medium-dark skin tone
+1F44A 1F3FF ; fully-qualified # 👊🏿 oncoming fist: dark skin tone
+1F91B ; fully-qualified # 🤛 left-facing fist
+1F91B 1F3FB ; fully-qualified # 🤛🏻 left-facing fist: light skin tone
+1F91B 1F3FC ; fully-qualified # 🤛🏼 left-facing fist: medium-light skin tone
+1F91B 1F3FD ; fully-qualified # 🤛🏽 left-facing fist: medium skin tone
+1F91B 1F3FE ; fully-qualified # 🤛🏾 left-facing fist: medium-dark skin tone
+1F91B 1F3FF ; fully-qualified # 🤛🏿 left-facing fist: dark skin tone
+1F91C ; fully-qualified # 🤜 right-facing fist
+1F91C 1F3FB ; fully-qualified # 🤜🏻 right-facing fist: light skin tone
+1F91C 1F3FC ; fully-qualified # 🤜🏼 right-facing fist: medium-light skin tone
+1F91C 1F3FD ; fully-qualified # 🤜🏽 right-facing fist: medium skin tone
+1F91C 1F3FE ; fully-qualified # 🤜🏾 right-facing fist: medium-dark skin tone
+1F91C 1F3FF ; fully-qualified # 🤜🏿 right-facing fist: dark skin tone
+1F91A ; fully-qualified # 🤚 raised back of hand
+1F91A 1F3FB ; fully-qualified # 🤚🏻 raised back of hand: light skin tone
+1F91A 1F3FC ; fully-qualified # 🤚🏼 raised back of hand: medium-light skin tone
+1F91A 1F3FD ; fully-qualified # 🤚🏽 raised back of hand: medium skin tone
+1F91A 1F3FE ; fully-qualified # 🤚🏾 raised back of hand: medium-dark skin tone
+1F91A 1F3FF ; fully-qualified # 🤚🏿 raised back of hand: dark skin tone
+1F44B ; fully-qualified # 👋 waving hand
+1F44B 1F3FB ; fully-qualified # 👋🏻 waving hand: light skin tone
+1F44B 1F3FC ; fully-qualified # 👋🏼 waving hand: medium-light skin tone
+1F44B 1F3FD ; fully-qualified # 👋🏽 waving hand: medium skin tone
+1F44B 1F3FE ; fully-qualified # 👋🏾 waving hand: medium-dark skin tone
+1F44B 1F3FF ; fully-qualified # 👋🏿 waving hand: dark skin tone
+1F91F ; fully-qualified # 🤟 love-you gesture
+1F91F 1F3FB ; fully-qualified # 🤟🏻 love-you gesture: light skin tone
+1F91F 1F3FC ; fully-qualified # 🤟🏼 love-you gesture: medium-light skin tone
+1F91F 1F3FD ; fully-qualified # 🤟🏽 love-you gesture: medium skin tone
+1F91F 1F3FE ; fully-qualified # 🤟🏾 love-you gesture: medium-dark skin tone
+1F91F 1F3FF ; fully-qualified # 🤟🏿 love-you gesture: dark skin tone
+270D FE0F ; fully-qualified # ✍️ writing hand
+270D ; non-fully-qualified # ✍ writing hand
+270D 1F3FB ; fully-qualified # ✍🏻 writing hand: light skin tone
+270D 1F3FC ; fully-qualified # ✍🏼 writing hand: medium-light skin tone
+270D 1F3FD ; fully-qualified # ✍🏽 writing hand: medium skin tone
+270D 1F3FE ; fully-qualified # ✍🏾 writing hand: medium-dark skin tone
+270D 1F3FF ; fully-qualified # ✍🏿 writing hand: dark skin tone
+1F44F ; fully-qualified # 👏 clapping hands
+1F44F 1F3FB ; fully-qualified # 👏🏻 clapping hands: light skin tone
+1F44F 1F3FC ; fully-qualified # 👏🏼 clapping hands: medium-light skin tone
+1F44F 1F3FD ; fully-qualified # 👏🏽 clapping hands: medium skin tone
+1F44F 1F3FE ; fully-qualified # 👏🏾 clapping hands: medium-dark skin tone
+1F44F 1F3FF ; fully-qualified # 👏🏿 clapping hands: dark skin tone
+1F450 ; fully-qualified # 👐 open hands
+1F450 1F3FB ; fully-qualified # 👐🏻 open hands: light skin tone
+1F450 1F3FC ; fully-qualified # 👐🏼 open hands: medium-light skin tone
+1F450 1F3FD ; fully-qualified # 👐🏽 open hands: medium skin tone
+1F450 1F3FE ; fully-qualified # 👐🏾 open hands: medium-dark skin tone
+1F450 1F3FF ; fully-qualified # 👐🏿 open hands: dark skin tone
+1F64C ; fully-qualified # 🙌 raising hands
+1F64C 1F3FB ; fully-qualified # 🙌🏻 raising hands: light skin tone
+1F64C 1F3FC ; fully-qualified # 🙌🏼 raising hands: medium-light skin tone
+1F64C 1F3FD ; fully-qualified # 🙌🏽 raising hands: medium skin tone
+1F64C 1F3FE ; fully-qualified # 🙌🏾 raising hands: medium-dark skin tone
+1F64C 1F3FF ; fully-qualified # 🙌🏿 raising hands: dark skin tone
+1F932 ; fully-qualified # 🤲 palms up together
+1F932 1F3FB ; fully-qualified # 🤲🏻 palms up together: light skin tone
+1F932 1F3FC ; fully-qualified # 🤲🏼 palms up together: medium-light skin tone
+1F932 1F3FD ; fully-qualified # 🤲🏽 palms up together: medium skin tone
+1F932 1F3FE ; fully-qualified # 🤲🏾 palms up together: medium-dark skin tone
+1F932 1F3FF ; fully-qualified # 🤲🏿 palms up together: dark skin tone
+1F64F ; fully-qualified # 🙏 folded hands
+1F64F 1F3FB ; fully-qualified # 🙏🏻 folded hands: light skin tone
+1F64F 1F3FC ; fully-qualified # 🙏🏼 folded hands: medium-light skin tone
+1F64F 1F3FD ; fully-qualified # 🙏🏽 folded hands: medium skin tone
+1F64F 1F3FE ; fully-qualified # 🙏🏾 folded hands: medium-dark skin tone
+1F64F 1F3FF ; fully-qualified # 🙏🏿 folded hands: dark skin tone
+1F91D ; fully-qualified # 🤝 handshake
+1F485 ; fully-qualified # 💅 nail polish
+1F485 1F3FB ; fully-qualified # 💅🏻 nail polish: light skin tone
+1F485 1F3FC ; fully-qualified # 💅🏼 nail polish: medium-light skin tone
+1F485 1F3FD ; fully-qualified # 💅🏽 nail polish: medium skin tone
+1F485 1F3FE ; fully-qualified # 💅🏾 nail polish: medium-dark skin tone
+1F485 1F3FF ; fully-qualified # 💅🏿 nail polish: dark skin tone
+1F442 ; fully-qualified # 👂 ear
+1F442 1F3FB ; fully-qualified # 👂🏻 ear: light skin tone
+1F442 1F3FC ; fully-qualified # 👂🏼 ear: medium-light skin tone
+1F442 1F3FD ; fully-qualified # 👂🏽 ear: medium skin tone
+1F442 1F3FE ; fully-qualified # 👂🏾 ear: medium-dark skin tone
+1F442 1F3FF ; fully-qualified # 👂🏿 ear: dark skin tone
+1F443 ; fully-qualified # 👃 nose
+1F443 1F3FB ; fully-qualified # 👃🏻 nose: light skin tone
+1F443 1F3FC ; fully-qualified # 👃🏼 nose: medium-light skin tone
+1F443 1F3FD ; fully-qualified # 👃🏽 nose: medium skin tone
+1F443 1F3FE ; fully-qualified # 👃🏾 nose: medium-dark skin tone
+1F443 1F3FF ; fully-qualified # 👃🏿 nose: dark skin tone
+1F9B0 ; fully-qualified # 🦰 red-haired
+1F9B1 ; fully-qualified # 🦱 curly-haired
+1F9B2 ; fully-qualified # 🦲 bald
+1F9B3 ; fully-qualified # 🦳 white-haired
+1F463 ; fully-qualified # 👣 footprints
+1F440 ; fully-qualified # 👀 eyes
+1F441 FE0F ; fully-qualified # 👁️ eye
+1F441 ; non-fully-qualified # 👁 eye
+1F441 FE0F 200D 1F5E8 FE0F ; fully-qualified # 👁️‍🗨️ eye in speech bubble
+1F441 200D 1F5E8 FE0F ; non-fully-qualified # 👁‍🗨️ eye in speech bubble
+1F441 FE0F 200D 1F5E8 ; non-fully-qualified # 👁️‍🗨 eye in speech bubble
+1F441 200D 1F5E8 ; non-fully-qualified # 👁‍🗨 eye in speech bubble
+1F9E0 ; fully-qualified # 🧠 brain
+1F9B4 ; fully-qualified # 🦴 bone
+1F9B7 ; fully-qualified # 🦷 tooth
+1F445 ; fully-qualified # 👅 tongue
+1F444 ; fully-qualified # 👄 mouth
+
+# subgroup: emotion
+1F48B ; fully-qualified # 💋 kiss mark
+1F498 ; fully-qualified # 💘 heart with arrow
+2764 FE0F ; fully-qualified # ❤️ red heart
+2764 ; non-fully-qualified # ❤ red heart
+1F493 ; fully-qualified # 💓 beating heart
+1F494 ; fully-qualified # 💔 broken heart
+1F495 ; fully-qualified # 💕 two hearts
+1F496 ; fully-qualified # 💖 sparkling heart
+1F497 ; fully-qualified # 💗 growing heart
+1F499 ; fully-qualified # 💙 blue heart
+1F49A ; fully-qualified # 💚 green heart
+1F49B ; fully-qualified # 💛 yellow heart
+1F9E1 ; fully-qualified # 🧡 orange heart
+1F49C ; fully-qualified # 💜 purple heart
+1F5A4 ; fully-qualified # 🖤 black heart
+1F49D ; fully-qualified # 💝 heart with ribbon
+1F49E ; fully-qualified # 💞 revolving hearts
+1F49F ; fully-qualified # 💟 heart decoration
+2763 FE0F ; fully-qualified # ❣️ heavy heart exclamation
+2763 ; non-fully-qualified # ❣ heavy heart exclamation
+1F48C ; fully-qualified # 💌 love letter
+1F4A4 ; fully-qualified # 💤 zzz
+1F4A2 ; fully-qualified # 💢 anger symbol
+1F4A3 ; fully-qualified # 💣 bomb
+1F4A5 ; fully-qualified # 💥 collision
+1F4A6 ; fully-qualified # 💦 sweat droplets
+1F4A8 ; fully-qualified # 💨 dashing away
+1F4AB ; fully-qualified # 💫 dizzy
+1F4AC ; fully-qualified # 💬 speech balloon
+1F5E8 FE0F ; fully-qualified # 🗨️ left speech bubble
+1F5E8 ; non-fully-qualified # 🗨 left speech bubble
+1F5EF FE0F ; fully-qualified # 🗯️ right anger bubble
+1F5EF ; non-fully-qualified # 🗯 right anger bubble
+1F4AD ; fully-qualified # 💭 thought balloon
+1F573 FE0F ; fully-qualified # 🕳️ hole
+1F573 ; non-fully-qualified # 🕳 hole
+
+# subgroup: clothing
+1F453 ; fully-qualified # 👓 glasses
+1F576 FE0F ; fully-qualified # 🕶️ sunglasses
+1F576 ; non-fully-qualified # 🕶 sunglasses
+1F97D ; fully-qualified # 🥽 goggles
+1F97C ; fully-qualified # 🥼 lab coat
+1F454 ; fully-qualified # 👔 necktie
+1F455 ; fully-qualified # 👕 t-shirt
+1F456 ; fully-qualified # 👖 jeans
+1F9E3 ; fully-qualified # 🧣 scarf
+1F9E4 ; fully-qualified # 🧤 gloves
+1F9E5 ; fully-qualified # 🧥 coat
+1F9E6 ; fully-qualified # 🧦 socks
+1F457 ; fully-qualified # 👗 dress
+1F458 ; fully-qualified # 👘 kimono
+1F459 ; fully-qualified # 👙 bikini
+1F45A ; fully-qualified # 👚 womans clothes
+1F45B ; fully-qualified # 👛 purse
+1F45C ; fully-qualified # 👜 handbag
+1F45D ; fully-qualified # 👝 clutch bag
+1F6CD FE0F ; fully-qualified # 🛍️ shopping bags
+1F6CD ; non-fully-qualified # 🛍 shopping bags
+1F392 ; fully-qualified # 🎒 school backpack
+1F45E ; fully-qualified # 👞 mans shoe
+1F45F ; fully-qualified # 👟 running shoe
+1F97E ; fully-qualified # 🥾 hiking boot
+1F97F ; fully-qualified # 🥿 womans flat shoe
+1F460 ; fully-qualified # 👠 high-heeled shoe
+1F461 ; fully-qualified # 👡 womans sandal
+1F462 ; fully-qualified # 👢 womans boot
+1F451 ; fully-qualified # 👑 crown
+1F452 ; fully-qualified # 👒 womans hat
+1F3A9 ; fully-qualified # 🎩 top hat
+1F393 ; fully-qualified # 🎓 graduation cap
+1F9E2 ; fully-qualified # 🧢 billed cap
+26D1 FE0F ; fully-qualified # ⛑️ rescue workers helmet
+26D1 ; non-fully-qualified # ⛑ rescue workers helmet
+1F4FF ; fully-qualified # 📿 prayer beads
+1F484 ; fully-qualified # 💄 lipstick
+1F48D ; fully-qualified # 💍 ring
+1F48E ; fully-qualified # 💎 gem stone
+
+# Smileys & People subtotal: 2210
+# Smileys & People subtotal: 625 w/o modifiers
+
+# group: Animals & Nature
+
+# subgroup: animal-mammal
+1F435 ; fully-qualified # 🐵 monkey face
+1F412 ; fully-qualified # 🐒 monkey
+1F98D ; fully-qualified # 🦍 gorilla
+1F436 ; fully-qualified # 🐶 dog face
+1F415 ; fully-qualified # 🐕 dog
+1F429 ; fully-qualified # 🐩 poodle
+1F43A ; fully-qualified # 🐺 wolf face
+1F98A ; fully-qualified # 🦊 fox face
+1F99D ; fully-qualified # 🦝 raccoon
+1F431 ; fully-qualified # 🐱 cat face
+1F408 ; fully-qualified # 🐈 cat
+1F981 ; fully-qualified # 🦁 lion face
+1F42F ; fully-qualified # 🐯 tiger face
+1F405 ; fully-qualified # 🐅 tiger
+1F406 ; fully-qualified # 🐆 leopard
+1F434 ; fully-qualified # 🐴 horse face
+1F40E ; fully-qualified # 🐎 horse
+1F984 ; fully-qualified # 🦄 unicorn face
+1F993 ; fully-qualified # 🦓 zebra
+1F98C ; fully-qualified # 🦌 deer
+1F42E ; fully-qualified # 🐮 cow face
+1F402 ; fully-qualified # 🐂 ox
+1F403 ; fully-qualified # 🐃 water buffalo
+1F404 ; fully-qualified # 🐄 cow
+1F437 ; fully-qualified # 🐷 pig face
+1F416 ; fully-qualified # 🐖 pig
+1F417 ; fully-qualified # 🐗 boar
+1F43D ; fully-qualified # 🐽 pig nose
+1F40F ; fully-qualified # 🐏 ram
+1F411 ; fully-qualified # 🐑 ewe
+1F410 ; fully-qualified # 🐐 goat
+1F42A ; fully-qualified # 🐪 camel
+1F42B ; fully-qualified # 🐫 two-hump camel
+1F999 ; fully-qualified # 🦙 llama
+1F992 ; fully-qualified # 🦒 giraffe
+1F418 ; fully-qualified # 🐘 elephant
+1F98F ; fully-qualified # 🦏 rhinoceros
+1F99B ; fully-qualified # 🦛 hippopotamus
+1F42D ; fully-qualified # 🐭 mouse face
+1F401 ; fully-qualified # 🐁 mouse
+1F400 ; fully-qualified # 🐀 rat
+1F439 ; fully-qualified # 🐹 hamster face
+1F430 ; fully-qualified # 🐰 rabbit face
+1F407 ; fully-qualified # 🐇 rabbit
+1F43F FE0F ; fully-qualified # 🐿️ chipmunk
+1F43F ; non-fully-qualified # 🐿 chipmunk
+1F994 ; fully-qualified # 🦔 hedgehog
+1F987 ; fully-qualified # 🦇 bat
+1F43B ; fully-qualified # 🐻 bear face
+1F428 ; fully-qualified # 🐨 koala
+1F43C ; fully-qualified # 🐼 panda face
+1F998 ; fully-qualified # 🦘 kangaroo
+1F9A1 ; fully-qualified # 🦡 badger
+1F43E ; fully-qualified # 🐾 paw prints
+
+# subgroup: animal-bird
+1F983 ; fully-qualified # 🦃 turkey
+1F414 ; fully-qualified # 🐔 chicken
+1F413 ; fully-qualified # 🐓 rooster
+1F423 ; fully-qualified # 🐣 hatching chick
+1F424 ; fully-qualified # 🐤 baby chick
+1F425 ; fully-qualified # 🐥 front-facing baby chick
+1F426 ; fully-qualified # 🐦 bird
+1F427 ; fully-qualified # 🐧 penguin
+1F54A FE0F ; fully-qualified # 🕊️ dove
+1F54A ; non-fully-qualified # 🕊 dove
+1F985 ; fully-qualified # 🦅 eagle
+1F986 ; fully-qualified # 🦆 duck
+1F9A2 ; fully-qualified # 🦢 swan
+1F989 ; fully-qualified # 🦉 owl
+1F99A ; fully-qualified # 🦚 peacock
+1F99C ; fully-qualified # 🦜 parrot
+
+# subgroup: animal-amphibian
+1F438 ; fully-qualified # 🐸 frog face
+
+# subgroup: animal-reptile
+1F40A ; fully-qualified # 🐊 crocodile
+1F422 ; fully-qualified # 🐢 turtle
+1F98E ; fully-qualified # 🦎 lizard
+1F40D ; fully-qualified # 🐍 snake
+1F432 ; fully-qualified # 🐲 dragon face
+1F409 ; fully-qualified # 🐉 dragon
+1F995 ; fully-qualified # 🦕 sauropod
+1F996 ; fully-qualified # 🦖 T-Rex
+
+# subgroup: animal-marine
+1F433 ; fully-qualified # 🐳 spouting whale
+1F40B ; fully-qualified # 🐋 whale
+1F42C ; fully-qualified # 🐬 dolphin
+1F41F ; fully-qualified # 🐟 fish
+1F420 ; fully-qualified # 🐠 tropical fish
+1F421 ; fully-qualified # 🐡 blowfish
+1F988 ; fully-qualified # 🦈 shark
+1F419 ; fully-qualified # 🐙 octopus
+1F41A ; fully-qualified # 🐚 spiral shell
+1F980 ; fully-qualified # 🦀 crab
+1F99E ; fully-qualified # 🦞 lobster
+1F990 ; fully-qualified # 🦐 shrimp
+1F991 ; fully-qualified # 🦑 squid
+
+# subgroup: animal-bug
+1F40C ; fully-qualified # 🐌 snail
+1F98B ; fully-qualified # 🦋 butterfly
+1F41B ; fully-qualified # 🐛 bug
+1F41C ; fully-qualified # 🐜 ant
+1F41D ; fully-qualified # 🐝 honeybee
+1F41E ; fully-qualified # 🐞 lady beetle
+1F997 ; fully-qualified # 🦗 cricket
+1F577 FE0F ; fully-qualified # 🕷️ spider
+1F577 ; non-fully-qualified # 🕷 spider
+1F578 FE0F ; fully-qualified # 🕸️ spider web
+1F578 ; non-fully-qualified # 🕸 spider web
+1F982 ; fully-qualified # 🦂 scorpion
+1F99F ; fully-qualified # 🦟 mosquito
+1F9A0 ; fully-qualified # 🦠 microbe
+
+# subgroup: plant-flower
+1F490 ; fully-qualified # 💐 bouquet
+1F338 ; fully-qualified # 🌸 cherry blossom
+1F4AE ; fully-qualified # 💮 white flower
+1F3F5 FE0F ; fully-qualified # 🏵️ rosette
+1F3F5 ; non-fully-qualified # 🏵 rosette
+1F339 ; fully-qualified # 🌹 rose
+1F940 ; fully-qualified # 🥀 wilted flower
+1F33A ; fully-qualified # 🌺 hibiscus
+1F33B ; fully-qualified # 🌻 sunflower
+1F33C ; fully-qualified # 🌼 blossom
+1F337 ; fully-qualified # 🌷 tulip
+
+# subgroup: plant-other
+1F331 ; fully-qualified # 🌱 seedling
+1F332 ; fully-qualified # 🌲 evergreen tree
+1F333 ; fully-qualified # 🌳 deciduous tree
+1F334 ; fully-qualified # 🌴 palm tree
+1F335 ; fully-qualified # 🌵 cactus
+1F33E ; fully-qualified # 🌾 sheaf of rice
+1F33F ; fully-qualified # 🌿 herb
+2618 FE0F ; fully-qualified # ☘️ shamrock
+2618 ; non-fully-qualified # ☘ shamrock
+1F340 ; fully-qualified # 🍀 four leaf clover
+1F341 ; fully-qualified # 🍁 maple leaf
+1F342 ; fully-qualified # 🍂 fallen leaf
+1F343 ; fully-qualified # 🍃 leaf fluttering in wind
+
+# Animals & Nature subtotal: 130
+# Animals & Nature subtotal: 130 w/o modifiers
+
+# group: Food & Drink
+
+# subgroup: food-fruit
+1F347 ; fully-qualified # 🍇 grapes
+1F348 ; fully-qualified # 🍈 melon
+1F349 ; fully-qualified # 🍉 watermelon
+1F34A ; fully-qualified # 🍊 tangerine
+1F34B ; fully-qualified # 🍋 lemon
+1F34C ; fully-qualified # 🍌 banana
+1F34D ; fully-qualified # 🍍 pineapple
+1F96D ; fully-qualified # 🥭 mango
+1F34E ; fully-qualified # 🍎 red apple
+1F34F ; fully-qualified # 🍏 green apple
+1F350 ; fully-qualified # 🍐 pear
+1F351 ; fully-qualified # 🍑 peach
+1F352 ; fully-qualified # 🍒 cherries
+1F353 ; fully-qualified # 🍓 strawberry
+1F95D ; fully-qualified # 🥝 kiwi fruit
+1F345 ; fully-qualified # 🍅 tomato
+1F965 ; fully-qualified # 🥥 coconut
+
+# subgroup: food-vegetable
+1F951 ; fully-qualified # 🥑 avocado
+1F346 ; fully-qualified # 🍆 eggplant
+1F954 ; fully-qualified # 🥔 potato
+1F955 ; fully-qualified # 🥕 carrot
+1F33D ; fully-qualified # 🌽 ear of corn
+1F336 FE0F ; fully-qualified # 🌶️ hot pepper
+1F336 ; non-fully-qualified # 🌶 hot pepper
+1F952 ; fully-qualified # 🥒 cucumber
+1F96C ; fully-qualified # 🥬 leafy green
+1F966 ; fully-qualified # 🥦 broccoli
+1F344 ; fully-qualified # 🍄 mushroom
+1F95C ; fully-qualified # 🥜 peanuts
+1F330 ; fully-qualified # 🌰 chestnut
+
+# subgroup: food-prepared
+1F35E ; fully-qualified # 🍞 bread
+1F950 ; fully-qualified # 🥐 croissant
+1F956 ; fully-qualified # 🥖 baguette bread
+1F968 ; fully-qualified # 🥨 pretzel
+1F96F ; fully-qualified # 🥯 bagel
+1F95E ; fully-qualified # 🥞 pancakes
+1F9C0 ; fully-qualified # 🧀 cheese wedge
+1F356 ; fully-qualified # 🍖 meat on bone
+1F357 ; fully-qualified # 🍗 poultry leg
+1F969 ; fully-qualified # 🥩 cut of meat
+1F953 ; fully-qualified # 🥓 bacon
+1F354 ; fully-qualified # 🍔 hamburger
+1F35F ; fully-qualified # 🍟 french fries
+1F355 ; fully-qualified # 🍕 pizza
+1F32D ; fully-qualified # 🌭 hot dog
+1F96A ; fully-qualified # 🥪 sandwich
+1F32E ; fully-qualified # 🌮 taco
+1F32F ; fully-qualified # 🌯 burrito
+1F959 ; fully-qualified # 🥙 stuffed flatbread
+1F95A ; fully-qualified # 🥚 egg
+1F373 ; fully-qualified # 🍳 cooking
+1F958 ; fully-qualified # 🥘 shallow pan of food
+1F372 ; fully-qualified # 🍲 pot of food
+1F963 ; fully-qualified # 🥣 bowl with spoon
+1F957 ; fully-qualified # 🥗 green salad
+1F37F ; fully-qualified # 🍿 popcorn
+1F9C2 ; fully-qualified # 🧂 salt
+1F96B ; fully-qualified # 🥫 canned food
+
+# subgroup: food-asian
+1F371 ; fully-qualified # 🍱 bento box
+1F358 ; fully-qualified # 🍘 rice cracker
+1F359 ; fully-qualified # 🍙 rice ball
+1F35A ; fully-qualified # 🍚 cooked rice
+1F35B ; fully-qualified # 🍛 curry rice
+1F35C ; fully-qualified # 🍜 steaming bowl
+1F35D ; fully-qualified # 🍝 spaghetti
+1F360 ; fully-qualified # 🍠 roasted sweet potato
+1F362 ; fully-qualified # 🍢 oden
+1F363 ; fully-qualified # 🍣 sushi
+1F364 ; fully-qualified # 🍤 fried shrimp
+1F365 ; fully-qualified # 🍥 fish cake with swirl
+1F96E ; fully-qualified # 🥮 moon cake
+1F361 ; fully-qualified # 🍡 dango
+1F95F ; fully-qualified # 🥟 dumpling
+1F960 ; fully-qualified # 🥠 fortune cookie
+1F961 ; fully-qualified # 🥡 takeout box
+
+# subgroup: food-sweet
+1F366 ; fully-qualified # 🍦 soft ice cream
+1F367 ; fully-qualified # 🍧 shaved ice
+1F368 ; fully-qualified # 🍨 ice cream
+1F369 ; fully-qualified # 🍩 doughnut
+1F36A ; fully-qualified # 🍪 cookie
+1F382 ; fully-qualified # 🎂 birthday cake
+1F370 ; fully-qualified # 🍰 shortcake
+1F9C1 ; fully-qualified # 🧁 cupcake
+1F967 ; fully-qualified # 🥧 pie
+1F36B ; fully-qualified # 🍫 chocolate bar
+1F36C ; fully-qualified # 🍬 candy
+1F36D ; fully-qualified # 🍭 lollipop
+1F36E ; fully-qualified # 🍮 custard
+1F36F ; fully-qualified # 🍯 honey pot
+
+# subgroup: drink
+1F37C ; fully-qualified # 🍼 baby bottle
+1F95B ; fully-qualified # 🥛 glass of milk
+2615 ; fully-qualified # ☕ hot beverage
+1F375 ; fully-qualified # 🍵 teacup without handle
+1F376 ; fully-qualified # 🍶 sake
+1F37E ; fully-qualified # 🍾 bottle with popping cork
+1F377 ; fully-qualified # 🍷 wine glass
+1F378 ; fully-qualified # 🍸 cocktail glass
+1F379 ; fully-qualified # 🍹 tropical drink
+1F37A ; fully-qualified # 🍺 beer mug
+1F37B ; fully-qualified # 🍻 clinking beer mugs
+1F942 ; fully-qualified # 🥂 clinking glasses
+1F943 ; fully-qualified # 🥃 tumbler glass
+1F964 ; fully-qualified # 🥤 cup with straw
+
+# subgroup: dishware
+1F962 ; fully-qualified # 🥢 chopsticks
+1F37D FE0F ; fully-qualified # 🍽️ fork and knife with plate
+1F37D ; non-fully-qualified # 🍽 fork and knife with plate
+1F374 ; fully-qualified # 🍴 fork and knife
+1F944 ; fully-qualified # 🥄 spoon
+1F52A ; fully-qualified # 🔪 kitchen knife
+1F3FA ; fully-qualified # 🏺 amphora
+
+# Food & Drink subtotal: 110
+# Food & Drink subtotal: 110 w/o modifiers
+
+# group: Travel & Places
+
+# subgroup: place-map
+1F30D ; fully-qualified # 🌍 globe showing Europe-Africa
+1F30E ; fully-qualified # 🌎 globe showing Americas
+1F30F ; fully-qualified # 🌏 globe showing Asia-Australia
+1F310 ; fully-qualified # 🌐 globe with meridians
+1F5FA FE0F ; fully-qualified # 🗺️ world map
+1F5FA ; non-fully-qualified # 🗺 world map
+1F5FE ; fully-qualified # 🗾 map of Japan
+1F9ED ; fully-qualified # 🧭 compass
+
+# subgroup: place-geographic
+1F3D4 FE0F ; fully-qualified # 🏔️ snow-capped mountain
+1F3D4 ; non-fully-qualified # 🏔 snow-capped mountain
+26F0 FE0F ; fully-qualified # ⛰️ mountain
+26F0 ; non-fully-qualified # ⛰ mountain
+1F30B ; fully-qualified # 🌋 volcano
+1F5FB ; fully-qualified # 🗻 mount fuji
+1F3D5 FE0F ; fully-qualified # 🏕️ camping
+1F3D5 ; non-fully-qualified # 🏕 camping
+1F3D6 FE0F ; fully-qualified # 🏖️ beach with umbrella
+1F3D6 ; non-fully-qualified # 🏖 beach with umbrella
+1F3DC FE0F ; fully-qualified # 🏜️ desert
+1F3DC ; non-fully-qualified # 🏜 desert
+1F3DD FE0F ; fully-qualified # 🏝️ desert island
+1F3DD ; non-fully-qualified # 🏝 desert island
+1F3DE FE0F ; fully-qualified # 🏞️ national park
+1F3DE ; non-fully-qualified # 🏞 national park
+
+# subgroup: place-building
+1F3DF FE0F ; fully-qualified # 🏟️ stadium
+1F3DF ; non-fully-qualified # 🏟 stadium
+1F3DB FE0F ; fully-qualified # 🏛️ classical building
+1F3DB ; non-fully-qualified # 🏛 classical building
+1F3D7 FE0F ; fully-qualified # 🏗️ building construction
+1F3D7 ; non-fully-qualified # 🏗 building construction
+1F9F1 ; fully-qualified # 🧱 bricks
+1F3D8 FE0F ; fully-qualified # 🏘️ houses
+1F3D8 ; non-fully-qualified # 🏘 houses
+1F3DA FE0F ; fully-qualified # 🏚️ derelict house
+1F3DA ; non-fully-qualified # 🏚 derelict house
+1F3E0 ; fully-qualified # 🏠 house
+1F3E1 ; fully-qualified # 🏡 house with garden
+1F3E2 ; fully-qualified # 🏢 office building
+1F3E3 ; fully-qualified # 🏣 Japanese post office
+1F3E4 ; fully-qualified # 🏤 post office
+1F3E5 ; fully-qualified # 🏥 hospital
+1F3E6 ; fully-qualified # 🏦 bank
+1F3E8 ; fully-qualified # 🏨 hotel
+1F3E9 ; fully-qualified # 🏩 love hotel
+1F3EA ; fully-qualified # 🏪 convenience store
+1F3EB ; fully-qualified # 🏫 school
+1F3EC ; fully-qualified # 🏬 department store
+1F3ED ; fully-qualified # 🏭 factory
+1F3EF ; fully-qualified # 🏯 Japanese castle
+1F3F0 ; fully-qualified # 🏰 castle
+1F492 ; fully-qualified # 💒 wedding
+1F5FC ; fully-qualified # 🗼 Tokyo tower
+1F5FD ; fully-qualified # 🗽 Statue of Liberty
+
+# subgroup: place-religious
+26EA ; fully-qualified # ⛪ church
+1F54C ; fully-qualified # 🕌 mosque
+1F54D ; fully-qualified # 🕍 synagogue
+26E9 FE0F ; fully-qualified # ⛩️ shinto shrine
+26E9 ; non-fully-qualified # ⛩ shinto shrine
+1F54B ; fully-qualified # 🕋 kaaba
+
+# subgroup: place-other
+26F2 ; fully-qualified # ⛲ fountain
+26FA ; fully-qualified # ⛺ tent
+1F301 ; fully-qualified # 🌁 foggy
+1F303 ; fully-qualified # 🌃 night with stars
+1F3D9 FE0F ; fully-qualified # 🏙️ cityscape
+1F3D9 ; non-fully-qualified # 🏙 cityscape
+1F304 ; fully-qualified # 🌄 sunrise over mountains
+1F305 ; fully-qualified # 🌅 sunrise
+1F306 ; fully-qualified # 🌆 cityscape at dusk
+1F307 ; fully-qualified # 🌇 sunset
+1F309 ; fully-qualified # 🌉 bridge at night
+2668 FE0F ; fully-qualified # ♨️ hot springs
+2668 ; non-fully-qualified # ♨ hot springs
+1F30C ; fully-qualified # 🌌 milky way
+1F3A0 ; fully-qualified # 🎠 carousel horse
+1F3A1 ; fully-qualified # 🎡 ferris wheel
+1F3A2 ; fully-qualified # 🎢 roller coaster
+1F488 ; fully-qualified # 💈 barber pole
+1F3AA ; fully-qualified # 🎪 circus tent
+
+# subgroup: transport-ground
+1F682 ; fully-qualified # 🚂 locomotive
+1F683 ; fully-qualified # 🚃 railway car
+1F684 ; fully-qualified # 🚄 high-speed train
+1F685 ; fully-qualified # 🚅 bullet train
+1F686 ; fully-qualified # 🚆 train
+1F687 ; fully-qualified # 🚇 metro
+1F688 ; fully-qualified # 🚈 light rail
+1F689 ; fully-qualified # 🚉 station
+1F68A ; fully-qualified # 🚊 tram
+1F69D ; fully-qualified # 🚝 monorail
+1F69E ; fully-qualified # 🚞 mountain railway
+1F68B ; fully-qualified # 🚋 tram car
+1F68C ; fully-qualified # 🚌 bus
+1F68D ; fully-qualified # 🚍 oncoming bus
+1F68E ; fully-qualified # 🚎 trolleybus
+1F690 ; fully-qualified # 🚐 minibus
+1F691 ; fully-qualified # 🚑 ambulance
+1F692 ; fully-qualified # 🚒 fire engine
+1F693 ; fully-qualified # 🚓 police car
+1F694 ; fully-qualified # 🚔 oncoming police car
+1F695 ; fully-qualified # 🚕 taxi
+1F696 ; fully-qualified # 🚖 oncoming taxi
+1F697 ; fully-qualified # 🚗 automobile
+1F698 ; fully-qualified # 🚘 oncoming automobile
+1F699 ; fully-qualified # 🚙 sport utility vehicle
+1F69A ; fully-qualified # 🚚 delivery truck
+1F69B ; fully-qualified # 🚛 articulated lorry
+1F69C ; fully-qualified # 🚜 tractor
+1F6B2 ; fully-qualified # 🚲 bicycle
+1F6F4 ; fully-qualified # 🛴 kick scooter
+1F6F9 ; fully-qualified # 🛹 skateboard
+1F6F5 ; fully-qualified # 🛵 motor scooter
+1F68F ; fully-qualified # 🚏 bus stop
+1F6E3 FE0F ; fully-qualified # 🛣️ motorway
+1F6E3 ; non-fully-qualified # 🛣 motorway
+1F6E4 FE0F ; fully-qualified # 🛤️ railway track
+1F6E4 ; non-fully-qualified # 🛤 railway track
+1F6E2 FE0F ; fully-qualified # 🛢️ oil drum
+1F6E2 ; non-fully-qualified # 🛢 oil drum
+26FD ; fully-qualified # ⛽ fuel pump
+1F6A8 ; fully-qualified # 🚨 police car light
+1F6A5 ; fully-qualified # 🚥 horizontal traffic light
+1F6A6 ; fully-qualified # 🚦 vertical traffic light
+1F6D1 ; fully-qualified # 🛑 stop sign
+1F6A7 ; fully-qualified # 🚧 construction
+
+# subgroup: transport-water
+2693 ; fully-qualified # ⚓ anchor
+26F5 ; fully-qualified # ⛵ sailboat
+1F6F6 ; fully-qualified # 🛶 canoe
+1F6A4 ; fully-qualified # 🚤 speedboat
+1F6F3 FE0F ; fully-qualified # 🛳️ passenger ship
+1F6F3 ; non-fully-qualified # 🛳 passenger ship
+26F4 FE0F ; fully-qualified # ⛴️ ferry
+26F4 ; non-fully-qualified # ⛴ ferry
+1F6E5 FE0F ; fully-qualified # 🛥️ motor boat
+1F6E5 ; non-fully-qualified # 🛥 motor boat
+1F6A2 ; fully-qualified # 🚢 ship
+
+# subgroup: transport-air
+2708 FE0F ; fully-qualified # ✈️ airplane
+2708 ; non-fully-qualified # ✈ airplane
+1F6E9 FE0F ; fully-qualified # 🛩️ small airplane
+1F6E9 ; non-fully-qualified # 🛩 small airplane
+1F6EB ; fully-qualified # 🛫 airplane departure
+1F6EC ; fully-qualified # 🛬 airplane arrival
+1F4BA ; fully-qualified # 💺 seat
+1F681 ; fully-qualified # 🚁 helicopter
+1F69F ; fully-qualified # 🚟 suspension railway
+1F6A0 ; fully-qualified # 🚠 mountain cableway
+1F6A1 ; fully-qualified # 🚡 aerial tramway
+1F6F0 FE0F ; fully-qualified # 🛰️ satellite
+1F6F0 ; non-fully-qualified # 🛰 satellite
+1F680 ; fully-qualified # 🚀 rocket
+1F6F8 ; fully-qualified # 🛸 flying saucer
+
+# subgroup: hotel
+1F6CE FE0F ; fully-qualified # 🛎️ bellhop bell
+1F6CE ; non-fully-qualified # 🛎 bellhop bell
+1F9F3 ; fully-qualified # 🧳 luggage
+
+# subgroup: time
+231B ; fully-qualified # ⌛ hourglass done
+23F3 ; fully-qualified # ⏳ hourglass not done
+231A ; fully-qualified # ⌚ watch
+23F0 ; fully-qualified # ⏰ alarm clock
+23F1 FE0F ; fully-qualified # ⏱️ stopwatch
+23F1 ; non-fully-qualified # ⏱ stopwatch
+23F2 FE0F ; fully-qualified # ⏲️ timer clock
+23F2 ; non-fully-qualified # ⏲ timer clock
+1F570 FE0F ; fully-qualified # 🕰️ mantelpiece clock
+1F570 ; non-fully-qualified # 🕰 mantelpiece clock
+1F55B ; fully-qualified # 🕛 twelve oclock
+1F567 ; fully-qualified # 🕧 twelve-thirty
+1F550 ; fully-qualified # 🕐 one oclock
+1F55C ; fully-qualified # 🕜 one-thirty
+1F551 ; fully-qualified # 🕑 two oclock
+1F55D ; fully-qualified # 🕝 two-thirty
+1F552 ; fully-qualified # 🕒 three oclock
+1F55E ; fully-qualified # 🕞 three-thirty
+1F553 ; fully-qualified # 🕓 four oclock
+1F55F ; fully-qualified # 🕟 four-thirty
+1F554 ; fully-qualified # 🕔 five oclock
+1F560 ; fully-qualified # 🕠 five-thirty
+1F555 ; fully-qualified # 🕕 six oclock
+1F561 ; fully-qualified # 🕡 six-thirty
+1F556 ; fully-qualified # 🕖 seven oclock
+1F562 ; fully-qualified # 🕢 seven-thirty
+1F557 ; fully-qualified # 🕗 eight oclock
+1F563 ; fully-qualified # 🕣 eight-thirty
+1F558 ; fully-qualified # 🕘 nine oclock
+1F564 ; fully-qualified # 🕤 nine-thirty
+1F559 ; fully-qualified # 🕙 ten oclock
+1F565 ; fully-qualified # 🕥 ten-thirty
+1F55A ; fully-qualified # 🕚 eleven oclock
+1F566 ; fully-qualified # 🕦 eleven-thirty
+
+# subgroup: sky & weather
+1F311 ; fully-qualified # 🌑 new moon
+1F312 ; fully-qualified # 🌒 waxing crescent moon
+1F313 ; fully-qualified # 🌓 first quarter moon
+1F314 ; fully-qualified # 🌔 waxing gibbous moon
+1F315 ; fully-qualified # 🌕 full moon
+1F316 ; fully-qualified # 🌖 waning gibbous moon
+1F317 ; fully-qualified # 🌗 last quarter moon
+1F318 ; fully-qualified # 🌘 waning crescent moon
+1F319 ; fully-qualified # 🌙 crescent moon
+1F31A ; fully-qualified # 🌚 new moon face
+1F31B ; fully-qualified # 🌛 first quarter moon face
+1F31C ; fully-qualified # 🌜 last quarter moon face
+1F321 FE0F ; fully-qualified # 🌡️ thermometer
+1F321 ; non-fully-qualified # 🌡 thermometer
+2600 FE0F ; fully-qualified # ☀️ sun
+2600 ; non-fully-qualified # ☀ sun
+1F31D ; fully-qualified # 🌝 full moon face
+1F31E ; fully-qualified # 🌞 sun with face
+2B50 ; fully-qualified # ⭐ star
+1F31F ; fully-qualified # 🌟 glowing star
+1F320 ; fully-qualified # 🌠 shooting star
+2601 FE0F ; fully-qualified # ☁️ cloud
+2601 ; non-fully-qualified # ☁ cloud
+26C5 ; fully-qualified # ⛅ sun behind cloud
+26C8 FE0F ; fully-qualified # ⛈️ cloud with lightning and rain
+26C8 ; non-fully-qualified # ⛈ cloud with lightning and rain
+1F324 FE0F ; fully-qualified # 🌤️ sun behind small cloud
+1F324 ; non-fully-qualified # 🌤 sun behind small cloud
+1F325 FE0F ; fully-qualified # 🌥️ sun behind large cloud
+1F325 ; non-fully-qualified # 🌥 sun behind large cloud
+1F326 FE0F ; fully-qualified # 🌦️ sun behind rain cloud
+1F326 ; non-fully-qualified # 🌦 sun behind rain cloud
+1F327 FE0F ; fully-qualified # 🌧️ cloud with rain
+1F327 ; non-fully-qualified # 🌧 cloud with rain
+1F328 FE0F ; fully-qualified # 🌨️ cloud with snow
+1F328 ; non-fully-qualified # 🌨 cloud with snow
+1F329 FE0F ; fully-qualified # 🌩️ cloud with lightning
+1F329 ; non-fully-qualified # 🌩 cloud with lightning
+1F32A FE0F ; fully-qualified # 🌪️ tornado
+1F32A ; non-fully-qualified # 🌪 tornado
+1F32B FE0F ; fully-qualified # 🌫️ fog
+1F32B ; non-fully-qualified # 🌫 fog
+1F32C FE0F ; fully-qualified # 🌬️ wind face
+1F32C ; non-fully-qualified # 🌬 wind face
+1F300 ; fully-qualified # 🌀 cyclone
+1F308 ; fully-qualified # 🌈 rainbow
+1F302 ; fully-qualified # 🌂 closed umbrella
+2602 FE0F ; fully-qualified # ☂️ umbrella
+2602 ; non-fully-qualified # ☂ umbrella
+2614 ; fully-qualified # ☔ umbrella with rain drops
+26F1 FE0F ; fully-qualified # ⛱️ umbrella on ground
+26F1 ; non-fully-qualified # ⛱ umbrella on ground
+26A1 ; fully-qualified # ⚡ high voltage
+2744 FE0F ; fully-qualified # ❄️ snowflake
+2744 ; non-fully-qualified # ❄ snowflake
+2603 FE0F ; fully-qualified # ☃️ snowman
+2603 ; non-fully-qualified # ☃ snowman
+26C4 ; fully-qualified # ⛄ snowman without snow
+2604 FE0F ; fully-qualified # ☄️ comet
+2604 ; non-fully-qualified # ☄ comet
+1F525 ; fully-qualified # 🔥 fire
+1F4A7 ; fully-qualified # 💧 droplet
+1F30A ; fully-qualified # 🌊 water wave
+
+# Travel & Places subtotal: 249
+# Travel & Places subtotal: 249 w/o modifiers
+
+# group: Activities
+
+# subgroup: event
+1F383 ; fully-qualified # 🎃 jack-o-lantern
+1F384 ; fully-qualified # 🎄 Christmas tree
+1F386 ; fully-qualified # 🎆 fireworks
+1F387 ; fully-qualified # 🎇 sparkler
+1F9E8 ; fully-qualified # 🧨 firecracker
+2728 ; fully-qualified # ✨ sparkles
+1F388 ; fully-qualified # 🎈 balloon
+1F389 ; fully-qualified # 🎉 party popper
+1F38A ; fully-qualified # 🎊 confetti ball
+1F38B ; fully-qualified # 🎋 tanabata tree
+1F38D ; fully-qualified # 🎍 pine decoration
+1F38E ; fully-qualified # 🎎 Japanese dolls
+1F38F ; fully-qualified # 🎏 carp streamer
+1F390 ; fully-qualified # 🎐 wind chime
+1F391 ; fully-qualified # 🎑 moon viewing ceremony
+1F9E7 ; fully-qualified # 🧧 red envelope
+1F380 ; fully-qualified # 🎀 ribbon
+1F381 ; fully-qualified # 🎁 wrapped gift
+1F397 FE0F ; fully-qualified # 🎗️ reminder ribbon
+1F397 ; non-fully-qualified # 🎗 reminder ribbon
+1F39F FE0F ; fully-qualified # 🎟️ admission tickets
+1F39F ; non-fully-qualified # 🎟 admission tickets
+1F3AB ; fully-qualified # 🎫 ticket
+
+# subgroup: award-medal
+1F396 FE0F ; fully-qualified # 🎖️ military medal
+1F396 ; non-fully-qualified # 🎖 military medal
+1F3C6 ; fully-qualified # 🏆 trophy
+1F3C5 ; fully-qualified # 🏅 sports medal
+1F947 ; fully-qualified # 🥇 1st place medal
+1F948 ; fully-qualified # 🥈 2nd place medal
+1F949 ; fully-qualified # 🥉 3rd place medal
+
+# subgroup: sport
+26BD ; fully-qualified # ⚽ soccer ball
+26BE ; fully-qualified # ⚾ baseball
+1F94E ; fully-qualified # 🥎 softball
+1F3C0 ; fully-qualified # 🏀 basketball
+1F3D0 ; fully-qualified # 🏐 volleyball
+1F3C8 ; fully-qualified # 🏈 american football
+1F3C9 ; fully-qualified # 🏉 rugby football
+1F3BE ; fully-qualified # 🎾 tennis
+1F94F ; fully-qualified # 🥏 flying disc
+1F3B3 ; fully-qualified # 🎳 bowling
+1F3CF ; fully-qualified # 🏏 cricket game
+1F3D1 ; fully-qualified # 🏑 field hockey
+1F3D2 ; fully-qualified # 🏒 ice hockey
+1F94D ; fully-qualified # 🥍 lacrosse
+1F3D3 ; fully-qualified # 🏓 ping pong
+1F3F8 ; fully-qualified # 🏸 badminton
+1F94A ; fully-qualified # 🥊 boxing glove
+1F94B ; fully-qualified # 🥋 martial arts uniform
+1F945 ; fully-qualified # 🥅 goal net
+26F3 ; fully-qualified # ⛳ flag in hole
+26F8 FE0F ; fully-qualified # ⛸️ ice skate
+26F8 ; non-fully-qualified # ⛸ ice skate
+1F3A3 ; fully-qualified # 🎣 fishing pole
+1F3BD ; fully-qualified # 🎽 running shirt
+1F3BF ; fully-qualified # 🎿 skis
+1F6F7 ; fully-qualified # 🛷 sled
+1F94C ; fully-qualified # 🥌 curling stone
+
+# subgroup: game
+1F3AF ; fully-qualified # 🎯 direct hit
+1F3B1 ; fully-qualified # 🎱 pool 8 ball
+1F52E ; fully-qualified # 🔮 crystal ball
+1F9FF ; fully-qualified # 🧿 nazar amulet
+1F3AE ; fully-qualified # 🎮 video game
+1F579 FE0F ; fully-qualified # 🕹️ joystick
+1F579 ; non-fully-qualified # 🕹 joystick
+1F3B0 ; fully-qualified # 🎰 slot machine
+1F3B2 ; fully-qualified # 🎲 game die
+1F9E9 ; fully-qualified # 🧩 jigsaw
+1F9F8 ; fully-qualified # 🧸 teddy bear
+2660 FE0F ; fully-qualified # ♠️ spade suit
+2660 ; non-fully-qualified # ♠ spade suit
+2665 FE0F ; fully-qualified # ♥️ heart suit
+2665 ; non-fully-qualified # ♥ heart suit
+2666 FE0F ; fully-qualified # ♦️ diamond suit
+2666 ; non-fully-qualified # ♦ diamond suit
+2663 FE0F ; fully-qualified # ♣️ club suit
+2663 ; non-fully-qualified # ♣ club suit
+265F FE0F ; fully-qualified # ♟️ chess pawn
+265F ; non-fully-qualified # ♟ chess pawn
+1F0CF ; fully-qualified # 🃏 joker
+1F004 ; fully-qualified # 🀄 mahjong red dragon
+1F3B4 ; fully-qualified # 🎴 flower playing cards
+
+# subgroup: arts & crafts
+1F3AD ; fully-qualified # 🎭 performing arts
+1F5BC FE0F ; fully-qualified # 🖼️ framed picture
+1F5BC ; non-fully-qualified # 🖼 framed picture
+1F3A8 ; fully-qualified # 🎨 artist palette
+1F9F5 ; fully-qualified # 🧵 thread
+1F9F6 ; fully-qualified # 🧶 yarn
+
+# Activities subtotal: 87
+# Activities subtotal: 87 w/o modifiers
+
+# group: Objects
+
+# subgroup: sound
+1F507 ; fully-qualified # 🔇 muted speaker
+1F508 ; fully-qualified # 🔈 speaker low volume
+1F509 ; fully-qualified # 🔉 speaker medium volume
+1F50A ; fully-qualified # 🔊 speaker high volume
+1F4E2 ; fully-qualified # 📢 loudspeaker
+1F4E3 ; fully-qualified # 📣 megaphone
+1F4EF ; fully-qualified # 📯 postal horn
+1F514 ; fully-qualified # 🔔 bell
+1F515 ; fully-qualified # 🔕 bell with slash
+
+# subgroup: music
+1F3BC ; fully-qualified # 🎼 musical score
+1F3B5 ; fully-qualified # 🎵 musical note
+1F3B6 ; fully-qualified # 🎶 musical notes
+1F399 FE0F ; fully-qualified # 🎙️ studio microphone
+1F399 ; non-fully-qualified # 🎙 studio microphone
+1F39A FE0F ; fully-qualified # 🎚️ level slider
+1F39A ; non-fully-qualified # 🎚 level slider
+1F39B FE0F ; fully-qualified # 🎛️ control knobs
+1F39B ; non-fully-qualified # 🎛 control knobs
+1F3A4 ; fully-qualified # 🎤 microphone
+1F3A7 ; fully-qualified # 🎧 headphone
+1F4FB ; fully-qualified # 📻 radio
+
+# subgroup: musical-instrument
+1F3B7 ; fully-qualified # 🎷 saxophone
+1F3B8 ; fully-qualified # 🎸 guitar
+1F3B9 ; fully-qualified # 🎹 musical keyboard
+1F3BA ; fully-qualified # 🎺 trumpet
+1F3BB ; fully-qualified # 🎻 violin
+1F941 ; fully-qualified # 🥁 drum
+
+# subgroup: phone
+1F4F1 ; fully-qualified # 📱 mobile phone
+1F4F2 ; fully-qualified # 📲 mobile phone with arrow
+260E FE0F ; fully-qualified # ☎️ telephone
+260E ; non-fully-qualified # ☎ telephone
+1F4DE ; fully-qualified # 📞 telephone receiver
+1F4DF ; fully-qualified # 📟 pager
+1F4E0 ; fully-qualified # 📠 fax machine
+
+# subgroup: computer
+1F50B ; fully-qualified # 🔋 battery
+1F50C ; fully-qualified # 🔌 electric plug
+1F4BB ; fully-qualified # 💻 laptop computer
+1F5A5 FE0F ; fully-qualified # 🖥️ desktop computer
+1F5A5 ; non-fully-qualified # 🖥 desktop computer
+1F5A8 FE0F ; fully-qualified # 🖨️ printer
+1F5A8 ; non-fully-qualified # 🖨 printer
+2328 FE0F ; fully-qualified # ⌨️ keyboard
+2328 ; non-fully-qualified # ⌨ keyboard
+1F5B1 FE0F ; fully-qualified # 🖱️ computer mouse
+1F5B1 ; non-fully-qualified # 🖱 computer mouse
+1F5B2 FE0F ; fully-qualified # 🖲️ trackball
+1F5B2 ; non-fully-qualified # 🖲 trackball
+1F4BD ; fully-qualified # 💽 computer disk
+1F4BE ; fully-qualified # 💾 floppy disk
+1F4BF ; fully-qualified # 💿 optical disk
+1F4C0 ; fully-qualified # 📀 dvd
+1F9EE ; fully-qualified # 🧮 abacus
+
+# subgroup: light & video
+1F3A5 ; fully-qualified # 🎥 movie camera
+1F39E FE0F ; fully-qualified # 🎞️ film frames
+1F39E ; non-fully-qualified # 🎞 film frames
+1F4FD FE0F ; fully-qualified # 📽️ film projector
+1F4FD ; non-fully-qualified # 📽 film projector
+1F3AC ; fully-qualified # 🎬 clapper board
+1F4FA ; fully-qualified # 📺 television
+1F4F7 ; fully-qualified # 📷 camera
+1F4F8 ; fully-qualified # 📸 camera with flash
+1F4F9 ; fully-qualified # 📹 video camera
+1F4FC ; fully-qualified # 📼 videocassette
+1F50D ; fully-qualified # 🔍 magnifying glass tilted left
+1F50E ; fully-qualified # 🔎 magnifying glass tilted right
+1F56F FE0F ; fully-qualified # 🕯️ candle
+1F56F ; non-fully-qualified # 🕯 candle
+1F4A1 ; fully-qualified # 💡 light bulb
+1F526 ; fully-qualified # 🔦 flashlight
+1F3EE ; fully-qualified # 🏮 red paper lantern
+
+# subgroup: book-paper
+1F4D4 ; fully-qualified # 📔 notebook with decorative cover
+1F4D5 ; fully-qualified # 📕 closed book
+1F4D6 ; fully-qualified # 📖 open book
+1F4D7 ; fully-qualified # 📗 green book
+1F4D8 ; fully-qualified # 📘 blue book
+1F4D9 ; fully-qualified # 📙 orange book
+1F4DA ; fully-qualified # 📚 books
+1F4D3 ; fully-qualified # 📓 notebook
+1F4D2 ; fully-qualified # 📒 ledger
+1F4C3 ; fully-qualified # 📃 page with curl
+1F4DC ; fully-qualified # 📜 scroll
+1F4C4 ; fully-qualified # 📄 page facing up
+1F4F0 ; fully-qualified # 📰 newspaper
+1F5DE FE0F ; fully-qualified # 🗞️ rolled-up newspaper
+1F5DE ; non-fully-qualified # 🗞 rolled-up newspaper
+1F4D1 ; fully-qualified # 📑 bookmark tabs
+1F516 ; fully-qualified # 🔖 bookmark
+1F3F7 FE0F ; fully-qualified # 🏷️ label
+1F3F7 ; non-fully-qualified # 🏷 label
+
+# subgroup: money
+1F4B0 ; fully-qualified # 💰 money bag
+1F4B4 ; fully-qualified # 💴 yen banknote
+1F4B5 ; fully-qualified # 💵 dollar banknote
+1F4B6 ; fully-qualified # 💶 euro banknote
+1F4B7 ; fully-qualified # 💷 pound banknote
+1F4B8 ; fully-qualified # 💸 money with wings
+1F4B3 ; fully-qualified # 💳 credit card
+1F9FE ; fully-qualified # 🧾 receipt
+1F4B9 ; fully-qualified # 💹 chart increasing with yen
+1F4B1 ; fully-qualified # 💱 currency exchange
+1F4B2 ; fully-qualified # 💲 heavy dollar sign
+
+# subgroup: mail
+2709 FE0F ; fully-qualified # ✉️ envelope
+2709 ; non-fully-qualified # ✉ envelope
+1F4E7 ; fully-qualified # 📧 e-mail
+1F4E8 ; fully-qualified # 📨 incoming envelope
+1F4E9 ; fully-qualified # 📩 envelope with arrow
+1F4E4 ; fully-qualified # 📤 outbox tray
+1F4E5 ; fully-qualified # 📥 inbox tray
+1F4E6 ; fully-qualified # 📦 package
+1F4EB ; fully-qualified # 📫 closed mailbox with raised flag
+1F4EA ; fully-qualified # 📪 closed mailbox with lowered flag
+1F4EC ; fully-qualified # 📬 open mailbox with raised flag
+1F4ED ; fully-qualified # 📭 open mailbox with lowered flag
+1F4EE ; fully-qualified # 📮 postbox
+1F5F3 FE0F ; fully-qualified # 🗳️ ballot box with ballot
+1F5F3 ; non-fully-qualified # 🗳 ballot box with ballot
+
+# subgroup: writing
+270F FE0F ; fully-qualified # ✏️ pencil
+270F ; non-fully-qualified # ✏ pencil
+2712 FE0F ; fully-qualified # ✒️ black nib
+2712 ; non-fully-qualified # ✒ black nib
+1F58B FE0F ; fully-qualified # 🖋️ fountain pen
+1F58B ; non-fully-qualified # 🖋 fountain pen
+1F58A FE0F ; fully-qualified # 🖊️ pen
+1F58A ; non-fully-qualified # 🖊 pen
+1F58C FE0F ; fully-qualified # 🖌️ paintbrush
+1F58C ; non-fully-qualified # 🖌 paintbrush
+1F58D FE0F ; fully-qualified # 🖍️ crayon
+1F58D ; non-fully-qualified # 🖍 crayon
+1F4DD ; fully-qualified # 📝 memo
+
+# subgroup: office
+1F4BC ; fully-qualified # 💼 briefcase
+1F4C1 ; fully-qualified # 📁 file folder
+1F4C2 ; fully-qualified # 📂 open file folder
+1F5C2 FE0F ; fully-qualified # 🗂️ card index dividers
+1F5C2 ; non-fully-qualified # 🗂 card index dividers
+1F4C5 ; fully-qualified # 📅 calendar
+1F4C6 ; fully-qualified # 📆 tear-off calendar
+1F5D2 FE0F ; fully-qualified # 🗒️ spiral notepad
+1F5D2 ; non-fully-qualified # 🗒 spiral notepad
+1F5D3 FE0F ; fully-qualified # 🗓️ spiral calendar
+1F5D3 ; non-fully-qualified # 🗓 spiral calendar
+1F4C7 ; fully-qualified # 📇 card index
+1F4C8 ; fully-qualified # 📈 chart increasing
+1F4C9 ; fully-qualified # 📉 chart decreasing
+1F4CA ; fully-qualified # 📊 bar chart
+1F4CB ; fully-qualified # 📋 clipboard
+1F4CC ; fully-qualified # 📌 pushpin
+1F4CD ; fully-qualified # 📍 round pushpin
+1F4CE ; fully-qualified # 📎 paperclip
+1F587 FE0F ; fully-qualified # 🖇️ linked paperclips
+1F587 ; non-fully-qualified # 🖇 linked paperclips
+1F4CF ; fully-qualified # 📏 straight ruler
+1F4D0 ; fully-qualified # 📐 triangular ruler
+2702 FE0F ; fully-qualified # ✂️ scissors
+2702 ; non-fully-qualified # ✂ scissors
+1F5C3 FE0F ; fully-qualified # 🗃️ card file box
+1F5C3 ; non-fully-qualified # 🗃 card file box
+1F5C4 FE0F ; fully-qualified # 🗄️ file cabinet
+1F5C4 ; non-fully-qualified # 🗄 file cabinet
+1F5D1 FE0F ; fully-qualified # 🗑️ wastebasket
+1F5D1 ; non-fully-qualified # 🗑 wastebasket
+
+# subgroup: lock
+1F512 ; fully-qualified # 🔒 locked
+1F513 ; fully-qualified # 🔓 unlocked
+1F50F ; fully-qualified # 🔏 locked with pen
+1F510 ; fully-qualified # 🔐 locked with key
+1F511 ; fully-qualified # 🔑 key
+1F5DD FE0F ; fully-qualified # 🗝️ old key
+1F5DD ; non-fully-qualified # 🗝 old key
+
+# subgroup: tool
+1F528 ; fully-qualified # 🔨 hammer
+26CF FE0F ; fully-qualified # ⛏️ pick
+26CF ; non-fully-qualified # ⛏ pick
+2692 FE0F ; fully-qualified # ⚒️ hammer and pick
+2692 ; non-fully-qualified # ⚒ hammer and pick
+1F6E0 FE0F ; fully-qualified # 🛠️ hammer and wrench
+1F6E0 ; non-fully-qualified # 🛠 hammer and wrench
+1F5E1 FE0F ; fully-qualified # 🗡️ dagger
+1F5E1 ; non-fully-qualified # 🗡 dagger
+2694 FE0F ; fully-qualified # ⚔️ crossed swords
+2694 ; non-fully-qualified # ⚔ crossed swords
+1F52B ; fully-qualified # 🔫 pistol
+1F3F9 ; fully-qualified # 🏹 bow and arrow
+1F6E1 FE0F ; fully-qualified # 🛡️ shield
+1F6E1 ; non-fully-qualified # 🛡 shield
+1F527 ; fully-qualified # 🔧 wrench
+1F529 ; fully-qualified # 🔩 nut and bolt
+2699 FE0F ; fully-qualified # ⚙️ gear
+2699 ; non-fully-qualified # ⚙ gear
+1F5DC FE0F ; fully-qualified # 🗜️ clamp
+1F5DC ; non-fully-qualified # 🗜 clamp
+2696 FE0F ; fully-qualified # ⚖️ balance scale
+2696 ; non-fully-qualified # ⚖ balance scale
+1F517 ; fully-qualified # 🔗 link
+26D3 FE0F ; fully-qualified # ⛓️ chains
+26D3 ; non-fully-qualified # ⛓ chains
+1F9F0 ; fully-qualified # 🧰 toolbox
+1F9F2 ; fully-qualified # 🧲 magnet
+
+# subgroup: science
+2697 FE0F ; fully-qualified # ⚗️ alembic
+2697 ; non-fully-qualified # ⚗ alembic
+1F9EA ; fully-qualified # 🧪 test tube
+1F9EB ; fully-qualified # 🧫 petri dish
+1F9EC ; fully-qualified # 🧬 dna
+1F52C ; fully-qualified # 🔬 microscope
+1F52D ; fully-qualified # 🔭 telescope
+1F4E1 ; fully-qualified # 📡 satellite antenna
+
+# subgroup: medical
+1F489 ; fully-qualified # 💉 syringe
+1F48A ; fully-qualified # 💊 pill
+
+# subgroup: household
+1F6AA ; fully-qualified # 🚪 door
+1F6CF FE0F ; fully-qualified # 🛏️ bed
+1F6CF ; non-fully-qualified # 🛏 bed
+1F6CB FE0F ; fully-qualified # 🛋️ couch and lamp
+1F6CB ; non-fully-qualified # 🛋 couch and lamp
+1F6BD ; fully-qualified # 🚽 toilet
+1F6BF ; fully-qualified # 🚿 shower
+1F6C1 ; fully-qualified # 🛁 bathtub
+1F9F4 ; fully-qualified # 🧴 lotion bottle
+1F9F7 ; fully-qualified # 🧷 safety pin
+1F9F9 ; fully-qualified # 🧹 broom
+1F9FA ; fully-qualified # 🧺 basket
+1F9FB ; fully-qualified # 🧻 roll of paper
+1F9FC ; fully-qualified # 🧼 soap
+1F9FD ; fully-qualified # 🧽 sponge
+1F9EF ; fully-qualified # 🧯 fire extinguisher
+1F6D2 ; fully-qualified # 🛒 shopping cart
+
+# subgroup: other-object
+1F6AC ; fully-qualified # 🚬 cigarette
+26B0 FE0F ; fully-qualified # ⚰️ coffin
+26B0 ; non-fully-qualified # ⚰ coffin
+26B1 FE0F ; fully-qualified # ⚱️ funeral urn
+26B1 ; non-fully-qualified # ⚱ funeral urn
+1F5FF ; fully-qualified # 🗿 moai
+
+# Objects subtotal: 227
+# Objects subtotal: 227 w/o modifiers
+
+# group: Symbols
+
+# subgroup: transport-sign
+1F3E7 ; fully-qualified # 🏧 ATM sign
+1F6AE ; fully-qualified # 🚮 litter in bin sign
+1F6B0 ; fully-qualified # 🚰 potable water
+267F ; fully-qualified # ♿ wheelchair symbol
+1F6B9 ; fully-qualified # 🚹 mens room
+1F6BA ; fully-qualified # 🚺 womens room
+1F6BB ; fully-qualified # 🚻 restroom
+1F6BC ; fully-qualified # 🚼 baby symbol
+1F6BE ; fully-qualified # 🚾 water closet
+1F6C2 ; fully-qualified # 🛂 passport control
+1F6C3 ; fully-qualified # 🛃 customs
+1F6C4 ; fully-qualified # 🛄 baggage claim
+1F6C5 ; fully-qualified # 🛅 left luggage
+
+# subgroup: warning
+26A0 FE0F ; fully-qualified # ⚠️ warning
+26A0 ; non-fully-qualified # ⚠ warning
+1F6B8 ; fully-qualified # 🚸 children crossing
+26D4 ; fully-qualified # ⛔ no entry
+1F6AB ; fully-qualified # 🚫 prohibited
+1F6B3 ; fully-qualified # 🚳 no bicycles
+1F6AD ; fully-qualified # 🚭 no smoking
+1F6AF ; fully-qualified # 🚯 no littering
+1F6B1 ; fully-qualified # 🚱 non-potable water
+1F6B7 ; fully-qualified # 🚷 no pedestrians
+1F4F5 ; fully-qualified # 📵 no mobile phones
+1F51E ; fully-qualified # 🔞 no one under eighteen
+2622 FE0F ; fully-qualified # ☢️ radioactive
+2622 ; non-fully-qualified # ☢ radioactive
+2623 FE0F ; fully-qualified # ☣️ biohazard
+2623 ; non-fully-qualified # ☣ biohazard
+
+# subgroup: arrow
+2B06 FE0F ; fully-qualified # ⬆️ up arrow
+2B06 ; non-fully-qualified # ⬆ up arrow
+2197 FE0F ; fully-qualified # ↗️ up-right arrow
+2197 ; non-fully-qualified # ↗ up-right arrow
+27A1 FE0F ; fully-qualified # ➡️ right arrow
+27A1 ; non-fully-qualified # ➡ right arrow
+2198 FE0F ; fully-qualified # ↘️ down-right arrow
+2198 ; non-fully-qualified # ↘ down-right arrow
+2B07 FE0F ; fully-qualified # ⬇️ down arrow
+2B07 ; non-fully-qualified # ⬇ down arrow
+2199 FE0F ; fully-qualified # ↙️ down-left arrow
+2199 ; non-fully-qualified # ↙ down-left arrow
+2B05 FE0F ; fully-qualified # ⬅️ left arrow
+2B05 ; non-fully-qualified # ⬅ left arrow
+2196 FE0F ; fully-qualified # ↖️ up-left arrow
+2196 ; non-fully-qualified # ↖ up-left arrow
+2195 FE0F ; fully-qualified # ↕️ up-down arrow
+2195 ; non-fully-qualified # ↕ up-down arrow
+2194 FE0F ; fully-qualified # ↔️ left-right arrow
+2194 ; non-fully-qualified # ↔ left-right arrow
+21A9 FE0F ; fully-qualified # ↩️ right arrow curving left
+21A9 ; non-fully-qualified # ↩ right arrow curving left
+21AA FE0F ; fully-qualified # ↪️ left arrow curving right
+21AA ; non-fully-qualified # ↪ left arrow curving right
+2934 FE0F ; fully-qualified # ⤴️ right arrow curving up
+2934 ; non-fully-qualified # ⤴ right arrow curving up
+2935 FE0F ; fully-qualified # ⤵️ right arrow curving down
+2935 ; non-fully-qualified # ⤵ right arrow curving down
+1F503 ; fully-qualified # 🔃 clockwise vertical arrows
+1F504 ; fully-qualified # 🔄 counterclockwise arrows button
+1F519 ; fully-qualified # 🔙 BACK arrow
+1F51A ; fully-qualified # 🔚 END arrow
+1F51B ; fully-qualified # 🔛 ON! arrow
+1F51C ; fully-qualified # 🔜 SOON arrow
+1F51D ; fully-qualified # 🔝 TOP arrow
+
+# subgroup: religion
+1F6D0 ; fully-qualified # 🛐 place of worship
+269B FE0F ; fully-qualified # ⚛️ atom symbol
+269B ; non-fully-qualified # ⚛ atom symbol
+1F549 FE0F ; fully-qualified # 🕉️ om
+1F549 ; non-fully-qualified # 🕉 om
+2721 FE0F ; fully-qualified # ✡️ star of David
+2721 ; non-fully-qualified # ✡ star of David
+2638 FE0F ; fully-qualified # ☸️ wheel of dharma
+2638 ; non-fully-qualified # ☸ wheel of dharma
+262F FE0F ; fully-qualified # ☯️ yin yang
+262F ; non-fully-qualified # ☯ yin yang
+271D FE0F ; fully-qualified # ✝️ latin cross
+271D ; non-fully-qualified # ✝ latin cross
+2626 FE0F ; fully-qualified # ☦️ orthodox cross
+2626 ; non-fully-qualified # ☦ orthodox cross
+262A FE0F ; fully-qualified # ☪️ star and crescent
+262A ; non-fully-qualified # ☪ star and crescent
+262E FE0F ; fully-qualified # ☮️ peace symbol
+262E ; non-fully-qualified # ☮ peace symbol
+1F54E ; fully-qualified # 🕎 menorah
+1F52F ; fully-qualified # 🔯 dotted six-pointed star
+
+# subgroup: zodiac
+2648 ; fully-qualified # ♈ Aries
+2649 ; fully-qualified # ♉ Taurus
+264A ; fully-qualified # ♊ Gemini
+264B ; fully-qualified # ♋ Cancer
+264C ; fully-qualified # ♌ Leo
+264D ; fully-qualified # ♍ Virgo
+264E ; fully-qualified # ♎ Libra
+264F ; fully-qualified # ♏ Scorpio
+2650 ; fully-qualified # ♐ Sagittarius
+2651 ; fully-qualified # ♑ Capricorn
+2652 ; fully-qualified # ♒ Aquarius
+2653 ; fully-qualified # ♓ Pisces
+26CE ; fully-qualified # ⛎ Ophiuchus
+
+# subgroup: av-symbol
+1F500 ; fully-qualified # 🔀 shuffle tracks button
+1F501 ; fully-qualified # 🔁 repeat button
+1F502 ; fully-qualified # 🔂 repeat single button
+25B6 FE0F ; fully-qualified # ▶️ play button
+25B6 ; non-fully-qualified # ▶ play button
+23E9 ; fully-qualified # ⏩ fast-forward button
+23ED FE0F ; fully-qualified # ⏭️ next track button
+23ED ; non-fully-qualified # ⏭ next track button
+23EF FE0F ; fully-qualified # ⏯️ play or pause button
+23EF ; non-fully-qualified # ⏯ play or pause button
+25C0 FE0F ; fully-qualified # ◀️ reverse button
+25C0 ; non-fully-qualified # ◀ reverse button
+23EA ; fully-qualified # ⏪ fast reverse button
+23EE FE0F ; fully-qualified # ⏮️ last track button
+23EE ; non-fully-qualified # ⏮ last track button
+1F53C ; fully-qualified # 🔼 upwards button
+23EB ; fully-qualified # ⏫ fast up button
+1F53D ; fully-qualified # 🔽 downwards button
+23EC ; fully-qualified # ⏬ fast down button
+23F8 FE0F ; fully-qualified # ⏸️ pause button
+23F8 ; non-fully-qualified # ⏸ pause button
+23F9 FE0F ; fully-qualified # ⏹️ stop button
+23F9 ; non-fully-qualified # ⏹ stop button
+23FA FE0F ; fully-qualified # ⏺️ record button
+23FA ; non-fully-qualified # ⏺ record button
+23CF FE0F ; fully-qualified # ⏏️ eject button
+23CF ; non-fully-qualified # ⏏ eject button
+1F3A6 ; fully-qualified # 🎦 cinema
+1F505 ; fully-qualified # 🔅 dim button
+1F506 ; fully-qualified # 🔆 bright button
+1F4F6 ; fully-qualified # 📶 antenna bars
+1F4F3 ; fully-qualified # 📳 vibration mode
+1F4F4 ; fully-qualified # 📴 mobile phone off
+
+# subgroup: other-symbol
+2640 FE0F ; fully-qualified # ♀️ female sign
+2640 ; non-fully-qualified # ♀ female sign
+2642 FE0F ; fully-qualified # ♂️ male sign
+2642 ; non-fully-qualified # ♂ male sign
+2695 FE0F ; fully-qualified # ⚕️ medical symbol
+2695 ; non-fully-qualified # ⚕ medical symbol
+267E FE0F ; fully-qualified # ♾️ infinity
+267E ; non-fully-qualified # ♾ infinity
+267B FE0F ; fully-qualified # ♻️ recycling symbol
+267B ; non-fully-qualified # ♻ recycling symbol
+269C FE0F ; fully-qualified # ⚜️ fleur-de-lis
+269C ; non-fully-qualified # ⚜ fleur-de-lis
+1F531 ; fully-qualified # 🔱 trident emblem
+1F4DB ; fully-qualified # 📛 name badge
+1F530 ; fully-qualified # 🔰 Japanese symbol for beginner
+2B55 ; fully-qualified # ⭕ heavy large circle
+2705 ; fully-qualified # ✅ white heavy check mark
+2611 FE0F ; fully-qualified # ☑️ ballot box with check
+2611 ; non-fully-qualified # ☑ ballot box with check
+2714 FE0F ; fully-qualified # ✔️ heavy check mark
+2714 ; non-fully-qualified # ✔ heavy check mark
+2716 FE0F ; fully-qualified # ✖️ heavy multiplication x
+2716 ; non-fully-qualified # ✖ heavy multiplication x
+274C ; fully-qualified # ❌ cross mark
+274E ; fully-qualified # ❎ cross mark button
+2795 ; fully-qualified # heavy plus sign
+2796 ; fully-qualified # heavy minus sign
+2797 ; fully-qualified # ➗ heavy division sign
+27B0 ; fully-qualified # ➰ curly loop
+27BF ; fully-qualified # ➿ double curly loop
+303D FE0F ; fully-qualified # 〽️ part alternation mark
+303D ; non-fully-qualified # 〽 part alternation mark
+2733 FE0F ; fully-qualified # ✳️ eight-spoked asterisk
+2733 ; non-fully-qualified # ✳ eight-spoked asterisk
+2734 FE0F ; fully-qualified # ✴️ eight-pointed star
+2734 ; non-fully-qualified # ✴ eight-pointed star
+2747 FE0F ; fully-qualified # ❇️ sparkle
+2747 ; non-fully-qualified # ❇ sparkle
+203C FE0F ; fully-qualified # ‼️ double exclamation mark
+203C ; non-fully-qualified # ‼ double exclamation mark
+2049 FE0F ; fully-qualified # ⁉️ exclamation question mark
+2049 ; non-fully-qualified # ⁉ exclamation question mark
+2753 ; fully-qualified # ❓ question mark
+2754 ; fully-qualified # ❔ white question mark
+2755 ; fully-qualified # ❕ white exclamation mark
+2757 ; fully-qualified # ❗ exclamation mark
+3030 FE0F ; fully-qualified # 〰️ wavy dash
+3030 ; non-fully-qualified # 〰 wavy dash
+00A9 FE0F ; fully-qualified # ©️ copyright
+00A9 ; non-fully-qualified # © copyright
+00AE FE0F ; fully-qualified # ®️ registered
+00AE ; non-fully-qualified # ® registered
+2122 FE0F ; fully-qualified # ™️ trade mark
+2122 ; non-fully-qualified # ™ trade mark
+
+# subgroup: keycap
+0023 FE0F 20E3 ; fully-qualified # #️⃣ keycap: #
+0023 20E3 ; non-fully-qualified # #⃣ keycap: #
+002A FE0F 20E3 ; fully-qualified # *️⃣ keycap: *
+002A 20E3 ; non-fully-qualified # *⃣ keycap: *
+0030 FE0F 20E3 ; fully-qualified # 0⃣ keycap: 0
+0030 20E3 ; non-fully-qualified # 0⃣ keycap: 0
+0031 FE0F 20E3 ; fully-qualified # 1⃣ keycap: 1
+0031 20E3 ; non-fully-qualified # 1⃣ keycap: 1
+0032 FE0F 20E3 ; fully-qualified # 2⃣ keycap: 2
+0032 20E3 ; non-fully-qualified # 2⃣ keycap: 2
+0033 FE0F 20E3 ; fully-qualified # 3⃣ keycap: 3
+0033 20E3 ; non-fully-qualified # 3⃣ keycap: 3
+0034 FE0F 20E3 ; fully-qualified # 4⃣ keycap: 4
+0034 20E3 ; non-fully-qualified # 4⃣ keycap: 4
+0035 FE0F 20E3 ; fully-qualified # 5⃣ keycap: 5
+0035 20E3 ; non-fully-qualified # 5⃣ keycap: 5
+0036 FE0F 20E3 ; fully-qualified # 6⃣ keycap: 6
+0036 20E3 ; non-fully-qualified # 6⃣ keycap: 6
+0037 FE0F 20E3 ; fully-qualified # 7⃣ keycap: 7
+0037 20E3 ; non-fully-qualified # 7⃣ keycap: 7
+0038 FE0F 20E3 ; fully-qualified # 8⃣ keycap: 8
+0038 20E3 ; non-fully-qualified # 8⃣ keycap: 8
+0039 FE0F 20E3 ; fully-qualified # 9⃣ keycap: 9
+0039 20E3 ; non-fully-qualified # 9⃣ keycap: 9
+1F51F ; fully-qualified # 🔟 keycap: 10
+
+# subgroup: alphanum
+1F4AF ; fully-qualified # 💯 hundred points
+1F520 ; fully-qualified # 🔠 input latin uppercase
+1F521 ; fully-qualified # 🔡 input latin lowercase
+1F522 ; fully-qualified # 🔢 input numbers
+1F523 ; fully-qualified # 🔣 input symbols
+1F524 ; fully-qualified # 🔤 input latin letters
+1F170 FE0F ; fully-qualified # 🅰️ A button (blood type)
+1F170 ; non-fully-qualified # 🅰 A button (blood type)
+1F18E ; fully-qualified # 🆎 AB button (blood type)
+1F171 FE0F ; fully-qualified # 🅱️ B button (blood type)
+1F171 ; non-fully-qualified # 🅱 B button (blood type)
+1F191 ; fully-qualified # 🆑 CL button
+1F192 ; fully-qualified # 🆒 COOL button
+1F193 ; fully-qualified # 🆓 FREE button
+2139 FE0F ; fully-qualified # information
+2139 ; non-fully-qualified # information
+1F194 ; fully-qualified # 🆔 ID button
+24C2 FE0F ; fully-qualified # Ⓜ️ circled M
+24C2 ; non-fully-qualified # Ⓜ circled M
+1F195 ; fully-qualified # 🆕 NEW button
+1F196 ; fully-qualified # 🆖 NG button
+1F17E FE0F ; fully-qualified # 🅾️ O button (blood type)
+1F17E ; non-fully-qualified # 🅾 O button (blood type)
+1F197 ; fully-qualified # 🆗 OK button
+1F17F FE0F ; fully-qualified # 🅿️ P button
+1F17F ; non-fully-qualified # 🅿 P button
+1F198 ; fully-qualified # 🆘 SOS button
+1F199 ; fully-qualified # 🆙 UP! button
+1F19A ; fully-qualified # 🆚 VS button
+1F201 ; fully-qualified # 🈁 Japanese “here” button
+1F202 FE0F ; fully-qualified # 🈂️ Japanese “service charge” button
+1F202 ; non-fully-qualified # 🈂 Japanese “service charge” button
+1F237 FE0F ; fully-qualified # 🈷️ Japanese “monthly amount” button
+1F237 ; non-fully-qualified # 🈷 Japanese “monthly amount” button
+1F236 ; fully-qualified # 🈶 Japanese “not free of charge” button
+1F22F ; fully-qualified # 🈯 Japanese “reserved” button
+1F250 ; fully-qualified # 🉐 Japanese “bargain” button
+1F239 ; fully-qualified # 🈹 Japanese “discount” button
+1F21A ; fully-qualified # 🈚 Japanese “free of charge” button
+1F232 ; fully-qualified # 🈲 Japanese “prohibited” button
+1F251 ; fully-qualified # 🉑 Japanese “acceptable” button
+1F238 ; fully-qualified # 🈸 Japanese “application” button
+1F234 ; fully-qualified # 🈴 Japanese “passing grade” button
+1F233 ; fully-qualified # 🈳 Japanese “vacancy” button
+3297 FE0F ; fully-qualified # ㊗️ Japanese “congratulations” button
+3297 ; non-fully-qualified # ㊗ Japanese “congratulations” button
+3299 FE0F ; fully-qualified # ㊙️ Japanese “secret” button
+3299 ; non-fully-qualified # ㊙ Japanese “secret” button
+1F23A ; fully-qualified # 🈺 Japanese “open for business” button
+1F235 ; fully-qualified # 🈵 Japanese “no vacancy” button
+
+# subgroup: geometric
+25AA FE0F ; fully-qualified # ▪️ black small square
+25AA ; non-fully-qualified # ▪ black small square
+25AB FE0F ; fully-qualified # ▫️ white small square
+25AB ; non-fully-qualified # ▫ white small square
+25FB FE0F ; fully-qualified # ◻️ white medium square
+25FB ; non-fully-qualified # ◻ white medium square
+25FC FE0F ; fully-qualified # ◼️ black medium square
+25FC ; non-fully-qualified # ◼ black medium square
+25FD ; fully-qualified # ◽ white medium-small square
+25FE ; fully-qualified # ◾ black medium-small square
+2B1B ; fully-qualified # ⬛ black large square
+2B1C ; fully-qualified # ⬜ white large square
+1F536 ; fully-qualified # 🔶 large orange diamond
+1F537 ; fully-qualified # 🔷 large blue diamond
+1F538 ; fully-qualified # 🔸 small orange diamond
+1F539 ; fully-qualified # 🔹 small blue diamond
+1F53A ; fully-qualified # 🔺 red triangle pointed up
+1F53B ; fully-qualified # 🔻 red triangle pointed down
+1F4A0 ; fully-qualified # 💠 diamond with a dot
+1F518 ; fully-qualified # 🔘 radio button
+1F532 ; fully-qualified # 🔲 black square button
+1F533 ; fully-qualified # 🔳 white square button
+26AA ; fully-qualified # ⚪ white circle
+26AB ; fully-qualified # ⚫ black circle
+1F534 ; fully-qualified # 🔴 red circle
+1F535 ; fully-qualified # 🔵 blue circle
+
+# Symbols subtotal: 286
+# Symbols subtotal: 286 w/o modifiers
+
+# group: Flags
+
+# subgroup: flag
+1F3C1 ; fully-qualified # 🏁 chequered flag
+1F6A9 ; fully-qualified # 🚩 triangular flag
+1F38C ; fully-qualified # 🎌 crossed flags
+1F3F4 ; fully-qualified # 🏴 black flag
+1F3F3 FE0F ; fully-qualified # 🏳️ white flag
+1F3F3 ; non-fully-qualified # 🏳 white flag
+1F3F3 FE0F 200D 1F308 ; fully-qualified # 🏳️‍🌈 rainbow flag
+1F3F3 200D 1F308 ; non-fully-qualified # 🏳‍🌈 rainbow flag
+1F3F4 200D 2620 FE0F ; fully-qualified # 🏴‍☠️ pirate flag
+1F3F4 200D 2620 ; non-fully-qualified # 🏴‍☠ pirate flag
+
+# subgroup: country-flag
+1F1E6 1F1E8 ; fully-qualified # 🇦🇨 Ascension Island
+1F1E6 1F1E9 ; fully-qualified # 🇦🇩 Andorra
+1F1E6 1F1EA ; fully-qualified # 🇦🇪 United Arab Emirates
+1F1E6 1F1EB ; fully-qualified # 🇦🇫 Afghanistan
+1F1E6 1F1EC ; fully-qualified # 🇦🇬 Antigua & Barbuda
+1F1E6 1F1EE ; fully-qualified # 🇦🇮 Anguilla
+1F1E6 1F1F1 ; fully-qualified # 🇦🇱 Albania
+1F1E6 1F1F2 ; fully-qualified # 🇦🇲 Armenia
+1F1E6 1F1F4 ; fully-qualified # 🇦🇴 Angola
+1F1E6 1F1F6 ; fully-qualified # 🇦🇶 Antarctica
+1F1E6 1F1F7 ; fully-qualified # 🇦🇷 Argentina
+1F1E6 1F1F8 ; fully-qualified # 🇦🇸 American Samoa
+1F1E6 1F1F9 ; fully-qualified # 🇦🇹 Austria
+1F1E6 1F1FA ; fully-qualified # 🇦🇺 Australia
+1F1E6 1F1FC ; fully-qualified # 🇦🇼 Aruba
+1F1E6 1F1FD ; fully-qualified # 🇦🇽 Åland Islands
+1F1E6 1F1FF ; fully-qualified # 🇦🇿 Azerbaijan
+1F1E7 1F1E6 ; fully-qualified # 🇧🇦 Bosnia & Herzegovina
+1F1E7 1F1E7 ; fully-qualified # 🇧🇧 Barbados
+1F1E7 1F1E9 ; fully-qualified # 🇧🇩 Bangladesh
+1F1E7 1F1EA ; fully-qualified # 🇧🇪 Belgium
+1F1E7 1F1EB ; fully-qualified # 🇧🇫 Burkina Faso
+1F1E7 1F1EC ; fully-qualified # 🇧🇬 Bulgaria
+1F1E7 1F1ED ; fully-qualified # 🇧🇭 Bahrain
+1F1E7 1F1EE ; fully-qualified # 🇧🇮 Burundi
+1F1E7 1F1EF ; fully-qualified # 🇧🇯 Benin
+1F1E7 1F1F1 ; fully-qualified # 🇧🇱 St. Barthélemy
+1F1E7 1F1F2 ; fully-qualified # 🇧🇲 Bermuda
+1F1E7 1F1F3 ; fully-qualified # 🇧🇳 Brunei
+1F1E7 1F1F4 ; fully-qualified # 🇧🇴 Bolivia
+1F1E7 1F1F6 ; fully-qualified # 🇧🇶 Caribbean Netherlands
+1F1E7 1F1F7 ; fully-qualified # 🇧🇷 Brazil
+1F1E7 1F1F8 ; fully-qualified # 🇧🇸 Bahamas
+1F1E7 1F1F9 ; fully-qualified # 🇧🇹 Bhutan
+1F1E7 1F1FB ; fully-qualified # 🇧🇻 Bouvet Island
+1F1E7 1F1FC ; fully-qualified # 🇧🇼 Botswana
+1F1E7 1F1FE ; fully-qualified # 🇧🇾 Belarus
+1F1E7 1F1FF ; fully-qualified # 🇧🇿 Belize
+1F1E8 1F1E6 ; fully-qualified # 🇨🇦 Canada
+1F1E8 1F1E8 ; fully-qualified # 🇨🇨 Cocos (Keeling) Islands
+1F1E8 1F1E9 ; fully-qualified # 🇨🇩 Congo - Kinshasa
+1F1E8 1F1EB ; fully-qualified # 🇨🇫 Central African Republic
+1F1E8 1F1EC ; fully-qualified # 🇨🇬 Congo - Brazzaville
+1F1E8 1F1ED ; fully-qualified # 🇨🇭 Switzerland
+1F1E8 1F1EE ; fully-qualified # 🇨🇮 Côte dIvoire
+1F1E8 1F1F0 ; fully-qualified # 🇨🇰 Cook Islands
+1F1E8 1F1F1 ; fully-qualified # 🇨🇱 Chile
+1F1E8 1F1F2 ; fully-qualified # 🇨🇲 Cameroon
+1F1E8 1F1F3 ; fully-qualified # 🇨🇳 China
+1F1E8 1F1F4 ; fully-qualified # 🇨🇴 Colombia
+1F1E8 1F1F5 ; fully-qualified # 🇨🇵 Clipperton Island
+1F1E8 1F1F7 ; fully-qualified # 🇨🇷 Costa Rica
+1F1E8 1F1FA ; fully-qualified # 🇨🇺 Cuba
+1F1E8 1F1FB ; fully-qualified # 🇨🇻 Cape Verde
+1F1E8 1F1FC ; fully-qualified # 🇨🇼 Curaçao
+1F1E8 1F1FD ; fully-qualified # 🇨🇽 Christmas Island
+1F1E8 1F1FE ; fully-qualified # 🇨🇾 Cyprus
+1F1E8 1F1FF ; fully-qualified # 🇨🇿 Czechia
+1F1E9 1F1EA ; fully-qualified # 🇩🇪 Germany
+1F1E9 1F1EC ; fully-qualified # 🇩🇬 Diego Garcia
+1F1E9 1F1EF ; fully-qualified # 🇩🇯 Djibouti
+1F1E9 1F1F0 ; fully-qualified # 🇩🇰 Denmark
+1F1E9 1F1F2 ; fully-qualified # 🇩🇲 Dominica
+1F1E9 1F1F4 ; fully-qualified # 🇩🇴 Dominican Republic
+1F1E9 1F1FF ; fully-qualified # 🇩🇿 Algeria
+1F1EA 1F1E6 ; fully-qualified # 🇪🇦 Ceuta & Melilla
+1F1EA 1F1E8 ; fully-qualified # 🇪🇨 Ecuador
+1F1EA 1F1EA ; fully-qualified # 🇪🇪 Estonia
+1F1EA 1F1EC ; fully-qualified # 🇪🇬 Egypt
+1F1EA 1F1ED ; fully-qualified # 🇪🇭 Western Sahara
+1F1EA 1F1F7 ; fully-qualified # 🇪🇷 Eritrea
+1F1EA 1F1F8 ; fully-qualified # 🇪🇸 Spain
+1F1EA 1F1F9 ; fully-qualified # 🇪🇹 Ethiopia
+1F1EA 1F1FA ; fully-qualified # 🇪🇺 European Union
+1F1EB 1F1EE ; fully-qualified # 🇫🇮 Finland
+1F1EB 1F1EF ; fully-qualified # 🇫🇯 Fiji
+1F1EB 1F1F0 ; fully-qualified # 🇫🇰 Falkland Islands
+1F1EB 1F1F2 ; fully-qualified # 🇫🇲 Micronesia
+1F1EB 1F1F4 ; fully-qualified # 🇫🇴 Faroe Islands
+1F1EB 1F1F7 ; fully-qualified # 🇫🇷 France
+1F1EC 1F1E6 ; fully-qualified # 🇬🇦 Gabon
+1F1EC 1F1E7 ; fully-qualified # 🇬🇧 United Kingdom
+1F1EC 1F1E9 ; fully-qualified # 🇬🇩 Grenada
+1F1EC 1F1EA ; fully-qualified # 🇬🇪 Georgia
+1F1EC 1F1EB ; fully-qualified # 🇬🇫 French Guiana
+1F1EC 1F1EC ; fully-qualified # 🇬🇬 Guernsey
+1F1EC 1F1ED ; fully-qualified # 🇬🇭 Ghana
+1F1EC 1F1EE ; fully-qualified # 🇬🇮 Gibraltar
+1F1EC 1F1F1 ; fully-qualified # 🇬🇱 Greenland
+1F1EC 1F1F2 ; fully-qualified # 🇬🇲 Gambia
+1F1EC 1F1F3 ; fully-qualified # 🇬🇳 Guinea
+1F1EC 1F1F5 ; fully-qualified # 🇬🇵 Guadeloupe
+1F1EC 1F1F6 ; fully-qualified # 🇬🇶 Equatorial Guinea
+1F1EC 1F1F7 ; fully-qualified # 🇬🇷 Greece
+1F1EC 1F1F8 ; fully-qualified # 🇬🇸 South Georgia & South Sandwich Islands
+1F1EC 1F1F9 ; fully-qualified # 🇬🇹 Guatemala
+1F1EC 1F1FA ; fully-qualified # 🇬🇺 Guam
+1F1EC 1F1FC ; fully-qualified # 🇬🇼 Guinea-Bissau
+1F1EC 1F1FE ; fully-qualified # 🇬🇾 Guyana
+1F1ED 1F1F0 ; fully-qualified # 🇭🇰 Hong Kong SAR China
+1F1ED 1F1F2 ; fully-qualified # 🇭🇲 Heard & McDonald Islands
+1F1ED 1F1F3 ; fully-qualified # 🇭🇳 Honduras
+1F1ED 1F1F7 ; fully-qualified # 🇭🇷 Croatia
+1F1ED 1F1F9 ; fully-qualified # 🇭🇹 Haiti
+1F1ED 1F1FA ; fully-qualified # 🇭🇺 Hungary
+1F1EE 1F1E8 ; fully-qualified # 🇮🇨 Canary Islands
+1F1EE 1F1E9 ; fully-qualified # 🇮🇩 Indonesia
+1F1EE 1F1EA ; fully-qualified # 🇮🇪 Ireland
+1F1EE 1F1F1 ; fully-qualified # 🇮🇱 Israel
+1F1EE 1F1F2 ; fully-qualified # 🇮🇲 Isle of Man
+1F1EE 1F1F3 ; fully-qualified # 🇮🇳 India
+1F1EE 1F1F4 ; fully-qualified # 🇮🇴 British Indian Ocean Territory
+1F1EE 1F1F6 ; fully-qualified # 🇮🇶 Iraq
+1F1EE 1F1F7 ; fully-qualified # 🇮🇷 Iran
+1F1EE 1F1F8 ; fully-qualified # 🇮🇸 Iceland
+1F1EE 1F1F9 ; fully-qualified # 🇮🇹 Italy
+1F1EF 1F1EA ; fully-qualified # 🇯🇪 Jersey
+1F1EF 1F1F2 ; fully-qualified # 🇯🇲 Jamaica
+1F1EF 1F1F4 ; fully-qualified # 🇯🇴 Jordan
+1F1EF 1F1F5 ; fully-qualified # 🇯🇵 Japan
+1F1F0 1F1EA ; fully-qualified # 🇰🇪 Kenya
+1F1F0 1F1EC ; fully-qualified # 🇰🇬 Kyrgyzstan
+1F1F0 1F1ED ; fully-qualified # 🇰🇭 Cambodia
+1F1F0 1F1EE ; fully-qualified # 🇰🇮 Kiribati
+1F1F0 1F1F2 ; fully-qualified # 🇰🇲 Comoros
+1F1F0 1F1F3 ; fully-qualified # 🇰🇳 St. Kitts & Nevis
+1F1F0 1F1F5 ; fully-qualified # 🇰🇵 North Korea
+1F1F0 1F1F7 ; fully-qualified # 🇰🇷 South Korea
+1F1F0 1F1FC ; fully-qualified # 🇰🇼 Kuwait
+1F1F0 1F1FE ; fully-qualified # 🇰🇾 Cayman Islands
+1F1F0 1F1FF ; fully-qualified # 🇰🇿 Kazakhstan
+1F1F1 1F1E6 ; fully-qualified # 🇱🇦 Laos
+1F1F1 1F1E7 ; fully-qualified # 🇱🇧 Lebanon
+1F1F1 1F1E8 ; fully-qualified # 🇱🇨 St. Lucia
+1F1F1 1F1EE ; fully-qualified # 🇱🇮 Liechtenstein
+1F1F1 1F1F0 ; fully-qualified # 🇱🇰 Sri Lanka
+1F1F1 1F1F7 ; fully-qualified # 🇱🇷 Liberia
+1F1F1 1F1F8 ; fully-qualified # 🇱🇸 Lesotho
+1F1F1 1F1F9 ; fully-qualified # 🇱🇹 Lithuania
+1F1F1 1F1FA ; fully-qualified # 🇱🇺 Luxembourg
+1F1F1 1F1FB ; fully-qualified # 🇱🇻 Latvia
+1F1F1 1F1FE ; fully-qualified # 🇱🇾 Libya
+1F1F2 1F1E6 ; fully-qualified # 🇲🇦 Morocco
+1F1F2 1F1E8 ; fully-qualified # 🇲🇨 Monaco
+1F1F2 1F1E9 ; fully-qualified # 🇲🇩 Moldova
+1F1F2 1F1EA ; fully-qualified # 🇲🇪 Montenegro
+1F1F2 1F1EB ; fully-qualified # 🇲🇫 St. Martin
+1F1F2 1F1EC ; fully-qualified # 🇲🇬 Madagascar
+1F1F2 1F1ED ; fully-qualified # 🇲🇭 Marshall Islands
+1F1F2 1F1F0 ; fully-qualified # 🇲🇰 Macedonia
+1F1F2 1F1F1 ; fully-qualified # 🇲🇱 Mali
+1F1F2 1F1F2 ; fully-qualified # 🇲🇲 Myanmar (Burma)
+1F1F2 1F1F3 ; fully-qualified # 🇲🇳 Mongolia
+1F1F2 1F1F4 ; fully-qualified # 🇲🇴 Macau SAR China
+1F1F2 1F1F5 ; fully-qualified # 🇲🇵 Northern Mariana Islands
+1F1F2 1F1F6 ; fully-qualified # 🇲🇶 Martinique
+1F1F2 1F1F7 ; fully-qualified # 🇲🇷 Mauritania
+1F1F2 1F1F8 ; fully-qualified # 🇲🇸 Montserrat
+1F1F2 1F1F9 ; fully-qualified # 🇲🇹 Malta
+1F1F2 1F1FA ; fully-qualified # 🇲🇺 Mauritius
+1F1F2 1F1FB ; fully-qualified # 🇲🇻 Maldives
+1F1F2 1F1FC ; fully-qualified # 🇲🇼 Malawi
+1F1F2 1F1FD ; fully-qualified # 🇲🇽 Mexico
+1F1F2 1F1FE ; fully-qualified # 🇲🇾 Malaysia
+1F1F2 1F1FF ; fully-qualified # 🇲🇿 Mozambique
+1F1F3 1F1E6 ; fully-qualified # 🇳🇦 Namibia
+1F1F3 1F1E8 ; fully-qualified # 🇳🇨 New Caledonia
+1F1F3 1F1EA ; fully-qualified # 🇳🇪 Niger
+1F1F3 1F1EB ; fully-qualified # 🇳🇫 Norfolk Island
+1F1F3 1F1EC ; fully-qualified # 🇳🇬 Nigeria
+1F1F3 1F1EE ; fully-qualified # 🇳🇮 Nicaragua
+1F1F3 1F1F1 ; fully-qualified # 🇳🇱 Netherlands
+1F1F3 1F1F4 ; fully-qualified # 🇳🇴 Norway
+1F1F3 1F1F5 ; fully-qualified # 🇳🇵 Nepal
+1F1F3 1F1F7 ; fully-qualified # 🇳🇷 Nauru
+1F1F3 1F1FA ; fully-qualified # 🇳🇺 Niue
+1F1F3 1F1FF ; fully-qualified # 🇳🇿 New Zealand
+1F1F4 1F1F2 ; fully-qualified # 🇴🇲 Oman
+1F1F5 1F1E6 ; fully-qualified # 🇵🇦 Panama
+1F1F5 1F1EA ; fully-qualified # 🇵🇪 Peru
+1F1F5 1F1EB ; fully-qualified # 🇵🇫 French Polynesia
+1F1F5 1F1EC ; fully-qualified # 🇵🇬 Papua New Guinea
+1F1F5 1F1ED ; fully-qualified # 🇵🇭 Philippines
+1F1F5 1F1F0 ; fully-qualified # 🇵🇰 Pakistan
+1F1F5 1F1F1 ; fully-qualified # 🇵🇱 Poland
+1F1F5 1F1F2 ; fully-qualified # 🇵🇲 St. Pierre & Miquelon
+1F1F5 1F1F3 ; fully-qualified # 🇵🇳 Pitcairn Islands
+1F1F5 1F1F7 ; fully-qualified # 🇵🇷 Puerto Rico
+1F1F5 1F1F8 ; fully-qualified # 🇵🇸 Palestinian Territories
+1F1F5 1F1F9 ; fully-qualified # 🇵🇹 Portugal
+1F1F5 1F1FC ; fully-qualified # 🇵🇼 Palau
+1F1F5 1F1FE ; fully-qualified # 🇵🇾 Paraguay
+1F1F6 1F1E6 ; fully-qualified # 🇶🇦 Qatar
+1F1F7 1F1EA ; fully-qualified # 🇷🇪 Réunion
+1F1F7 1F1F4 ; fully-qualified # 🇷🇴 Romania
+1F1F7 1F1F8 ; fully-qualified # 🇷🇸 Serbia
+1F1F7 1F1FA ; fully-qualified # 🇷🇺 Russia
+1F1F7 1F1FC ; fully-qualified # 🇷🇼 Rwanda
+1F1F8 1F1E6 ; fully-qualified # 🇸🇦 Saudi Arabia
+1F1F8 1F1E7 ; fully-qualified # 🇸🇧 Solomon Islands
+1F1F8 1F1E8 ; fully-qualified # 🇸🇨 Seychelles
+1F1F8 1F1E9 ; fully-qualified # 🇸🇩 Sudan
+1F1F8 1F1EA ; fully-qualified # 🇸🇪 Sweden
+1F1F8 1F1EC ; fully-qualified # 🇸🇬 Singapore
+1F1F8 1F1ED ; fully-qualified # 🇸🇭 St. Helena
+1F1F8 1F1EE ; fully-qualified # 🇸🇮 Slovenia
+1F1F8 1F1EF ; fully-qualified # 🇸🇯 Svalbard & Jan Mayen
+1F1F8 1F1F0 ; fully-qualified # 🇸🇰 Slovakia
+1F1F8 1F1F1 ; fully-qualified # 🇸🇱 Sierra Leone
+1F1F8 1F1F2 ; fully-qualified # 🇸🇲 San Marino
+1F1F8 1F1F3 ; fully-qualified # 🇸🇳 Senegal
+1F1F8 1F1F4 ; fully-qualified # 🇸🇴 Somalia
+1F1F8 1F1F7 ; fully-qualified # 🇸🇷 Suriname
+1F1F8 1F1F8 ; fully-qualified # 🇸🇸 South Sudan
+1F1F8 1F1F9 ; fully-qualified # 🇸🇹 São Tomé & Príncipe
+1F1F8 1F1FB ; fully-qualified # 🇸🇻 El Salvador
+1F1F8 1F1FD ; fully-qualified # 🇸🇽 Sint Maarten
+1F1F8 1F1FE ; fully-qualified # 🇸🇾 Syria
+1F1F8 1F1FF ; fully-qualified # 🇸🇿 Swaziland
+1F1F9 1F1E6 ; fully-qualified # 🇹🇦 Tristan da Cunha
+1F1F9 1F1E8 ; fully-qualified # 🇹🇨 Turks & Caicos Islands
+1F1F9 1F1E9 ; fully-qualified # 🇹🇩 Chad
+1F1F9 1F1EB ; fully-qualified # 🇹🇫 French Southern Territories
+1F1F9 1F1EC ; fully-qualified # 🇹🇬 Togo
+1F1F9 1F1ED ; fully-qualified # 🇹🇭 Thailand
+1F1F9 1F1EF ; fully-qualified # 🇹🇯 Tajikistan
+1F1F9 1F1F0 ; fully-qualified # 🇹🇰 Tokelau
+1F1F9 1F1F1 ; fully-qualified # 🇹🇱 Timor-Leste
+1F1F9 1F1F2 ; fully-qualified # 🇹🇲 Turkmenistan
+1F1F9 1F1F3 ; fully-qualified # 🇹🇳 Tunisia
+1F1F9 1F1F4 ; fully-qualified # 🇹🇴 Tonga
+1F1F9 1F1F7 ; fully-qualified # 🇹🇷 Turkey
+1F1F9 1F1F9 ; fully-qualified # 🇹🇹 Trinidad & Tobago
+1F1F9 1F1FB ; fully-qualified # 🇹🇻 Tuvalu
+1F1F9 1F1FC ; fully-qualified # 🇹🇼 Taiwan
+1F1F9 1F1FF ; fully-qualified # 🇹🇿 Tanzania
+1F1FA 1F1E6 ; fully-qualified # 🇺🇦 Ukraine
+1F1FA 1F1EC ; fully-qualified # 🇺🇬 Uganda
+1F1FA 1F1F2 ; fully-qualified # 🇺🇲 U.S. Outlying Islands
+1F1FA 1F1F3 ; fully-qualified # 🇺🇳 United Nations
+1F1FA 1F1F8 ; fully-qualified # 🇺🇸 United States
+1F1FA 1F1FE ; fully-qualified # 🇺🇾 Uruguay
+1F1FA 1F1FF ; fully-qualified # 🇺🇿 Uzbekistan
+1F1FB 1F1E6 ; fully-qualified # 🇻🇦 Vatican City
+1F1FB 1F1E8 ; fully-qualified # 🇻🇨 St. Vincent & Grenadines
+1F1FB 1F1EA ; fully-qualified # 🇻🇪 Venezuela
+1F1FB 1F1EC ; fully-qualified # 🇻🇬 British Virgin Islands
+1F1FB 1F1EE ; fully-qualified # 🇻🇮 U.S. Virgin Islands
+1F1FB 1F1F3 ; fully-qualified # 🇻🇳 Vietnam
+1F1FB 1F1FA ; fully-qualified # 🇻🇺 Vanuatu
+1F1FC 1F1EB ; fully-qualified # 🇼🇫 Wallis & Futuna
+1F1FC 1F1F8 ; fully-qualified # 🇼🇸 Samoa
+1F1FD 1F1F0 ; fully-qualified # 🇽🇰 Kosovo
+1F1FE 1F1EA ; fully-qualified # 🇾🇪 Yemen
+1F1FE 1F1F9 ; fully-qualified # 🇾🇹 Mayotte
+1F1FF 1F1E6 ; fully-qualified # 🇿🇦 South Africa
+1F1FF 1F1F2 ; fully-qualified # 🇿🇲 Zambia
+1F1FF 1F1FC ; fully-qualified # 🇿🇼 Zimbabwe
+
+# subgroup: subdivision-flag
+1F3F4 E0067 E0062 E0065 E006E E0067 E007F ; fully-qualified # 🏴󠁧󠁢󠁥󠁮󠁧󠁿 England
+1F3F4 E0067 E0062 E0073 E0063 E0074 E007F ; fully-qualified # 🏴󠁧󠁢󠁳󠁣󠁴󠁿 Scotland
+1F3F4 E0067 E0062 E0077 E006C E0073 E007F ; fully-qualified # 🏴󠁧󠁢󠁷󠁬󠁳󠁿 Wales
+
+# Flags subtotal: 271
+# Flags subtotal: 271 w/o modifiers
+
+#EOF
diff --git a/tests/manual/emojisequences/main.cpp b/tests/manual/emojisequences/main.cpp
new file mode 100644
index 00000000..aa3bd803
--- /dev/null
+++ b/tests/manual/emojisequences/main.cpp
@@ -0,0 +1,18 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include "mainwindow.h"
+
+#include <QtGui>
+#include <QtWidgets>
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+
+ MainWindow w;
+ w.show();
+
+ return a.exec();
+}
+
diff --git a/tests/manual/emojisequences/mainwindow.cpp b/tests/manual/emojisequences/mainwindow.cpp
new file mode 100644
index 00000000..1b50698b
--- /dev/null
+++ b/tests/manual/emojisequences/mainwindow.cpp
@@ -0,0 +1,95 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+
+#include <QtCore>
+#include <QtGui>
+#include <QtWidgets>
+
+MainWindow::MainWindow(QWidget *parent)
+ : QMainWindow(parent)
+ , ui(new Ui::MainWindow)
+{
+ ui->setupUi(this);
+
+ connect(ui->toolButton, &QToolButton::clicked, this, &MainWindow::loadCustomFont);
+
+ populateEmojiTest();
+}
+
+MainWindow::~MainWindow()
+{
+ delete ui;
+}
+
+void MainWindow::populateEmojiTest()
+{
+ QFile file(":/emoji-test.txt");
+
+ ui->tableWidget->clear();
+ ui->tableWidget->setColumnCount(8);
+
+ QList<QPair<QString, QString> > strings;
+ if (file.open(QIODevice::ReadOnly)) {
+ while (!file.atEnd()) {
+ QString l = file.readLine();
+
+ QStringList toolTip;
+ QString testString;
+ QStringList tokens = l.split(QLatin1Char(' '), Qt::SkipEmptyParts);
+ for (int i = 0; i < tokens.size(); ++i) {
+ if (tokens.at(i) == QLatin1Char(';'))
+ break;
+
+ bool ok;
+ char32_t ucs4 = tokens.at(i).toUInt(&ok, 16);
+ if (!ok)
+ break;
+
+ testString += QString::fromUcs4(&ucs4, 1);
+ toolTip << QString::number(ucs4, 16);
+ }
+
+ if (!toolTip.isEmpty()) {
+ strings.append(qMakePair(testString, toolTip.join(',')));
+ }
+ }
+ }
+
+ ui->tableWidget->setRowCount(strings.count() / 8);
+ for (int i = 0; i < strings.count(); ++i) {
+ int row = i / 8;
+ int column = i % 8;
+ QString testString = strings.at(i).first;
+ QString toolTip = strings.at(i).second;
+
+ QTableWidgetItem *it = new QTableWidgetItem(testString);
+ ui->tableWidget->setItem(row, column, it);
+ it->setText(testString);
+ it->setToolTip(toolTip);
+ }
+}
+
+void MainWindow::loadCustomFont()
+{
+#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
+ ui->tableWidget->clear();
+ QFontDatabase::removeAllApplicationFonts();
+
+ QString fileName = QFileDialog::getOpenFileName(this, tr("Open font file"), QString(), tr("Fonts (*.ttf *.otf);All files (*)"));
+ if (!fileName.isEmpty()) {
+ int id = QFontDatabase::addApplicationFont(fileName);
+ if (id >= 0) {
+ QStringList families = QFontDatabase::applicationFontFamilies(id);
+ QString family = families.size() > 0 ? families.first() : QString();
+ if (!family.isEmpty()) {
+ QFontDatabase::setApplicationEmojiFontFamilies(QStringList() << family);
+ populateEmojiTest();
+ }
+ }
+ }
+#endif
+}
+
diff --git a/tests/manual/emojisequences/mainwindow.h b/tests/manual/emojisequences/mainwindow.h
new file mode 100644
index 00000000..cda2d9a4
--- /dev/null
+++ b/tests/manual/emojisequences/mainwindow.h
@@ -0,0 +1,31 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+
+namespace Ui {
+class MainWindow;
+}
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ explicit MainWindow(QWidget *parent = nullptr);
+ ~MainWindow();
+
+private slots:
+ void loadCustomFont();
+
+private:
+ void populateEmojiTest();
+
+
+ Ui::MainWindow *ui;
+};
+
+#endif // MAINWINDOW_H
diff --git a/tests/manual/emojisequences/mainwindow.ui b/tests/manual/emojisequences/mainwindow.ui
new file mode 100644
index 00000000..622b149f
--- /dev/null
+++ b/tests/manual/emojisequences/mainwindow.ui
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>1245</width>
+ <height>972</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>MainWindow</string>
+ </property>
+ <widget class="QWidget" name="centralwidget">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTableWidget" name="tableWidget">
+ <property name="font">
+ <font>
+ <pointsize>20</pointsize>
+ </font>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="toolButton">
+ <property name="text">
+ <string>Load custom font...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menubar">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>1245</width>
+ <height>22</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QStatusBar" name="statusbar"/>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>