summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/context/documents/general/qrcs/setup-cs.pdfbin808145 -> 808145 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-de.pdfbin809567 -> 809571 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-en.pdfbin811967 -> 811964 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-fr.pdfbin805757 -> 805753 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-it.pdfbin809776 -> 809771 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-nl.pdfbin806228 -> 806224 bytes
-rw-r--r--doc/context/documents/general/qrcs/setup-ro.pdfbin804689 -> 804687 bytes
-rw-r--r--scripts/context/lua/mtx-fonts.lua2
-rw-r--r--scripts/context/lua/mtx-unicode.lua98
-rw-r--r--scripts/context/lua/mtxrun.lua10
-rw-r--r--scripts/context/stubs/mswin/mtxrun.lua10
-rw-r--r--scripts/context/stubs/unix/mtxrun10
-rw-r--r--scripts/context/stubs/win64/mtxrun.lua10
-rw-r--r--tex/context/base/mkii/cont-new.mkii2
-rw-r--r--tex/context/base/mkii/context.mkii2
-rw-r--r--tex/context/base/mkiv/attr-col.lua4
-rw-r--r--tex/context/base/mkiv/char-def.lua2
-rw-r--r--tex/context/base/mkiv/char-emj.lua2633
-rw-r--r--tex/context/base/mkiv/char-ini.lua173
-rw-r--r--tex/context/base/mkiv/cldf-ini.lua12
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkiv4
-rw-r--r--tex/context/base/mkiv/font-cff.lua23
-rw-r--r--tex/context/base/mkiv/font-col.lua17
-rw-r--r--tex/context/base/mkiv/font-col.mkvi15
-rw-r--r--tex/context/base/mkiv/font-ctx.lua36
-rw-r--r--tex/context/base/mkiv/font-dsp.lua99
-rw-r--r--tex/context/base/mkiv/font-mat.mkvi18
-rw-r--r--tex/context/base/mkiv/font-mis.lua2
-rw-r--r--tex/context/base/mkiv/font-nod.lua10
-rw-r--r--tex/context/base/mkiv/font-ocl.lua138
-rw-r--r--tex/context/base/mkiv/font-otc.lua8
-rw-r--r--tex/context/base/mkiv/font-otj.lua7
-rw-r--r--tex/context/base/mkiv/font-otl.lua2
-rw-r--r--tex/context/base/mkiv/font-otr.lua28
-rw-r--r--tex/context/base/mkiv/font-ots.lua54
-rw-r--r--tex/context/base/mkiv/font-oup.lua44
-rw-r--r--tex/context/base/mkiv/font-pre.mkiv9
-rw-r--r--tex/context/base/mkiv/l-table.lua6
-rw-r--r--tex/context/base/mkiv/lpdf-col.lua6
-rw-r--r--tex/context/base/mkiv/math-act.lua176
-rw-r--r--tex/context/base/mkiv/node-typ.lua29
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin25644 -> 25667 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin424467 -> 424881 bytes
-rw-r--r--tex/context/base/mkiv/symb-emj.lua82
-rw-r--r--tex/context/base/mkiv/symb-emj.mkiv27
-rw-r--r--tex/context/base/mkiv/trac-vis.lua7
-rw-r--r--tex/context/interface/mkiv/i-context.pdfbin811967 -> 811964 bytes
-rw-r--r--tex/context/interface/mkiv/i-readme.pdfbin60772 -> 60863 bytes
-rw-r--r--tex/context/modules/mkiv/s-fonts-emoji.mkiv331
-rw-r--r--tex/context/modules/mkiv/s-fonts-variable.lua11
-rw-r--r--tex/context/modules/mkiv/s-fonts-variable.mkiv3
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua354
53 files changed, 4106 insertions, 410 deletions
diff --git a/doc/context/documents/general/qrcs/setup-cs.pdf b/doc/context/documents/general/qrcs/setup-cs.pdf
index 6cd7dc620..4c29b57e6 100644
--- a/doc/context/documents/general/qrcs/setup-cs.pdf
+++ b/doc/context/documents/general/qrcs/setup-cs.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-de.pdf b/doc/context/documents/general/qrcs/setup-de.pdf
index f1b39be5a..f9aa7e4d9 100644
--- a/doc/context/documents/general/qrcs/setup-de.pdf
+++ b/doc/context/documents/general/qrcs/setup-de.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-en.pdf b/doc/context/documents/general/qrcs/setup-en.pdf
index bb6619b2e..60d780fef 100644
--- a/doc/context/documents/general/qrcs/setup-en.pdf
+++ b/doc/context/documents/general/qrcs/setup-en.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-fr.pdf b/doc/context/documents/general/qrcs/setup-fr.pdf
index f5ce96d5e..8d4bd1fbe 100644
--- a/doc/context/documents/general/qrcs/setup-fr.pdf
+++ b/doc/context/documents/general/qrcs/setup-fr.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-it.pdf b/doc/context/documents/general/qrcs/setup-it.pdf
index cecb16e89..ccc464822 100644
--- a/doc/context/documents/general/qrcs/setup-it.pdf
+++ b/doc/context/documents/general/qrcs/setup-it.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-nl.pdf b/doc/context/documents/general/qrcs/setup-nl.pdf
index 83e7b2a8e..fc8ef52a0 100644
--- a/doc/context/documents/general/qrcs/setup-nl.pdf
+++ b/doc/context/documents/general/qrcs/setup-nl.pdf
Binary files differ
diff --git a/doc/context/documents/general/qrcs/setup-ro.pdf b/doc/context/documents/general/qrcs/setup-ro.pdf
index 4f0def580..fcb3ba153 100644
--- a/doc/context/documents/general/qrcs/setup-ro.pdf
+++ b/doc/context/documents/general/qrcs/setup-ro.pdf
Binary files differ
diff --git a/scripts/context/lua/mtx-fonts.lua b/scripts/context/lua/mtx-fonts.lua
index a3924ef8f..068d38a84 100644
--- a/scripts/context/lua/mtx-fonts.lua
+++ b/scripts/context/lua/mtx-fonts.lua
@@ -17,7 +17,7 @@ local concat = table.concat
local write_nl = texio.write_nl
local otfversion = 2.826
-local otlversion = 3.028
+local otlversion = 3.029
local helpinfo = [[
<?xml version="1.0"?>
diff --git a/scripts/context/lua/mtx-unicode.lua b/scripts/context/lua/mtx-unicode.lua
index 418df9261..557e70b79 100644
--- a/scripts/context/lua/mtx-unicode.lua
+++ b/scripts/context/lua/mtx-unicode.lua
@@ -52,7 +52,9 @@ local split, splitlines, strip = string.split, string.splitlines, string.strip
local are_equal = table.are_equal
local tonumber, tostring, rawget = tonumber, tostring, rawget
local lpegmatch = lpeg.match
+local P, C, S, R, Cs, Ct, Cg, Cf, Cc = lpeg.P, lpeg.C, lpeg.S, lpeg.R, lpeg.Cs, lpeg.Ct, lpeg.Cg, lpeg.Cf, lpeg.Cc
local formatters = string.formatters
+local utfchar = utf.char
local report = application.report
@@ -73,7 +75,7 @@ local sparse = false
local split_space_table = lpeg.tsplitat(" ")
local split_space_two = lpeg.splitat (" ")
local split_range_two = lpeg.splitat ("..")
-local split_colon_table = lpeg.tsplitat(lpeg.P(" ")^0 * lpeg.P(";") * lpeg.P(" ")^0)
+local split_colon_table = lpeg.tsplitat(P(" ")^0 * P(";") * P(" ")^0)
local skipped = {
[0x002C6] = true, -- MODIFIER LETTER CIRCUMFLEX ACCENT
@@ -541,10 +543,10 @@ function scripts.unicode.extras() -- old code
index[k] = nil
end
end
--- for k, v in next, data do
--- v.synonym = nil
--- v.synonyms = nil
--- end
+ -- for k, v in next, data do
+ -- v.synonym = nil
+ -- v.synonyms = nil
+ -- end
for k, v in table.sortedhash(index) do
local d = data[v]
if d and d.description ~= upper(k) then
@@ -571,6 +573,91 @@ function scripts.unicode.extras() -- old code
end
end
+do
+
+ local space = P(" ")
+ local spaces = space^0
+ local semicolon = P(";")
+ local hash = P("#")
+ local newline = S("\n\r")
+
+ local unicode = Cs(R("09","AF")^1)/function(n) return tonumber(n,16) end
+ * spaces
+ local components = Ct (unicode^1)
+
+ -- local rubish_a = semicolon
+ -- * spaces
+ -- * P("Emoji_ZWJ_Sequence")
+ -- * spaces
+ -- * semicolon
+ -- * spaces
+ -- local description = C((1 - (spaces * (hash+newline)))^1)
+ -- local rubish_b = (1-newline)^0
+ -- * newline^1
+ --
+ -- local pattern_1 = Ct ( (
+ -- Cf ( Ct("") *
+ -- Cg (Cc("components") * components)
+ -- * rubish_a
+ -- * Cg (Cc("description") * description )
+ -- * rubish_b
+ -- , rawset)
+ -- + P(1) )^1 )
+
+ local rubish_a = semicolon
+ * spaces
+ * P("non-")^0 * P("fully-qualified")
+ * spaces
+ * hash
+ * spaces
+ local textstring = C((1 - space)^1)
+ * spaces
+ local description = ((1 - (spaces * newline))^1) / string.lower
+ local rubish_b = (1-newline)^0
+ * newline^1
+
+ local pattern_2 = Ct ( (
+ Cf ( Ct("") *
+ Cg (Cc("components") * components)
+ * rubish_a
+ * Cg (Cc("textstring") * textstring)
+ * Cg (Cc("description") * description )
+ * rubish_b
+ , rawset)
+ + P(1) )^1 )
+
+ function scripts.unicode.emoji(filename)
+
+ local name = resolvers.findfile("emoji-test.txt") or ""
+ if name == "" then
+ return
+ end
+ local l = io.loaddata(name)
+ local t = lpegmatch(pattern_2,l)
+
+ local hash = { }
+
+ local replace = lpeg.replacer {
+ ["#"] = "hash",
+ ["*"] = "asterisk"
+ }
+
+ for i=1,#t do
+ local v = t[i]
+ local d = v.description
+ local k = lpegmatch(replace,d) or d
+ hash[k] = v.components
+ end
+ local new = table.serialize(hash,"return", { hexify = true })
+ local old = io.loaddata(resolvers.findfile("char-emj.lua"))
+ if old and old ~= "" then
+ new = gsub(old,"^(.-)return .*$","%1" .. new)
+ end
+ io.savedata(filename,new)
+ end
+
+end
+
-- the action
local filename = environment.files[1]
@@ -583,6 +670,7 @@ else
scripts.unicode.update()
scripts.unicode.extras()
scripts.unicode.save("char-def-new.lua")
+ scripts.unicode.emoji("char-emj-new.lua")
else
report("nothing to do")
end
diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua
index 6b998eb74..89c156551 100644
--- a/scripts/context/lua/mtxrun.lua
+++ b/scripts/context/lua/mtxrun.lua
@@ -1670,7 +1670,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-table"] = package.loaded["l-table"] or true
--- original size: 39587, stripped down to: 23144
+-- original size: 39608, stripped down to: 23165
if not modules then modules={} end modules ['l-table']={
version=1.001,
@@ -2003,7 +2003,7 @@ local reserved=table.tohash {
'in','local','nil','not','or','repeat','return','then','true','until','while',
'NaN','goto',
}
-local function is_simple_table(t)
+local function is_simple_table(t,hexify)
local nt=#t
if nt>0 then
local n=0
@@ -2121,7 +2121,7 @@ local function do_serialize(root,name,depth,level,indexed)
if next(v)==nil then
handle(format("%s {},",depth))
elseif inline then
- local st=is_simple_table(v)
+ local st=is_simple_table(v,hexify)
if st then
handle(format("%s { %s },",depth,concat(st,", ")))
else
@@ -2204,7 +2204,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%q]={},",depth,k))
end
elseif inline then
- local st=is_simple_table(v)
+ local st=is_simple_table(v,hexify)
if st then
if tk=="number" then
if hexify then
@@ -20430,7 +20430,7 @@ end -- of closure
-- used libraries : l-lua.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 841875
+-- original bytes : 841896
-- stripped bytes : 305446
-- end library merge
diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua
index 6b998eb74..89c156551 100644
--- a/scripts/context/stubs/mswin/mtxrun.lua
+++ b/scripts/context/stubs/mswin/mtxrun.lua
@@ -1670,7 +1670,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-table"] = package.loaded["l-table"] or true
--- original size: 39587, stripped down to: 23144
+-- original size: 39608, stripped down to: 23165
if not modules then modules={} end modules ['l-table']={
version=1.001,
@@ -2003,7 +2003,7 @@ local reserved=table.tohash {
'in','local','nil','not','or','repeat','return','then','true','until','while',
'NaN','goto',
}
-local function is_simple_table(t)
+local function is_simple_table(t,hexify)
local nt=#t
if nt>0 then
local n=0
@@ -2121,7 +2121,7 @@ local function do_serialize(root,name,depth,level,indexed)
if next(v)==nil then
handle(format("%s {},",depth))
elseif inline then
- local st=is_simple_table(v)
+ local st=is_simple_table(v,hexify)
if st then
handle(format("%s { %s },",depth,concat(st,", ")))
else
@@ -2204,7 +2204,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%q]={},",depth,k))
end
elseif inline then
- local st=is_simple_table(v)
+ local st=is_simple_table(v,hexify)
if st then
if tk=="number" then
if hexify then
@@ -20430,7 +20430,7 @@ end -- of closure
-- used libraries : l-lua.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 841875
+-- original bytes : 841896
-- stripped bytes : 305446
-- end library merge
diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun
index 6b998eb74..89c156551 100644
--- a/scripts/context/stubs/unix/mtxrun
+++ b/scripts/context/stubs/unix/mtxrun
@@ -1670,7 +1670,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-table"] = package.loaded["l-table"] or true
--- original size: 39587, stripped down to: 23144
+-- original size: 39608, stripped down to: 23165
if not modules then modules={} end modules ['l-table']={
version=1.001,
@@ -2003,7 +2003,7 @@ local reserved=table.tohash {
'in','local','nil','not','or','repeat','return','then','true','until','while',
'NaN','goto',
}
-local function is_simple_table(t)
+local function is_simple_table(t,hexify)
local nt=#t
if nt>0 then
local n=0
@@ -2121,7 +2121,7 @@ local function do_serialize(root,name,depth,level,indexed)
if next(v)==nil then
handle(format("%s {},",depth))
elseif inline then
- local st=is_simple_table(v)
+ local st=is_simple_table(v,hexify)
if st then
handle(format("%s { %s },",depth,concat(st,", ")))
else
@@ -2204,7 +2204,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%q]={},",depth,k))
end
elseif inline then
- local st=is_simple_table(v)
+ local st=is_simple_table(v,hexify)
if st then
if tk=="number" then
if hexify then
@@ -20430,7 +20430,7 @@ end -- of closure
-- used libraries : l-lua.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 841875
+-- original bytes : 841896
-- stripped bytes : 305446
-- end library merge
diff --git a/scripts/context/stubs/win64/mtxrun.lua b/scripts/context/stubs/win64/mtxrun.lua
index 6b998eb74..89c156551 100644
--- a/scripts/context/stubs/win64/mtxrun.lua
+++ b/scripts/context/stubs/win64/mtxrun.lua
@@ -1670,7 +1670,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-table"] = package.loaded["l-table"] or true
--- original size: 39587, stripped down to: 23144
+-- original size: 39608, stripped down to: 23165
if not modules then modules={} end modules ['l-table']={
version=1.001,
@@ -2003,7 +2003,7 @@ local reserved=table.tohash {
'in','local','nil','not','or','repeat','return','then','true','until','while',
'NaN','goto',
}
-local function is_simple_table(t)
+local function is_simple_table(t,hexify)
local nt=#t
if nt>0 then
local n=0
@@ -2121,7 +2121,7 @@ local function do_serialize(root,name,depth,level,indexed)
if next(v)==nil then
handle(format("%s {},",depth))
elseif inline then
- local st=is_simple_table(v)
+ local st=is_simple_table(v,hexify)
if st then
handle(format("%s { %s },",depth,concat(st,", ")))
else
@@ -2204,7 +2204,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%q]={},",depth,k))
end
elseif inline then
- local st=is_simple_table(v)
+ local st=is_simple_table(v,hexify)
if st then
if tk=="number" then
if hexify then
@@ -20430,7 +20430,7 @@ end -- of closure
-- used libraries : l-lua.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 841875
+-- original bytes : 841896
-- stripped bytes : 305446
-- end library merge
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index 0d52642ba..0a74d9611 100644
--- a/tex/context/base/mkii/cont-new.mkii
+++ b/tex/context/base/mkii/cont-new.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2017.04.20 21:31}
+\newcontextversion{2017.04.27 01:00}
%D This file is loaded at runtime, thereby providing an
%D excellent place for hacks, patches, extensions and new
diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii
index 6e0150998..e6dc51a82 100644
--- a/tex/context/base/mkii/context.mkii
+++ b/tex/context/base/mkii/context.mkii
@@ -20,7 +20,7 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2017.04.20 21:31}
+\edef\contextversion{2017.04.27 01:00}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/attr-col.lua b/tex/context/base/mkiv/attr-col.lua
index 3cd712449..c3b644bda 100644
--- a/tex/context/base/mkiv/attr-col.lua
+++ b/tex/context/base/mkiv/attr-col.lua
@@ -527,8 +527,8 @@ local function reviver(data,n)
end
end
-setmetatableindex(transparencies, extender)
-setmetatableindex(transparencies.data, reviver) -- register if used
+setmetatableindex(transparencies,extender)
+setmetatableindex(transparencies.data,reviver) -- register if used
-- check if there is an identity
diff --git a/tex/context/base/mkiv/char-def.lua b/tex/context/base/mkiv/char-def.lua
index 0618ceb2e..76c51a6b4 100644
--- a/tex/context/base/mkiv/char-def.lua
+++ b/tex/context/base/mkiv/char-def.lua
@@ -238949,4 +238949,4 @@ characters.data={
synonyms={ "vs17" },
unicodeslot=0xE0100,
},
-} \ No newline at end of file
+}
diff --git a/tex/context/base/mkiv/char-emj.lua b/tex/context/base/mkiv/char-emj.lua
new file mode 100644
index 000000000..718d3bc6e
--- /dev/null
+++ b/tex/context/base/mkiv/char-emj.lua
@@ -0,0 +1,2633 @@
+if not modules then modules = { } end modules ['char-emj'] = {
+ version = 1.001,
+ comment = "companion to char-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files",
+ dataonly = true,
+}
+
+-- This table is generated.
+
+return {
+ ["1st place medal"]={ 0x1F947 },
+ ["2nd place medal"]={ 0x1F948 },
+ ["3rd place medal"]={ 0x1F949 },
+ ["a button (blood type)"]={ 0x1F170 },
+ ["ab button (blood type)"]={ 0x1F18E },
+ ["admission tickets"]={ 0x1F39F },
+ ["adult"]={ 0x1F9D1 },
+ ["adult: dark skin tone"]={ 0x1F9D1, 0x1F3FF },
+ ["adult: light skin tone"]={ 0x1F9D1, 0x1F3FB },
+ ["adult: medium skin tone"]={ 0x1F9D1, 0x1F3FD },
+ ["adult: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE },
+ ["adult: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC },
+ ["aerial tramway"]={ 0x1F6A1 },
+ ["afghanistan"]={ 0x1F1E6, 0x1F1EB },
+ ["airplane"]={ 0x2708 },
+ ["airplane arrival"]={ 0x1F6EC },
+ ["airplane departure"]={ 0x1F6EB },
+ ["alarm clock"]={ 0x23F0 },
+ ["albania"]={ 0x1F1E6, 0x1F1F1 },
+ ["alembic"]={ 0x2697 },
+ ["algeria"]={ 0x1F1E9, 0x1F1FF },
+ ["alien"]={ 0x1F47D },
+ ["alien monster"]={ 0x1F47E },
+ ["ambulance"]={ 0x1F691 },
+ ["american football"]={ 0x1F3C8 },
+ ["american samoa"]={ 0x1F1E6, 0x1F1F8 },
+ ["amphora"]={ 0x1F3FA },
+ ["anchor"]={ 0x2693 },
+ ["andorra"]={ 0x1F1E6, 0x1F1E9 },
+ ["anger symbol"]={ 0x1F4A2 },
+ ["angola"]={ 0x1F1E6, 0x1F1F4 },
+ ["angry face"]={ 0x1F620 },
+ ["angry face with horns"]={ 0x1F47F },
+ ["anguilla"]={ 0x1F1E6, 0x1F1EE },
+ ["anguished face"]={ 0x1F627 },
+ ["ant"]={ 0x1F41C },
+ ["antarctica"]={ 0x1F1E6, 0x1F1F6 },
+ ["antenna bars"]={ 0x1F4F6 },
+ ["anticlockwise arrows button"]={ 0x1F504 },
+ ["antigua & barbuda"]={ 0x1F1E6, 0x1F1EC },
+ ["aquarius"]={ 0x2652 },
+ ["argentina"]={ 0x1F1E6, 0x1F1F7 },
+ ["aries"]={ 0x2648 },
+ ["armenia"]={ 0x1F1E6, 0x1F1F2 },
+ ["articulated lorry"]={ 0x1F69B },
+ ["artist palette"]={ 0x1F3A8 },
+ ["aruba"]={ 0x1F1E6, 0x1F1FC },
+ ["ascension island"]={ 0x1F1E6, 0x1F1E8 },
+ ["astonished face"]={ 0x1F632 },
+ ["atm sign"]={ 0x1F3E7 },
+ ["atom symbol"]={ 0x269B },
+ ["australia"]={ 0x1F1E6, 0x1F1FA },
+ ["austria"]={ 0x1F1E6, 0x1F1F9 },
+ ["automobile"]={ 0x1F697 },
+ ["avocado"]={ 0x1F951 },
+ ["azerbaijan"]={ 0x1F1E6, 0x1F1FF },
+ ["b button (blood type)"]={ 0x1F171 },
+ ["baby"]={ 0x1F476 },
+ ["baby angel"]={ 0x1F47C },
+ ["baby angel: dark skin tone"]={ 0x1F47C, 0x1F3FF },
+ ["baby angel: light skin tone"]={ 0x1F47C, 0x1F3FB },
+ ["baby angel: medium skin tone"]={ 0x1F47C, 0x1F3FD },
+ ["baby angel: medium-dark skin tone"]={ 0x1F47C, 0x1F3FE },
+ ["baby angel: medium-light skin tone"]={ 0x1F47C, 0x1F3FC },
+ ["baby bottle"]={ 0x1F37C },
+ ["baby chick"]={ 0x1F424 },
+ ["baby symbol"]={ 0x1F6BC },
+ ["baby: dark skin tone"]={ 0x1F476, 0x1F3FF },
+ ["baby: light skin tone"]={ 0x1F476, 0x1F3FB },
+ ["baby: medium skin tone"]={ 0x1F476, 0x1F3FD },
+ ["baby: medium-dark skin tone"]={ 0x1F476, 0x1F3FE },
+ ["baby: medium-light skin tone"]={ 0x1F476, 0x1F3FC },
+ ["back arrow"]={ 0x1F519 },
+ ["backhand index pointing down"]={ 0x1F447 },
+ ["backhand index pointing down: dark skin tone"]={ 0x1F447, 0x1F3FF },
+ ["backhand index pointing down: light skin tone"]={ 0x1F447, 0x1F3FB },
+ ["backhand index pointing down: medium skin tone"]={ 0x1F447, 0x1F3FD },
+ ["backhand index pointing down: medium-dark skin tone"]={ 0x1F447, 0x1F3FE },
+ ["backhand index pointing down: medium-light skin tone"]={ 0x1F447, 0x1F3FC },
+ ["backhand index pointing left"]={ 0x1F448 },
+ ["backhand index pointing left: dark skin tone"]={ 0x1F448, 0x1F3FF },
+ ["backhand index pointing left: light skin tone"]={ 0x1F448, 0x1F3FB },
+ ["backhand index pointing left: medium skin tone"]={ 0x1F448, 0x1F3FD },
+ ["backhand index pointing left: medium-dark skin tone"]={ 0x1F448, 0x1F3FE },
+ ["backhand index pointing left: medium-light skin tone"]={ 0x1F448, 0x1F3FC },
+ ["backhand index pointing right"]={ 0x1F449 },
+ ["backhand index pointing right: dark skin tone"]={ 0x1F449, 0x1F3FF },
+ ["backhand index pointing right: light skin tone"]={ 0x1F449, 0x1F3FB },
+ ["backhand index pointing right: medium skin tone"]={ 0x1F449, 0x1F3FD },
+ ["backhand index pointing right: medium-dark skin tone"]={ 0x1F449, 0x1F3FE },
+ ["backhand index pointing right: medium-light skin tone"]={ 0x1F449, 0x1F3FC },
+ ["backhand index pointing up"]={ 0x1F446 },
+ ["backhand index pointing up: dark skin tone"]={ 0x1F446, 0x1F3FF },
+ ["backhand index pointing up: light skin tone"]={ 0x1F446, 0x1F3FB },
+ ["backhand index pointing up: medium skin tone"]={ 0x1F446, 0x1F3FD },
+ ["backhand index pointing up: medium-dark skin tone"]={ 0x1F446, 0x1F3FE },
+ ["backhand index pointing up: medium-light skin tone"]={ 0x1F446, 0x1F3FC },
+ ["bacon"]={ 0x1F953 },
+ ["badminton"]={ 0x1F3F8 },
+ ["baggage claim"]={ 0x1F6C4 },
+ ["baguette bread"]={ 0x1F956 },
+ ["bahamas"]={ 0x1F1E7, 0x1F1F8 },
+ ["bahrain"]={ 0x1F1E7, 0x1F1ED },
+ ["balance scale"]={ 0x2696 },
+ ["balloon"]={ 0x1F388 },
+ ["ballot box with ballot"]={ 0x1F5F3 },
+ ["ballot box with check"]={ 0x2611 },
+ ["banana"]={ 0x1F34C },
+ ["bangladesh"]={ 0x1F1E7, 0x1F1E9 },
+ ["bank"]={ 0x1F3E6 },
+ ["bar chart"]={ 0x1F4CA },
+ ["barbados"]={ 0x1F1E7, 0x1F1E7 },
+ ["barber pole"]={ 0x1F488 },
+ ["baseball"]={ 0x26BE },
+ ["basketball"]={ 0x1F3C0 },
+ ["bat"]={ 0x1F987 },
+ ["bathtub"]={ 0x1F6C1 },
+ ["battery"]={ 0x1F50B },
+ ["beach with umbrella"]={ 0x1F3D6 },
+ ["bear face"]={ 0x1F43B },
+ ["bearded person"]={ 0x1F9D4 },
+ ["bearded person: dark skin tone"]={ 0x1F9D4, 0x1F3FF },
+ ["bearded person: light skin tone"]={ 0x1F9D4, 0x1F3FB },
+ ["bearded person: medium skin tone"]={ 0x1F9D4, 0x1F3FD },
+ ["bearded person: medium-dark skin tone"]={ 0x1F9D4, 0x1F3FE },
+ ["bearded person: medium-light skin tone"]={ 0x1F9D4, 0x1F3FC },
+ ["beating heart"]={ 0x1F493 },
+ ["bed"]={ 0x1F6CF },
+ ["beer mug"]={ 0x1F37A },
+ ["belarus"]={ 0x1F1E7, 0x1F1FE },
+ ["belgium"]={ 0x1F1E7, 0x1F1EA },
+ ["belize"]={ 0x1F1E7, 0x1F1FF },
+ ["bell"]={ 0x1F514 },
+ ["bell with slash"]={ 0x1F515 },
+ ["bellhop bell"]={ 0x1F6CE },
+ ["benin"]={ 0x1F1E7, 0x1F1EF },
+ ["bento box"]={ 0x1F371 },
+ ["bermuda"]={ 0x1F1E7, 0x1F1F2 },
+ ["bhutan"]={ 0x1F1E7, 0x1F1F9 },
+ ["bicycle"]={ 0x1F6B2 },
+ ["bikini"]={ 0x1F459 },
+ ["billed cap"]={ 0x1F9E2 },
+ ["biohazard"]={ 0x2623 },
+ ["bird"]={ 0x1F426 },
+ ["birthday cake"]={ 0x1F382 },
+ ["black circle"]={ 0x26AB },
+ ["black flag"]={ 0x1F3F4 },
+ ["black heart"]={ 0x1F5A4 },
+ ["black large square"]={ 0x2B1B },
+ ["black medium square"]={ 0x25FC },
+ ["black medium-small square"]={ 0x25FE },
+ ["black nib"]={ 0x2712 },
+ ["black small square"]={ 0x25AA },
+ ["black square button"]={ 0x1F532 },
+ ["blond-haired man"]={ 0x1F471, 0x200D, 0x2642 },
+ ["blond-haired man: dark skin tone"]={ 0x1F471, 0x1F3FF, 0x200D, 0x2642 },
+ ["blond-haired man: light skin tone"]={ 0x1F471, 0x1F3FB, 0x200D, 0x2642 },
+ ["blond-haired man: medium skin tone"]={ 0x1F471, 0x1F3FD, 0x200D, 0x2642 },
+ ["blond-haired man: medium-dark skin tone"]={ 0x1F471, 0x1F3FE, 0x200D, 0x2642 },
+ ["blond-haired man: medium-light skin tone"]={ 0x1F471, 0x1F3FC, 0x200D, 0x2642 },
+ ["blond-haired person"]={ 0x1F471 },
+ ["blond-haired person: dark skin tone"]={ 0x1F471, 0x1F3FF },
+ ["blond-haired person: light skin tone"]={ 0x1F471, 0x1F3FB },
+ ["blond-haired person: medium skin tone"]={ 0x1F471, 0x1F3FD },
+ ["blond-haired person: medium-dark skin tone"]={ 0x1F471, 0x1F3FE },
+ ["blond-haired person: medium-light skin tone"]={ 0x1F471, 0x1F3FC },
+ ["blond-haired woman"]={ 0x1F471, 0x200D, 0x2640 },
+ ["blond-haired woman: dark skin tone"]={ 0x1F471, 0x1F3FF, 0x200D, 0x2640 },
+ ["blond-haired woman: light skin tone"]={ 0x1F471, 0x1F3FB, 0x200D, 0x2640 },
+ ["blond-haired woman: medium skin tone"]={ 0x1F471, 0x1F3FD, 0x200D, 0x2640 },
+ ["blond-haired woman: medium-dark skin tone"]={ 0x1F471, 0x1F3FE, 0x200D, 0x2640 },
+ ["blond-haired woman: medium-light skin tone"]={ 0x1F471, 0x1F3FC, 0x200D, 0x2640 },
+ ["blossom"]={ 0x1F33C },
+ ["blowfish"]={ 0x1F421 },
+ ["blue book"]={ 0x1F4D8 },
+ ["blue circle"]={ 0x1F535 },
+ ["blue heart"]={ 0x1F499 },
+ ["boar"]={ 0x1F417 },
+ ["bolivia"]={ 0x1F1E7, 0x1F1F4 },
+ ["bomb"]={ 0x1F4A3 },
+ ["bookmark"]={ 0x1F516 },
+ ["bookmark tabs"]={ 0x1F4D1 },
+ ["books"]={ 0x1F4DA },
+ ["bosnia & herzegovina"]={ 0x1F1E7, 0x1F1E6 },
+ ["botswana"]={ 0x1F1E7, 0x1F1FC },
+ ["bottle with popping cork"]={ 0x1F37E },
+ ["bouquet"]={ 0x1F490 },
+ ["bouvet island"]={ 0x1F1E7, 0x1F1FB },
+ ["bow and arrow"]={ 0x1F3F9 },
+ ["bowl with spoon"]={ 0x1F963 },
+ ["bowling"]={ 0x1F3B3 },
+ ["boxing glove"]={ 0x1F94A },
+ ["boy"]={ 0x1F466 },
+ ["boy: dark skin tone"]={ 0x1F466, 0x1F3FF },
+ ["boy: light skin tone"]={ 0x1F466, 0x1F3FB },
+ ["boy: medium skin tone"]={ 0x1F466, 0x1F3FD },
+ ["boy: medium-dark skin tone"]={ 0x1F466, 0x1F3FE },
+ ["boy: medium-light skin tone"]={ 0x1F466, 0x1F3FC },
+ ["brain"]={ 0x1F9E0 },
+ ["brazil"]={ 0x1F1E7, 0x1F1F7 },
+ ["bread"]={ 0x1F35E },
+ ["breast-feeding"]={ 0x1F931 },
+ ["breast-feeding: dark skin tone"]={ 0x1F931, 0x1F3FF },
+ ["breast-feeding: light skin tone"]={ 0x1F931, 0x1F3FB },
+ ["breast-feeding: medium skin tone"]={ 0x1F931, 0x1F3FD },
+ ["breast-feeding: medium-dark skin tone"]={ 0x1F931, 0x1F3FE },
+ ["breast-feeding: medium-light skin tone"]={ 0x1F931, 0x1F3FC },
+ ["bride with veil"]={ 0x1F470 },
+ ["bride with veil: dark skin tone"]={ 0x1F470, 0x1F3FF },
+ ["bride with veil: light skin tone"]={ 0x1F470, 0x1F3FB },
+ ["bride with veil: medium skin tone"]={ 0x1F470, 0x1F3FD },
+ ["bride with veil: medium-dark skin tone"]={ 0x1F470, 0x1F3FE },
+ ["bride with veil: medium-light skin tone"]={ 0x1F470, 0x1F3FC },
+ ["bridge at night"]={ 0x1F309 },
+ ["briefcase"]={ 0x1F4BC },
+ ["bright button"]={ 0x1F506 },
+ ["british indian ocean territory"]={ 0x1F1EE, 0x1F1F4 },
+ ["british virgin islands"]={ 0x1F1FB, 0x1F1EC },
+ ["broccoli"]={ 0x1F966 },
+ ["broken heart"]={ 0x1F494 },
+ ["brunei"]={ 0x1F1E7, 0x1F1F3 },
+ ["bug"]={ 0x1F41B },
+ ["building construction"]={ 0x1F3D7 },
+ ["bulgaria"]={ 0x1F1E7, 0x1F1EC },
+ ["burkina faso"]={ 0x1F1E7, 0x1F1EB },
+ ["burrito"]={ 0x1F32F },
+ ["burundi"]={ 0x1F1E7, 0x1F1EE },
+ ["bus"]={ 0x1F68C },
+ ["bus stop"]={ 0x1F68F },
+ ["bust in silhouette"]={ 0x1F464 },
+ ["busts in silhouette"]={ 0x1F465 },
+ ["butterfly"]={ 0x1F98B },
+ ["cactus"]={ 0x1F335 },
+ ["calendar"]={ 0x1F4C5 },
+ ["call me hand"]={ 0x1F919 },
+ ["call me hand: dark skin tone"]={ 0x1F919, 0x1F3FF },
+ ["call me hand: light skin tone"]={ 0x1F919, 0x1F3FB },
+ ["call me hand: medium skin tone"]={ 0x1F919, 0x1F3FD },
+ ["call me hand: medium-dark skin tone"]={ 0x1F919, 0x1F3FE },
+ ["call me hand: medium-light skin tone"]={ 0x1F919, 0x1F3FC },
+ ["cambodia"]={ 0x1F1F0, 0x1F1ED },
+ ["camel"]={ 0x1F42A },
+ ["camera"]={ 0x1F4F7 },
+ ["camera with flash"]={ 0x1F4F8 },
+ ["cameroon"]={ 0x1F1E8, 0x1F1F2 },
+ ["camping"]={ 0x1F3D5 },
+ ["canada"]={ 0x1F1E8, 0x1F1E6 },
+ ["canary islands"]={ 0x1F1EE, 0x1F1E8 },
+ ["cancer"]={ 0x264B },
+ ["candle"]={ 0x1F56F },
+ ["candy"]={ 0x1F36C },
+ ["canned food"]={ 0x1F96B },
+ ["canoe"]={ 0x1F6F6 },
+ ["cape verde"]={ 0x1F1E8, 0x1F1FB },
+ ["capricorn"]={ 0x2651 },
+ ["card file box"]={ 0x1F5C3 },
+ ["card index"]={ 0x1F4C7 },
+ ["card index dividers"]={ 0x1F5C2 },
+ ["caribbean netherlands"]={ 0x1F1E7, 0x1F1F6 },
+ ["carousel horse"]={ 0x1F3A0 },
+ ["carp streamer"]={ 0x1F38F },
+ ["carrot"]={ 0x1F955 },
+ ["castle"]={ 0x1F3F0 },
+ ["cat"]={ 0x1F408 },
+ ["cat face"]={ 0x1F431 },
+ ["cat face with tears of joy"]={ 0x1F639 },
+ ["cat face with wry smile"]={ 0x1F63C },
+ ["cayman islands"]={ 0x1F1F0, 0x1F1FE },
+ ["central african republic"]={ 0x1F1E8, 0x1F1EB },
+ ["ceuta & melilla"]={ 0x1F1EA, 0x1F1E6 },
+ ["chad"]={ 0x1F1F9, 0x1F1E9 },
+ ["chains"]={ 0x26D3 },
+ ["chart decreasing"]={ 0x1F4C9 },
+ ["chart increasing"]={ 0x1F4C8 },
+ ["chart increasing with yen"]={ 0x1F4B9 },
+ ["cheese wedge"]={ 0x1F9C0 },
+ ["chequered flag"]={ 0x1F3C1 },
+ ["cherries"]={ 0x1F352 },
+ ["cherry blossom"]={ 0x1F338 },
+ ["chestnut"]={ 0x1F330 },
+ ["chicken"]={ 0x1F414 },
+ ["child"]={ 0x1F9D2 },
+ ["child: dark skin tone"]={ 0x1F9D2, 0x1F3FF },
+ ["child: light skin tone"]={ 0x1F9D2, 0x1F3FB },
+ ["child: medium skin tone"]={ 0x1F9D2, 0x1F3FD },
+ ["child: medium-dark skin tone"]={ 0x1F9D2, 0x1F3FE },
+ ["child: medium-light skin tone"]={ 0x1F9D2, 0x1F3FC },
+ ["children crossing"]={ 0x1F6B8 },
+ ["chile"]={ 0x1F1E8, 0x1F1F1 },
+ ["china"]={ 0x1F1E8, 0x1F1F3 },
+ ["chipmunk"]={ 0x1F43F },
+ ["chocolate bar"]={ 0x1F36B },
+ ["chopsticks"]={ 0x1F962 },
+ ["christmas island"]={ 0x1F1E8, 0x1F1FD },
+ ["christmas tree"]={ 0x1F384 },
+ ["church"]={ 0x26EA },
+ ["cigarette"]={ 0x1F6AC },
+ ["cinema"]={ 0x1F3A6 },
+ ["circled m"]={ 0x24C2 },
+ ["circus tent"]={ 0x1F3AA },
+ ["cityscape"]={ 0x1F3D9 },
+ ["cityscape at dusk"]={ 0x1F306 },
+ ["cl button"]={ 0x1F191 },
+ ["clamp"]={ 0x1F5DC },
+ ["clapper board"]={ 0x1F3AC },
+ ["clapping hands"]={ 0x1F44F },
+ ["clapping hands: dark skin tone"]={ 0x1F44F, 0x1F3FF },
+ ["clapping hands: light skin tone"]={ 0x1F44F, 0x1F3FB },
+ ["clapping hands: medium skin tone"]={ 0x1F44F, 0x1F3FD },
+ ["clapping hands: medium-dark skin tone"]={ 0x1F44F, 0x1F3FE },
+ ["clapping hands: medium-light skin tone"]={ 0x1F44F, 0x1F3FC },
+ ["classical building"]={ 0x1F3DB },
+ ["clinking beer mugs"]={ 0x1F37B },
+ ["clinking glasses"]={ 0x1F942 },
+ ["clipboard"]={ 0x1F4CB },
+ ["clipperton island"]={ 0x1F1E8, 0x1F1F5 },
+ ["clockwise vertical arrows"]={ 0x1F503 },
+ ["closed book"]={ 0x1F4D5 },
+ ["closed mailbox with lowered flag"]={ 0x1F4EA },
+ ["closed mailbox with raised flag"]={ 0x1F4EB },
+ ["closed umbrella"]={ 0x1F302 },
+ ["cloud"]={ 0x2601 },
+ ["cloud with lightning"]={ 0x1F329 },
+ ["cloud with lightning and rain"]={ 0x26C8 },
+ ["cloud with rain"]={ 0x1F327 },
+ ["cloud with snow"]={ 0x1F328 },
+ ["clown face"]={ 0x1F921 },
+ ["club suit"]={ 0x2663 },
+ ["clutch bag"]={ 0x1F45D },
+ ["coat"]={ 0x1F9E5 },
+ ["cocktail glass"]={ 0x1F378 },
+ ["coconut"]={ 0x1F965 },
+ ["cocos (keeling) islands"]={ 0x1F1E8, 0x1F1E8 },
+ ["coffin"]={ 0x26B0 },
+ ["collision"]={ 0x1F4A5 },
+ ["colombia"]={ 0x1F1E8, 0x1F1F4 },
+ ["comet"]={ 0x2604 },
+ ["comoros"]={ 0x1F1F0, 0x1F1F2 },
+ ["computer disk"]={ 0x1F4BD },
+ ["computer mouse"]={ 0x1F5B1 },
+ ["confetti ball"]={ 0x1F38A },
+ ["confounded face"]={ 0x1F616 },
+ ["confused face"]={ 0x1F615 },
+ ["congo - brazzaville"]={ 0x1F1E8, 0x1F1EC },
+ ["congo - kinshasa"]={ 0x1F1E8, 0x1F1E9 },
+ ["construction"]={ 0x1F6A7 },
+ ["construction worker"]={ 0x1F477 },
+ ["construction worker: dark skin tone"]={ 0x1F477, 0x1F3FF },
+ ["construction worker: light skin tone"]={ 0x1F477, 0x1F3FB },
+ ["construction worker: medium skin tone"]={ 0x1F477, 0x1F3FD },
+ ["construction worker: medium-dark skin tone"]={ 0x1F477, 0x1F3FE },
+ ["construction worker: medium-light skin tone"]={ 0x1F477, 0x1F3FC },
+ ["control knobs"]={ 0x1F39B },
+ ["convenience store"]={ 0x1F3EA },
+ ["cook islands"]={ 0x1F1E8, 0x1F1F0 },
+ ["cooked rice"]={ 0x1F35A },
+ ["cookie"]={ 0x1F36A },
+ ["cooking"]={ 0x1F373 },
+ ["cool button"]={ 0x1F192 },
+ ["copyright"]={ 0xA9 },
+ ["costa rica"]={ 0x1F1E8, 0x1F1F7 },
+ ["couch and lamp"]={ 0x1F6CB },
+ ["couple with heart"]={ 0x1F491 },
+ ["couple with heart: man, man"]={ 0x1F468, 0x200D, 0x2764, 0x200D, 0x1F468 },
+ ["couple with heart: woman, man"]={ 0x1F469, 0x200D, 0x2764, 0x200D, 0x1F468 },
+ ["couple with heart: woman, woman"]={ 0x1F469, 0x200D, 0x2764, 0x200D, 0x1F469 },
+ ["cow"]={ 0x1F404 },
+ ["cow face"]={ 0x1F42E },
+ ["cowboy hat face"]={ 0x1F920 },
+ ["crab"]={ 0x1F980 },
+ ["crayon"]={ 0x1F58D },
+ ["crazy face"]={ 0x1F92A },
+ ["credit card"]={ 0x1F4B3 },
+ ["crescent moon"]={ 0x1F319 },
+ ["cricket"]={ 0x1F3CF },
+ ["croatia"]={ 0x1F1ED, 0x1F1F7 },
+ ["crocodile"]={ 0x1F40A },
+ ["croissant"]={ 0x1F950 },
+ ["cross mark"]={ 0x274C },
+ ["cross mark button"]={ 0x274E },
+ ["crossed fingers"]={ 0x1F91E },
+ ["crossed fingers: dark skin tone"]={ 0x1F91E, 0x1F3FF },
+ ["crossed fingers: light skin tone"]={ 0x1F91E, 0x1F3FB },
+ ["crossed fingers: medium skin tone"]={ 0x1F91E, 0x1F3FD },
+ ["crossed fingers: medium-dark skin tone"]={ 0x1F91E, 0x1F3FE },
+ ["crossed fingers: medium-light skin tone"]={ 0x1F91E, 0x1F3FC },
+ ["crossed flags"]={ 0x1F38C },
+ ["crossed swords"]={ 0x2694 },
+ ["crown"]={ 0x1F451 },
+ ["crying cat face"]={ 0x1F63F },
+ ["crying face"]={ 0x1F622 },
+ ["crystal ball"]={ 0x1F52E },
+ ["cuba"]={ 0x1F1E8, 0x1F1FA },
+ ["cucumber"]={ 0x1F952 },
+ ["cup with straw"]={ 0x1F964 },
+ ["curaçao"]={ 0x1F1E8, 0x1F1FC },
+ ["curling stone"]={ 0x1F94C },
+ ["curly loop"]={ 0x27B0 },
+ ["currency exchange"]={ 0x1F4B1 },
+ ["curry rice"]={ 0x1F35B },
+ ["custard"]={ 0x1F36E },
+ ["customs"]={ 0x1F6C3 },
+ ["cut of meat"]={ 0x1F969 },
+ ["cyclone"]={ 0x1F300 },
+ ["cyprus"]={ 0x1F1E8, 0x1F1FE },
+ ["czechia"]={ 0x1F1E8, 0x1F1FF },
+ ["côte d’ivoire"]={ 0x1F1E8, 0x1F1EE },
+ ["dagger"]={ 0x1F5E1 },
+ ["dango"]={ 0x1F361 },
+ ["dashing away"]={ 0x1F4A8 },
+ ["deciduous tree"]={ 0x1F333 },
+ ["deer"]={ 0x1F98C },
+ ["delivery truck"]={ 0x1F69A },
+ ["denmark"]={ 0x1F1E9, 0x1F1F0 },
+ ["department store"]={ 0x1F3EC },
+ ["derelict house"]={ 0x1F3DA },
+ ["desert"]={ 0x1F3DC },
+ ["desert island"]={ 0x1F3DD },
+ ["desktop computer"]={ 0x1F5A5 },
+ ["detective"]={ 0x1F575 },
+ ["detective: dark skin tone"]={ 0x1F575, 0x1F3FF },
+ ["detective: light skin tone"]={ 0x1F575, 0x1F3FB },
+ ["detective: medium skin tone"]={ 0x1F575, 0x1F3FD },
+ ["detective: medium-dark skin tone"]={ 0x1F575, 0x1F3FE },
+ ["detective: medium-light skin tone"]={ 0x1F575, 0x1F3FC },
+ ["diamond suit"]={ 0x2666 },
+ ["diamond with a dot"]={ 0x1F4A0 },
+ ["diego garcia"]={ 0x1F1E9, 0x1F1EC },
+ ["dim button"]={ 0x1F505 },
+ ["direct hit"]={ 0x1F3AF },
+ ["disappointed but relieved face"]={ 0x1F625 },
+ ["disappointed face"]={ 0x1F61E },
+ ["dizzy"]={ 0x1F4AB },
+ ["dizzy face"]={ 0x1F635 },
+ ["djibouti"]={ 0x1F1E9, 0x1F1EF },
+ ["dog"]={ 0x1F415 },
+ ["dog face"]={ 0x1F436 },
+ ["dollar banknote"]={ 0x1F4B5 },
+ ["dolphin"]={ 0x1F42C },
+ ["dominica"]={ 0x1F1E9, 0x1F1F2 },
+ ["dominican republic"]={ 0x1F1E9, 0x1F1F4 },
+ ["door"]={ 0x1F6AA },
+ ["dotted six-pointed star"]={ 0x1F52F },
+ ["double curly loop"]={ 0x27BF },
+ ["double exclamation mark"]={ 0x203C },
+ ["doughnut"]={ 0x1F369 },
+ ["dove"]={ 0x1F54A },
+ ["down arrow"]={ 0x2B07 },
+ ["down button"]={ 0x1F53D },
+ ["down-left arrow"]={ 0x2199 },
+ ["down-right arrow"]={ 0x2198 },
+ ["dragon"]={ 0x1F409 },
+ ["dragon face"]={ 0x1F432 },
+ ["dress"]={ 0x1F457 },
+ ["drooling face"]={ 0x1F924 },
+ ["droplet"]={ 0x1F4A7 },
+ ["drum"]={ 0x1F941 },
+ ["duck"]={ 0x1F986 },
+ ["dumpling"]={ 0x1F95F },
+ ["dvd"]={ 0x1F4C0 },
+ ["e-mail"]={ 0x1F4E7 },
+ ["eagle"]={ 0x1F985 },
+ ["ear"]={ 0x1F442 },
+ ["ear of corn"]={ 0x1F33D },
+ ["ear: dark skin tone"]={ 0x1F442, 0x1F3FF },
+ ["ear: light skin tone"]={ 0x1F442, 0x1F3FB },
+ ["ear: medium skin tone"]={ 0x1F442, 0x1F3FD },
+ ["ear: medium-dark skin tone"]={ 0x1F442, 0x1F3FE },
+ ["ear: medium-light skin tone"]={ 0x1F442, 0x1F3FC },
+ ["ecuador"]={ 0x1F1EA, 0x1F1E8 },
+ ["egg"]={ 0x1F95A },
+ ["eggplant"]={ 0x1F346 },
+ ["egypt"]={ 0x1F1EA, 0x1F1EC },
+ ["eight o’clock"]={ 0x1F557 },
+ ["eight-pointed star"]={ 0x2734 },
+ ["eight-spoked asterisk"]={ 0x2733 },
+ ["eight-thirty"]={ 0x1F563 },
+ ["eject button"]={ 0x23CF },
+ ["el salvador"]={ 0x1F1F8, 0x1F1FB },
+ ["electric plug"]={ 0x1F50C },
+ ["elephant"]={ 0x1F418 },
+ ["eleven o’clock"]={ 0x1F55A },
+ ["eleven-thirty"]={ 0x1F566 },
+ ["elf"]={ 0x1F9DD },
+ ["elf: dark skin tone"]={ 0x1F9DD, 0x1F3FF },
+ ["elf: light skin tone"]={ 0x1F9DD, 0x1F3FB },
+ ["elf: medium skin tone"]={ 0x1F9DD, 0x1F3FD },
+ ["elf: medium-dark skin tone"]={ 0x1F9DD, 0x1F3FE },
+ ["elf: medium-light skin tone"]={ 0x1F9DD, 0x1F3FC },
+ ["end arrow"]={ 0x1F51A },
+ ["england"]={ 0x1F3F4, 0xE0067, 0xE0062, 0xE0065, 0xE006E, 0xE0067, 0xE007F },
+ ["envelope"]={ 0x2709 },
+ ["envelope with arrow"]={ 0x1F4E9 },
+ ["equatorial guinea"]={ 0x1F1EC, 0x1F1F6 },
+ ["eritrea"]={ 0x1F1EA, 0x1F1F7 },
+ ["estonia"]={ 0x1F1EA, 0x1F1EA },
+ ["ethiopia"]={ 0x1F1EA, 0x1F1F9 },
+ ["euro banknote"]={ 0x1F4B6 },
+ ["european union"]={ 0x1F1EA, 0x1F1FA },
+ ["evergreen tree"]={ 0x1F332 },
+ ["ewe"]={ 0x1F411 },
+ ["exclamation mark"]={ 0x2757 },
+ ["exclamation question mark"]={ 0x2049 },
+ ["exploding head"]={ 0x1F92F },
+ ["expressionless face"]={ 0x1F611 },
+ ["eye"]={ 0x1F441 },
+ ["eye in speech bubble"]={ 0x1F441, 0x200D, 0x1F5E8 },
+ ["eyes"]={ 0x1F440 },
+ ["face blowing a kiss"]={ 0x1F618 },
+ ["face savouring delicious food"]={ 0x1F60B },
+ ["face screaming in fear"]={ 0x1F631 },
+ ["face vomiting"]={ 0x1F92E },
+ ["face with cold sweat"]={ 0x1F613 },
+ ["face with hand over mouth"]={ 0x1F92D },
+ ["face with head-bandage"]={ 0x1F915 },
+ ["face with medical mask"]={ 0x1F637 },
+ ["face with monocle"]={ 0x1F9D0 },
+ ["face with open mouth"]={ 0x1F62E },
+ ["face with open mouth & cold sweat"]={ 0x1F630 },
+ ["face with raised eyebrow"]={ 0x1F928 },
+ ["face with rolling eyes"]={ 0x1F644 },
+ ["face with steam from nose"]={ 0x1F624 },
+ ["face with stuck-out tongue"]={ 0x1F61B },
+ ["face with stuck-out tongue & closed eyes"]={ 0x1F61D },
+ ["face with stuck-out tongue & winking eye"]={ 0x1F61C },
+ ["face with symbols over mouth"]={ 0x1F92C },
+ ["face with tears of joy"]={ 0x1F602 },
+ ["face with thermometer"]={ 0x1F912 },
+ ["face without mouth"]={ 0x1F636 },
+ ["factory"]={ 0x1F3ED },
+ ["fairy"]={ 0x1F9DA },
+ ["fairy: dark skin tone"]={ 0x1F9DA, 0x1F3FF },
+ ["fairy: light skin tone"]={ 0x1F9DA, 0x1F3FB },
+ ["fairy: medium skin tone"]={ 0x1F9DA, 0x1F3FD },
+ ["fairy: medium-dark skin tone"]={ 0x1F9DA, 0x1F3FE },
+ ["fairy: medium-light skin tone"]={ 0x1F9DA, 0x1F3FC },
+ ["falkland islands"]={ 0x1F1EB, 0x1F1F0 },
+ ["fallen leaf"]={ 0x1F342 },
+ ["family"]={ 0x1F46A },
+ ["family: man, boy"]={ 0x1F468, 0x200D, 0x1F466 },
+ ["family: man, boy, boy"]={ 0x1F468, 0x200D, 0x1F466, 0x200D, 0x1F466 },
+ ["family: man, girl"]={ 0x1F468, 0x200D, 0x1F467 },
+ ["family: man, girl, boy"]={ 0x1F468, 0x200D, 0x1F467, 0x200D, 0x1F466 },
+ ["family: man, girl, girl"]={ 0x1F468, 0x200D, 0x1F467, 0x200D, 0x1F467 },
+ ["family: man, man, boy"]={ 0x1F468, 0x200D, 0x1F468, 0x200D, 0x1F466 },
+ ["family: man, man, boy, boy"]={ 0x1F468, 0x200D, 0x1F468, 0x200D, 0x1F466, 0x200D, 0x1F466 },
+ ["family: man, man, girl"]={ 0x1F468, 0x200D, 0x1F468, 0x200D, 0x1F467 },
+ ["family: man, man, girl, boy"]={ 0x1F468, 0x200D, 0x1F468, 0x200D, 0x1F467, 0x200D, 0x1F466 },
+ ["family: man, man, girl, girl"]={ 0x1F468, 0x200D, 0x1F468, 0x200D, 0x1F467, 0x200D, 0x1F467 },
+ ["family: man, woman, boy"]={ 0x1F468, 0x200D, 0x1F469, 0x200D, 0x1F466 },
+ ["family: man, woman, boy, boy"]={ 0x1F468, 0x200D, 0x1F469, 0x200D, 0x1F466, 0x200D, 0x1F466 },
+ ["family: man, woman, girl"]={ 0x1F468, 0x200D, 0x1F469, 0x200D, 0x1F467 },
+ ["family: man, woman, girl, boy"]={ 0x1F468, 0x200D, 0x1F469, 0x200D, 0x1F467, 0x200D, 0x1F466 },
+ ["family: man, woman, girl, girl"]={ 0x1F468, 0x200D, 0x1F469, 0x200D, 0x1F467, 0x200D, 0x1F467 },
+ ["family: woman, boy"]={ 0x1F469, 0x200D, 0x1F466 },
+ ["family: woman, boy, boy"]={ 0x1F469, 0x200D, 0x1F466, 0x200D, 0x1F466 },
+ ["family: woman, girl"]={ 0x1F469, 0x200D, 0x1F467 },
+ ["family: woman, girl, boy"]={ 0x1F469, 0x200D, 0x1F467, 0x200D, 0x1F466 },
+ ["family: woman, girl, girl"]={ 0x1F469, 0x200D, 0x1F467, 0x200D, 0x1F467 },
+ ["family: woman, woman, boy"]={ 0x1F469, 0x200D, 0x1F469, 0x200D, 0x1F466 },
+ ["family: woman, woman, boy, boy"]={ 0x1F469, 0x200D, 0x1F469, 0x200D, 0x1F466, 0x200D, 0x1F466 },
+ ["family: woman, woman, girl"]={ 0x1F469, 0x200D, 0x1F469, 0x200D, 0x1F467 },
+ ["family: woman, woman, girl, boy"]={ 0x1F469, 0x200D, 0x1F469, 0x200D, 0x1F467, 0x200D, 0x1F466 },
+ ["family: woman, woman, girl, girl"]={ 0x1F469, 0x200D, 0x1F469, 0x200D, 0x1F467, 0x200D, 0x1F467 },
+ ["faroe islands"]={ 0x1F1EB, 0x1F1F4 },
+ ["fast down button"]={ 0x23EC },
+ ["fast reverse button"]={ 0x23EA },
+ ["fast up button"]={ 0x23EB },
+ ["fast-forward button"]={ 0x23E9 },
+ ["fax machine"]={ 0x1F4E0 },
+ ["fearful face"]={ 0x1F628 },
+ ["female sign"]={ 0x2640 },
+ ["ferris wheel"]={ 0x1F3A1 },
+ ["ferry"]={ 0x26F4 },
+ ["field hockey"]={ 0x1F3D1 },
+ ["fiji"]={ 0x1F1EB, 0x1F1EF },
+ ["file cabinet"]={ 0x1F5C4 },
+ ["file folder"]={ 0x1F4C1 },
+ ["film frames"]={ 0x1F39E },
+ ["film projector"]={ 0x1F4FD },
+ ["finland"]={ 0x1F1EB, 0x1F1EE },
+ ["fire"]={ 0x1F525 },
+ ["fire engine"]={ 0x1F692 },
+ ["fireworks"]={ 0x1F386 },
+ ["first quarter moon"]={ 0x1F313 },
+ ["first quarter moon with face"]={ 0x1F31B },
+ ["fish"]={ 0x1F41F },
+ ["fish cake with swirl"]={ 0x1F365 },
+ ["fishing pole"]={ 0x1F3A3 },
+ ["five o’clock"]={ 0x1F554 },
+ ["five-thirty"]={ 0x1F560 },
+ ["flag in hole"]={ 0x26F3 },
+ ["flashlight"]={ 0x1F526 },
+ ["fleur-de-lis"]={ 0x269C },
+ ["flexed biceps"]={ 0x1F4AA },
+ ["flexed biceps: dark skin tone"]={ 0x1F4AA, 0x1F3FF },
+ ["flexed biceps: light skin tone"]={ 0x1F4AA, 0x1F3FB },
+ ["flexed biceps: medium skin tone"]={ 0x1F4AA, 0x1F3FD },
+ ["flexed biceps: medium-dark skin tone"]={ 0x1F4AA, 0x1F3FE },
+ ["flexed biceps: medium-light skin tone"]={ 0x1F4AA, 0x1F3FC },
+ ["floppy disk"]={ 0x1F4BE },
+ ["flower playing cards"]={ 0x1F3B4 },
+ ["flushed face"]={ 0x1F633 },
+ ["flying saucer"]={ 0x1F6F8 },
+ ["fog"]={ 0x1F32B },
+ ["foggy"]={ 0x1F301 },
+ ["folded hands"]={ 0x1F64F },
+ ["folded hands: dark skin tone"]={ 0x1F64F, 0x1F3FF },
+ ["folded hands: light skin tone"]={ 0x1F64F, 0x1F3FB },
+ ["folded hands: medium skin tone"]={ 0x1F64F, 0x1F3FD },
+ ["folded hands: medium-dark skin tone"]={ 0x1F64F, 0x1F3FE },
+ ["folded hands: medium-light skin tone"]={ 0x1F64F, 0x1F3FC },
+ ["footprints"]={ 0x1F463 },
+ ["fork and knife"]={ 0x1F374 },
+ ["fork and knife with plate"]={ 0x1F37D },
+ ["fortune cookie"]={ 0x1F960 },
+ ["fountain"]={ 0x26F2 },
+ ["fountain pen"]={ 0x1F58B },
+ ["four leaf clover"]={ 0x1F340 },
+ ["four o’clock"]={ 0x1F553 },
+ ["four-thirty"]={ 0x1F55F },
+ ["fox face"]={ 0x1F98A },
+ ["framed picture"]={ 0x1F5BC },
+ ["france"]={ 0x1F1EB, 0x1F1F7 },
+ ["free button"]={ 0x1F193 },
+ ["french fries"]={ 0x1F35F },
+ ["french guiana"]={ 0x1F1EC, 0x1F1EB },
+ ["french polynesia"]={ 0x1F1F5, 0x1F1EB },
+ ["french southern territories"]={ 0x1F1F9, 0x1F1EB },
+ ["fried shrimp"]={ 0x1F364 },
+ ["frog face"]={ 0x1F438 },
+ ["front-facing baby chick"]={ 0x1F425 },
+ ["frowning face"]={ 0x2639 },
+ ["frowning face with open mouth"]={ 0x1F626 },
+ ["fuel pump"]={ 0x26FD },
+ ["full moon"]={ 0x1F315 },
+ ["full moon with face"]={ 0x1F31D },
+ ["funeral urn"]={ 0x26B1 },
+ ["gabon"]={ 0x1F1EC, 0x1F1E6 },
+ ["gambia"]={ 0x1F1EC, 0x1F1F2 },
+ ["game die"]={ 0x1F3B2 },
+ ["gear"]={ 0x2699 },
+ ["gem stone"]={ 0x1F48E },
+ ["gemini"]={ 0x264A },
+ ["genie"]={ 0x1F9DE },
+ ["georgia"]={ 0x1F1EC, 0x1F1EA },
+ ["germany"]={ 0x1F1E9, 0x1F1EA },
+ ["ghana"]={ 0x1F1EC, 0x1F1ED },
+ ["ghost"]={ 0x1F47B },
+ ["gibraltar"]={ 0x1F1EC, 0x1F1EE },
+ ["giraffe"]={ 0x1F992 },
+ ["girl"]={ 0x1F467 },
+ ["girl: dark skin tone"]={ 0x1F467, 0x1F3FF },
+ ["girl: light skin tone"]={ 0x1F467, 0x1F3FB },
+ ["girl: medium skin tone"]={ 0x1F467, 0x1F3FD },
+ ["girl: medium-dark skin tone"]={ 0x1F467, 0x1F3FE },
+ ["girl: medium-light skin tone"]={ 0x1F467, 0x1F3FC },
+ ["glass of milk"]={ 0x1F95B },
+ ["glasses"]={ 0x1F453 },
+ ["globe showing americas"]={ 0x1F30E },
+ ["globe showing asia-australia"]={ 0x1F30F },
+ ["globe showing europe-africa"]={ 0x1F30D },
+ ["globe with meridians"]={ 0x1F310 },
+ ["gloves"]={ 0x1F9E4 },
+ ["glowing star"]={ 0x1F31F },
+ ["goal net"]={ 0x1F945 },
+ ["goat"]={ 0x1F410 },
+ ["goblin"]={ 0x1F47A },
+ ["gorilla"]={ 0x1F98D },
+ ["graduation cap"]={ 0x1F393 },
+ ["grapes"]={ 0x1F347 },
+ ["greece"]={ 0x1F1EC, 0x1F1F7 },
+ ["green apple"]={ 0x1F34F },
+ ["green book"]={ 0x1F4D7 },
+ ["green heart"]={ 0x1F49A },
+ ["green salad"]={ 0x1F957 },
+ ["greenland"]={ 0x1F1EC, 0x1F1F1 },
+ ["grenada"]={ 0x1F1EC, 0x1F1E9 },
+ ["grimacing face"]={ 0x1F62C },
+ ["grinning cat face with smiling eyes"]={ 0x1F638 },
+ ["grinning face"]={ 0x1F600 },
+ ["grinning face with smiling eyes"]={ 0x1F601 },
+ ["growing heart"]={ 0x1F497 },
+ ["guadeloupe"]={ 0x1F1EC, 0x1F1F5 },
+ ["guam"]={ 0x1F1EC, 0x1F1FA },
+ ["guard"]={ 0x1F482 },
+ ["guard: dark skin tone"]={ 0x1F482, 0x1F3FF },
+ ["guard: light skin tone"]={ 0x1F482, 0x1F3FB },
+ ["guard: medium skin tone"]={ 0x1F482, 0x1F3FD },
+ ["guard: medium-dark skin tone"]={ 0x1F482, 0x1F3FE },
+ ["guard: medium-light skin tone"]={ 0x1F482, 0x1F3FC },
+ ["guatemala"]={ 0x1F1EC, 0x1F1F9 },
+ ["guernsey"]={ 0x1F1EC, 0x1F1EC },
+ ["guinea"]={ 0x1F1EC, 0x1F1F3 },
+ ["guinea-bissau"]={ 0x1F1EC, 0x1F1FC },
+ ["guitar"]={ 0x1F3B8 },
+ ["guyana"]={ 0x1F1EC, 0x1F1FE },
+ ["haiti"]={ 0x1F1ED, 0x1F1F9 },
+ ["hamburger"]={ 0x1F354 },
+ ["hammer"]={ 0x1F528 },
+ ["hammer and pick"]={ 0x2692 },
+ ["hammer and wrench"]={ 0x1F6E0 },
+ ["hamster face"]={ 0x1F439 },
+ ["handbag"]={ 0x1F45C },
+ ["handshake"]={ 0x1F91D },
+ ["hatching chick"]={ 0x1F423 },
+ ["headphone"]={ 0x1F3A7 },
+ ["hear-no-evil monkey"]={ 0x1F649 },
+ ["heard & mcdonald islands"]={ 0x1F1ED, 0x1F1F2 },
+ ["heart decoration"]={ 0x1F49F },
+ ["heart suit"]={ 0x2665 },
+ ["heart with arrow"]={ 0x1F498 },
+ ["heart with ribbon"]={ 0x1F49D },
+ ["heavy check mark"]={ 0x2714 },
+ ["heavy division sign"]={ 0x2797 },
+ ["heavy dollar sign"]={ 0x1F4B2 },
+ ["heavy heart exclamation"]={ 0x2763 },
+ ["heavy large circle"]={ 0x2B55 },
+ ["heavy minus sign"]={ 0x2796 },
+ ["heavy multiplication x"]={ 0x2716 },
+ ["heavy plus sign"]={ 0x2795 },
+ ["hedgehog"]={ 0x1F994 },
+ ["helicopter"]={ 0x1F681 },
+ ["herb"]={ 0x1F33F },
+ ["hibiscus"]={ 0x1F33A },
+ ["high voltage"]={ 0x26A1 },
+ ["high-heeled shoe"]={ 0x1F460 },
+ ["high-speed train"]={ 0x1F684 },
+ ["high-speed train with bullet nose"]={ 0x1F685 },
+ ["hole"]={ 0x1F573 },
+ ["honduras"]={ 0x1F1ED, 0x1F1F3 },
+ ["honey pot"]={ 0x1F36F },
+ ["honeybee"]={ 0x1F41D },
+ ["hong kong sar china"]={ 0x1F1ED, 0x1F1F0 },
+ ["horizontal traffic light"]={ 0x1F6A5 },
+ ["horse"]={ 0x1F40E },
+ ["horse face"]={ 0x1F434 },
+ ["horse racing"]={ 0x1F3C7 },
+ ["horse racing: dark skin tone"]={ 0x1F3C7, 0x1F3FF },
+ ["horse racing: light skin tone"]={ 0x1F3C7, 0x1F3FB },
+ ["horse racing: medium skin tone"]={ 0x1F3C7, 0x1F3FD },
+ ["horse racing: medium-dark skin tone"]={ 0x1F3C7, 0x1F3FE },
+ ["horse racing: medium-light skin tone"]={ 0x1F3C7, 0x1F3FC },
+ ["hospital"]={ 0x1F3E5 },
+ ["hot beverage"]={ 0x2615 },
+ ["hot dog"]={ 0x1F32D },
+ ["hot pepper"]={ 0x1F336 },
+ ["hot springs"]={ 0x2668 },
+ ["hotel"]={ 0x1F3E8 },
+ ["hourglass"]={ 0x231B },
+ ["hourglass with flowing sand"]={ 0x23F3 },
+ ["house"]={ 0x1F3E0 },
+ ["house with garden"]={ 0x1F3E1 },
+ ["hugging face"]={ 0x1F917 },
+ ["hundred points"]={ 0x1F4AF },
+ ["hungary"]={ 0x1F1ED, 0x1F1FA },
+ ["hushed face"]={ 0x1F62F },
+ ["ice cream"]={ 0x1F368 },
+ ["ice hockey"]={ 0x1F3D2 },
+ ["ice skate"]={ 0x26F8 },
+ ["iceland"]={ 0x1F1EE, 0x1F1F8 },
+ ["id button"]={ 0x1F194 },
+ ["inbox tray"]={ 0x1F4E5 },
+ ["incoming envelope"]={ 0x1F4E8 },
+ ["index pointing up"]={ 0x261D },
+ ["index pointing up: dark skin tone"]={ 0x261D, 0x1F3FF },
+ ["index pointing up: light skin tone"]={ 0x261D, 0x1F3FB },
+ ["index pointing up: medium skin tone"]={ 0x261D, 0x1F3FD },
+ ["index pointing up: medium-dark skin tone"]={ 0x261D, 0x1F3FE },
+ ["index pointing up: medium-light skin tone"]={ 0x261D, 0x1F3FC },
+ ["india"]={ 0x1F1EE, 0x1F1F3 },
+ ["indonesia"]={ 0x1F1EE, 0x1F1E9 },
+ ["information"]={ 0x2139 },
+ ["input latin letters"]={ 0x1F524 },
+ ["input latin lowercase"]={ 0x1F521 },
+ ["input latin uppercase"]={ 0x1F520 },
+ ["input numbers"]={ 0x1F522 },
+ ["input symbols"]={ 0x1F523 },
+ ["iran"]={ 0x1F1EE, 0x1F1F7 },
+ ["iraq"]={ 0x1F1EE, 0x1F1F6 },
+ ["ireland"]={ 0x1F1EE, 0x1F1EA },
+ ["isle of man"]={ 0x1F1EE, 0x1F1F2 },
+ ["israel"]={ 0x1F1EE, 0x1F1F1 },
+ ["italy"]={ 0x1F1EE, 0x1F1F9 },
+ ["jack-o-lantern"]={ 0x1F383 },
+ ["jamaica"]={ 0x1F1EF, 0x1F1F2 },
+ ["japan"]={ 0x1F1EF, 0x1F1F5 },
+ ["japanese castle"]={ 0x1F3EF },
+ ["japanese dolls"]={ 0x1F38E },
+ ["japanese post office"]={ 0x1F3E3 },
+ ["japanese symbol for beginner"]={ 0x1F530 },
+ ["japanese “acceptable” button"]={ 0x1F251 },
+ ["japanese “application” button"]={ 0x1F238 },
+ ["japanese “bargain” button"]={ 0x1F250 },
+ ["japanese “congratulations” button"]={ 0x3297 },
+ ["japanese “discount” button"]={ 0x1F239 },
+ ["japanese “free of charge” button"]={ 0x1F21A },
+ ["japanese “here” button"]={ 0x1F201 },
+ ["japanese “monthly amount” button"]={ 0x1F237 },
+ ["japanese “no vacancy” button"]={ 0x1F235 },
+ ["japanese “not free of charge” button"]={ 0x1F236 },
+ ["japanese “open for business” button"]={ 0x1F23A },
+ ["japanese “passing grade” button"]={ 0x1F234 },
+ ["japanese “prohibited” button"]={ 0x1F232 },
+ ["japanese “reserved” button"]={ 0x1F22F },
+ ["japanese “secret” button"]={ 0x3299 },
+ ["japanese “service charge” button"]={ 0x1F202 },
+ ["japanese “vacancy” button"]={ 0x1F233 },
+ ["jeans"]={ 0x1F456 },
+ ["jersey"]={ 0x1F1EF, 0x1F1EA },
+ ["joker"]={ 0x1F0CF },
+ ["jordan"]={ 0x1F1EF, 0x1F1F4 },
+ ["joystick"]={ 0x1F579 },
+ ["kaaba"]={ 0x1F54B },
+ ["kazakhstan"]={ 0x1F1F0, 0x1F1FF },
+ ["kenya"]={ 0x1F1F0, 0x1F1EA },
+ ["key"]={ 0x1F511 },
+ ["keyboard"]={ 0x2328 },
+ ["keycap 10"]={ 0x1F51F },
+ ["keycap: 0"]={ 0x30, 0x20E3 },
+ ["keycap: 1"]={ 0x31, 0x20E3 },
+ ["keycap: 2"]={ 0x32, 0x20E3 },
+ ["keycap: 3"]={ 0x33, 0x20E3 },
+ ["keycap: 4"]={ 0x34, 0x20E3 },
+ ["keycap: 5"]={ 0x35, 0x20E3 },
+ ["keycap: 6"]={ 0x36, 0x20E3 },
+ ["keycap: 7"]={ 0x37, 0x20E3 },
+ ["keycap: 8"]={ 0x38, 0x20E3 },
+ ["keycap: 9"]={ 0x39, 0x20E3 },
+ ["keycap: asterisk"]={ 0x2A, 0x20E3 },
+ ["keycap: hash"]={ 0x23, 0x20E3 },
+ ["kick scooter"]={ 0x1F6F4 },
+ ["kimono"]={ 0x1F458 },
+ ["kiribati"]={ 0x1F1F0, 0x1F1EE },
+ ["kiss"]={ 0x1F48F },
+ ["kiss mark"]={ 0x1F48B },
+ ["kiss: man, man"]={ 0x1F468, 0x200D, 0x2764, 0x200D, 0x1F48B, 0x200D, 0x1F468 },
+ ["kiss: woman, man"]={ 0x1F469, 0x200D, 0x2764, 0x200D, 0x1F48B, 0x200D, 0x1F468 },
+ ["kiss: woman, woman"]={ 0x1F469, 0x200D, 0x2764, 0x200D, 0x1F48B, 0x200D, 0x1F469 },
+ ["kissing cat face with closed eyes"]={ 0x1F63D },
+ ["kissing face"]={ 0x1F617 },
+ ["kissing face with closed eyes"]={ 0x1F61A },
+ ["kissing face with smiling eyes"]={ 0x1F619 },
+ ["kitchen knife"]={ 0x1F52A },
+ ["kiwi fruit"]={ 0x1F95D },
+ ["koala"]={ 0x1F428 },
+ ["kosovo"]={ 0x1F1FD, 0x1F1F0 },
+ ["kuwait"]={ 0x1F1F0, 0x1F1FC },
+ ["kyrgyzstan"]={ 0x1F1F0, 0x1F1EC },
+ ["label"]={ 0x1F3F7 },
+ ["lady beetle"]={ 0x1F41E },
+ ["laos"]={ 0x1F1F1, 0x1F1E6 },
+ ["laptop computer"]={ 0x1F4BB },
+ ["large blue diamond"]={ 0x1F537 },
+ ["large orange diamond"]={ 0x1F536 },
+ ["last quarter moon"]={ 0x1F317 },
+ ["last quarter moon with face"]={ 0x1F31C },
+ ["last track button"]={ 0x23EE },
+ ["latin cross"]={ 0x271D },
+ ["latvia"]={ 0x1F1F1, 0x1F1FB },
+ ["leaf fluttering in wind"]={ 0x1F343 },
+ ["lebanon"]={ 0x1F1F1, 0x1F1E7 },
+ ["ledger"]={ 0x1F4D2 },
+ ["left arrow"]={ 0x2B05 },
+ ["left arrow curving right"]={ 0x21AA },
+ ["left luggage"]={ 0x1F6C5 },
+ ["left speech bubble"]={ 0x1F5E8 },
+ ["left-facing fist"]={ 0x1F91B },
+ ["left-facing fist: dark skin tone"]={ 0x1F91B, 0x1F3FF },
+ ["left-facing fist: light skin tone"]={ 0x1F91B, 0x1F3FB },
+ ["left-facing fist: medium skin tone"]={ 0x1F91B, 0x1F3FD },
+ ["left-facing fist: medium-dark skin tone"]={ 0x1F91B, 0x1F3FE },
+ ["left-facing fist: medium-light skin tone"]={ 0x1F91B, 0x1F3FC },
+ ["left-pointing magnifying glass"]={ 0x1F50D },
+ ["left-right arrow"]={ 0x2194 },
+ ["lemon"]={ 0x1F34B },
+ ["leo"]={ 0x264C },
+ ["leopard"]={ 0x1F406 },
+ ["lesotho"]={ 0x1F1F1, 0x1F1F8 },
+ ["level slider"]={ 0x1F39A },
+ ["liberia"]={ 0x1F1F1, 0x1F1F7 },
+ ["libra"]={ 0x264E },
+ ["libya"]={ 0x1F1F1, 0x1F1FE },
+ ["liechtenstein"]={ 0x1F1F1, 0x1F1EE },
+ ["light bulb"]={ 0x1F4A1 },
+ ["light rail"]={ 0x1F688 },
+ ["link"]={ 0x1F517 },
+ ["linked paperclips"]={ 0x1F587 },
+ ["lion face"]={ 0x1F981 },
+ ["lipstick"]={ 0x1F484 },
+ ["lithuania"]={ 0x1F1F1, 0x1F1F9 },
+ ["litter in bin sign"]={ 0x1F6AE },
+ ["lizard"]={ 0x1F98E },
+ ["locked"]={ 0x1F512 },
+ ["locked with key"]={ 0x1F510 },
+ ["locked with pen"]={ 0x1F50F },
+ ["locomotive"]={ 0x1F682 },
+ ["lollipop"]={ 0x1F36D },
+ ["loudly crying face"]={ 0x1F62D },
+ ["loudspeaker"]={ 0x1F4E2 },
+ ["love hotel"]={ 0x1F3E9 },
+ ["love letter"]={ 0x1F48C },
+ ["love-you gesture"]={ 0x1F91F },
+ ["love-you gesture: dark skin tone"]={ 0x1F91F, 0x1F3FF },
+ ["love-you gesture: light skin tone"]={ 0x1F91F, 0x1F3FB },
+ ["love-you gesture: medium skin tone"]={ 0x1F91F, 0x1F3FD },
+ ["love-you gesture: medium-dark skin tone"]={ 0x1F91F, 0x1F3FE },
+ ["love-you gesture: medium-light skin tone"]={ 0x1F91F, 0x1F3FC },
+ ["luxembourg"]={ 0x1F1F1, 0x1F1FA },
+ ["lying face"]={ 0x1F925 },
+ ["macau sar china"]={ 0x1F1F2, 0x1F1F4 },
+ ["macedonia"]={ 0x1F1F2, 0x1F1F0 },
+ ["madagascar"]={ 0x1F1F2, 0x1F1EC },
+ ["mage"]={ 0x1F9D9 },
+ ["mage: dark skin tone"]={ 0x1F9D9, 0x1F3FF },
+ ["mage: light skin tone"]={ 0x1F9D9, 0x1F3FB },
+ ["mage: medium skin tone"]={ 0x1F9D9, 0x1F3FD },
+ ["mage: medium-dark skin tone"]={ 0x1F9D9, 0x1F3FE },
+ ["mage: medium-light skin tone"]={ 0x1F9D9, 0x1F3FC },
+ ["mahjong red dragon"]={ 0x1F004 },
+ ["malawi"]={ 0x1F1F2, 0x1F1FC },
+ ["malaysia"]={ 0x1F1F2, 0x1F1FE },
+ ["maldives"]={ 0x1F1F2, 0x1F1FB },
+ ["male sign"]={ 0x2642 },
+ ["mali"]={ 0x1F1F2, 0x1F1F1 },
+ ["malta"]={ 0x1F1F2, 0x1F1F9 },
+ ["man"]={ 0x1F468 },
+ ["man and woman holding hands"]={ 0x1F46B },
+ ["man artist"]={ 0x1F468, 0x200D, 0x1F3A8 },
+ ["man artist: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F3A8 },
+ ["man artist: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F3A8 },
+ ["man artist: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F3A8 },
+ ["man artist: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F3A8 },
+ ["man artist: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F3A8 },
+ ["man astronaut"]={ 0x1F468, 0x200D, 0x1F680 },
+ ["man astronaut: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F680 },
+ ["man astronaut: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F680 },
+ ["man astronaut: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F680 },
+ ["man astronaut: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F680 },
+ ["man astronaut: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F680 },
+ ["man biking"]={ 0x1F6B4, 0x200D, 0x2642 },
+ ["man biking: dark skin tone"]={ 0x1F6B4, 0x1F3FF, 0x200D, 0x2642 },
+ ["man biking: light skin tone"]={ 0x1F6B4, 0x1F3FB, 0x200D, 0x2642 },
+ ["man biking: medium skin tone"]={ 0x1F6B4, 0x1F3FD, 0x200D, 0x2642 },
+ ["man biking: medium-dark skin tone"]={ 0x1F6B4, 0x1F3FE, 0x200D, 0x2642 },
+ ["man biking: medium-light skin tone"]={ 0x1F6B4, 0x1F3FC, 0x200D, 0x2642 },
+ ["man bouncing ball"]={ 0x26F9, 0x200D, 0x2642 },
+ ["man bouncing ball: dark skin tone"]={ 0x26F9, 0x1F3FF, 0x200D, 0x2642 },
+ ["man bouncing ball: light skin tone"]={ 0x26F9, 0x1F3FB, 0x200D, 0x2642 },
+ ["man bouncing ball: medium skin tone"]={ 0x26F9, 0x1F3FD, 0x200D, 0x2642 },
+ ["man bouncing ball: medium-dark skin tone"]={ 0x26F9, 0x1F3FE, 0x200D, 0x2642 },
+ ["man bouncing ball: medium-light skin tone"]={ 0x26F9, 0x1F3FC, 0x200D, 0x2642 },
+ ["man bowing"]={ 0x1F647, 0x200D, 0x2642 },
+ ["man bowing: dark skin tone"]={ 0x1F647, 0x1F3FF, 0x200D, 0x2642 },
+ ["man bowing: light skin tone"]={ 0x1F647, 0x1F3FB, 0x200D, 0x2642 },
+ ["man bowing: medium skin tone"]={ 0x1F647, 0x1F3FD, 0x200D, 0x2642 },
+ ["man bowing: medium-dark skin tone"]={ 0x1F647, 0x1F3FE, 0x200D, 0x2642 },
+ ["man bowing: medium-light skin tone"]={ 0x1F647, 0x1F3FC, 0x200D, 0x2642 },
+ ["man cartwheeling"]={ 0x1F938, 0x200D, 0x2642 },
+ ["man cartwheeling: dark skin tone"]={ 0x1F938, 0x1F3FF, 0x200D, 0x2642 },
+ ["man cartwheeling: light skin tone"]={ 0x1F938, 0x1F3FB, 0x200D, 0x2642 },
+ ["man cartwheeling: medium skin tone"]={ 0x1F938, 0x1F3FD, 0x200D, 0x2642 },
+ ["man cartwheeling: medium-dark skin tone"]={ 0x1F938, 0x1F3FE, 0x200D, 0x2642 },
+ ["man cartwheeling: medium-light skin tone"]={ 0x1F938, 0x1F3FC, 0x200D, 0x2642 },
+ ["man climbing"]={ 0x1F9D7, 0x200D, 0x2642 },
+ ["man climbing: dark skin tone"]={ 0x1F9D7, 0x1F3FF, 0x200D, 0x2642 },
+ ["man climbing: light skin tone"]={ 0x1F9D7, 0x1F3FB, 0x200D, 0x2642 },
+ ["man climbing: medium skin tone"]={ 0x1F9D7, 0x1F3FD, 0x200D, 0x2642 },
+ ["man climbing: medium-dark skin tone"]={ 0x1F9D7, 0x1F3FE, 0x200D, 0x2642 },
+ ["man climbing: medium-light skin tone"]={ 0x1F9D7, 0x1F3FC, 0x200D, 0x2642 },
+ ["man construction worker"]={ 0x1F477, 0x200D, 0x2642 },
+ ["man construction worker: dark skin tone"]={ 0x1F477, 0x1F3FF, 0x200D, 0x2642 },
+ ["man construction worker: light skin tone"]={ 0x1F477, 0x1F3FB, 0x200D, 0x2642 },
+ ["man construction worker: medium skin tone"]={ 0x1F477, 0x1F3FD, 0x200D, 0x2642 },
+ ["man construction worker: medium-dark skin tone"]={ 0x1F477, 0x1F3FE, 0x200D, 0x2642 },
+ ["man construction worker: medium-light skin tone"]={ 0x1F477, 0x1F3FC, 0x200D, 0x2642 },
+ ["man cook"]={ 0x1F468, 0x200D, 0x1F373 },
+ ["man cook: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F373 },
+ ["man cook: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F373 },
+ ["man cook: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F373 },
+ ["man cook: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F373 },
+ ["man cook: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F373 },
+ ["man dancing"]={ 0x1F57A },
+ ["man dancing: dark skin tone"]={ 0x1F57A, 0x1F3FF },
+ ["man dancing: light skin tone"]={ 0x1F57A, 0x1F3FB },
+ ["man dancing: medium skin tone"]={ 0x1F57A, 0x1F3FD },
+ ["man dancing: medium-dark skin tone"]={ 0x1F57A, 0x1F3FE },
+ ["man dancing: medium-light skin tone"]={ 0x1F57A, 0x1F3FC },
+ ["man detective"]={ 0x1F575, 0x200D, 0x2642 },
+ ["man detective: dark skin tone"]={ 0x1F575, 0x1F3FF, 0x200D, 0x2642 },
+ ["man detective: light skin tone"]={ 0x1F575, 0x1F3FB, 0x200D, 0x2642 },
+ ["man detective: medium skin tone"]={ 0x1F575, 0x1F3FD, 0x200D, 0x2642 },
+ ["man detective: medium-dark skin tone"]={ 0x1F575, 0x1F3FE, 0x200D, 0x2642 },
+ ["man detective: medium-light skin tone"]={ 0x1F575, 0x1F3FC, 0x200D, 0x2642 },
+ ["man elf"]={ 0x1F9DD, 0x200D, 0x2642 },
+ ["man elf: dark skin tone"]={ 0x1F9DD, 0x1F3FF, 0x200D, 0x2642 },
+ ["man elf: light skin tone"]={ 0x1F9DD, 0x1F3FB, 0x200D, 0x2642 },
+ ["man elf: medium skin tone"]={ 0x1F9DD, 0x1F3FD, 0x200D, 0x2642 },
+ ["man elf: medium-dark skin tone"]={ 0x1F9DD, 0x1F3FE, 0x200D, 0x2642 },
+ ["man elf: medium-light skin tone"]={ 0x1F9DD, 0x1F3FC, 0x200D, 0x2642 },
+ ["man facepalming"]={ 0x1F926, 0x200D, 0x2642 },
+ ["man facepalming: dark skin tone"]={ 0x1F926, 0x1F3FF, 0x200D, 0x2642 },
+ ["man facepalming: light skin tone"]={ 0x1F926, 0x1F3FB, 0x200D, 0x2642 },
+ ["man facepalming: medium skin tone"]={ 0x1F926, 0x1F3FD, 0x200D, 0x2642 },
+ ["man facepalming: medium-dark skin tone"]={ 0x1F926, 0x1F3FE, 0x200D, 0x2642 },
+ ["man facepalming: medium-light skin tone"]={ 0x1F926, 0x1F3FC, 0x200D, 0x2642 },
+ ["man factory worker"]={ 0x1F468, 0x200D, 0x1F3ED },
+ ["man factory worker: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F3ED },
+ ["man factory worker: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F3ED },
+ ["man factory worker: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F3ED },
+ ["man factory worker: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F3ED },
+ ["man factory worker: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F3ED },
+ ["man fairy"]={ 0x1F9DA, 0x200D, 0x2642 },
+ ["man fairy: dark skin tone"]={ 0x1F9DA, 0x1F3FF, 0x200D, 0x2642 },
+ ["man fairy: light skin tone"]={ 0x1F9DA, 0x1F3FB, 0x200D, 0x2642 },
+ ["man fairy: medium skin tone"]={ 0x1F9DA, 0x1F3FD, 0x200D, 0x2642 },
+ ["man fairy: medium-dark skin tone"]={ 0x1F9DA, 0x1F3FE, 0x200D, 0x2642 },
+ ["man fairy: medium-light skin tone"]={ 0x1F9DA, 0x1F3FC, 0x200D, 0x2642 },
+ ["man farmer"]={ 0x1F468, 0x200D, 0x1F33E },
+ ["man farmer: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F33E },
+ ["man farmer: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F33E },
+ ["man farmer: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F33E },
+ ["man farmer: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F33E },
+ ["man farmer: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F33E },
+ ["man firefighter"]={ 0x1F468, 0x200D, 0x1F692 },
+ ["man firefighter: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F692 },
+ ["man firefighter: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F692 },
+ ["man firefighter: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F692 },
+ ["man firefighter: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F692 },
+ ["man firefighter: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F692 },
+ ["man frowning"]={ 0x1F64D, 0x200D, 0x2642 },
+ ["man frowning: dark skin tone"]={ 0x1F64D, 0x1F3FF, 0x200D, 0x2642 },
+ ["man frowning: light skin tone"]={ 0x1F64D, 0x1F3FB, 0x200D, 0x2642 },
+ ["man frowning: medium skin tone"]={ 0x1F64D, 0x1F3FD, 0x200D, 0x2642 },
+ ["man frowning: medium-dark skin tone"]={ 0x1F64D, 0x1F3FE, 0x200D, 0x2642 },
+ ["man frowning: medium-light skin tone"]={ 0x1F64D, 0x1F3FC, 0x200D, 0x2642 },
+ ["man genie"]={ 0x1F9DE, 0x200D, 0x2642 },
+ ["man gesturing no"]={ 0x1F645, 0x200D, 0x2642 },
+ ["man gesturing no: dark skin tone"]={ 0x1F645, 0x1F3FF, 0x200D, 0x2642 },
+ ["man gesturing no: light skin tone"]={ 0x1F645, 0x1F3FB, 0x200D, 0x2642 },
+ ["man gesturing no: medium skin tone"]={ 0x1F645, 0x1F3FD, 0x200D, 0x2642 },
+ ["man gesturing no: medium-dark skin tone"]={ 0x1F645, 0x1F3FE, 0x200D, 0x2642 },
+ ["man gesturing no: medium-light skin tone"]={ 0x1F645, 0x1F3FC, 0x200D, 0x2642 },
+ ["man gesturing ok"]={ 0x1F646, 0x200D, 0x2642 },
+ ["man gesturing ok: dark skin tone"]={ 0x1F646, 0x1F3FF, 0x200D, 0x2642 },
+ ["man gesturing ok: light skin tone"]={ 0x1F646, 0x1F3FB, 0x200D, 0x2642 },
+ ["man gesturing ok: medium skin tone"]={ 0x1F646, 0x1F3FD, 0x200D, 0x2642 },
+ ["man gesturing ok: medium-dark skin tone"]={ 0x1F646, 0x1F3FE, 0x200D, 0x2642 },
+ ["man gesturing ok: medium-light skin tone"]={ 0x1F646, 0x1F3FC, 0x200D, 0x2642 },
+ ["man getting haircut"]={ 0x1F487, 0x200D, 0x2642 },
+ ["man getting haircut: dark skin tone"]={ 0x1F487, 0x1F3FF, 0x200D, 0x2642 },
+ ["man getting haircut: light skin tone"]={ 0x1F487, 0x1F3FB, 0x200D, 0x2642 },
+ ["man getting haircut: medium skin tone"]={ 0x1F487, 0x1F3FD, 0x200D, 0x2642 },
+ ["man getting haircut: medium-dark skin tone"]={ 0x1F487, 0x1F3FE, 0x200D, 0x2642 },
+ ["man getting haircut: medium-light skin tone"]={ 0x1F487, 0x1F3FC, 0x200D, 0x2642 },
+ ["man getting massage"]={ 0x1F486, 0x200D, 0x2642 },
+ ["man getting massage: dark skin tone"]={ 0x1F486, 0x1F3FF, 0x200D, 0x2642 },
+ ["man getting massage: light skin tone"]={ 0x1F486, 0x1F3FB, 0x200D, 0x2642 },
+ ["man getting massage: medium skin tone"]={ 0x1F486, 0x1F3FD, 0x200D, 0x2642 },
+ ["man getting massage: medium-dark skin tone"]={ 0x1F486, 0x1F3FE, 0x200D, 0x2642 },
+ ["man getting massage: medium-light skin tone"]={ 0x1F486, 0x1F3FC, 0x200D, 0x2642 },
+ ["man golfing"]={ 0x1F3CC, 0x200D, 0x2642 },
+ ["man golfing: dark skin tone"]={ 0x1F3CC, 0x1F3FF, 0x200D, 0x2642 },
+ ["man golfing: light skin tone"]={ 0x1F3CC, 0x1F3FB, 0x200D, 0x2642 },
+ ["man golfing: medium skin tone"]={ 0x1F3CC, 0x1F3FD, 0x200D, 0x2642 },
+ ["man golfing: medium-dark skin tone"]={ 0x1F3CC, 0x1F3FE, 0x200D, 0x2642 },
+ ["man golfing: medium-light skin tone"]={ 0x1F3CC, 0x1F3FC, 0x200D, 0x2642 },
+ ["man guard"]={ 0x1F482, 0x200D, 0x2642 },
+ ["man guard: dark skin tone"]={ 0x1F482, 0x1F3FF, 0x200D, 0x2642 },
+ ["man guard: light skin tone"]={ 0x1F482, 0x1F3FB, 0x200D, 0x2642 },
+ ["man guard: medium skin tone"]={ 0x1F482, 0x1F3FD, 0x200D, 0x2642 },
+ ["man guard: medium-dark skin tone"]={ 0x1F482, 0x1F3FE, 0x200D, 0x2642 },
+ ["man guard: medium-light skin tone"]={ 0x1F482, 0x1F3FC, 0x200D, 0x2642 },
+ ["man health worker"]={ 0x1F468, 0x200D, 0x2695 },
+ ["man health worker: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x2695 },
+ ["man health worker: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x2695 },
+ ["man health worker: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x2695 },
+ ["man health worker: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x2695 },
+ ["man health worker: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x2695 },
+ ["man in business suit levitating"]={ 0x1F574 },
+ ["man in business suit levitating: dark skin tone"]={ 0x1F574, 0x1F3FF },
+ ["man in business suit levitating: light skin tone"]={ 0x1F574, 0x1F3FB },
+ ["man in business suit levitating: medium skin tone"]={ 0x1F574, 0x1F3FD },
+ ["man in business suit levitating: medium-dark skin tone"]={ 0x1F574, 0x1F3FE },
+ ["man in business suit levitating: medium-light skin tone"]={ 0x1F574, 0x1F3FC },
+ ["man in lotus position"]={ 0x1F9D8, 0x200D, 0x2642 },
+ ["man in lotus position: dark skin tone"]={ 0x1F9D8, 0x1F3FF, 0x200D, 0x2642 },
+ ["man in lotus position: light skin tone"]={ 0x1F9D8, 0x1F3FB, 0x200D, 0x2642 },
+ ["man in lotus position: medium skin tone"]={ 0x1F9D8, 0x1F3FD, 0x200D, 0x2642 },
+ ["man in lotus position: medium-dark skin tone"]={ 0x1F9D8, 0x1F3FE, 0x200D, 0x2642 },
+ ["man in lotus position: medium-light skin tone"]={ 0x1F9D8, 0x1F3FC, 0x200D, 0x2642 },
+ ["man in steamy room"]={ 0x1F9D6, 0x200D, 0x2642 },
+ ["man in steamy room: dark skin tone"]={ 0x1F9D6, 0x1F3FF, 0x200D, 0x2642 },
+ ["man in steamy room: light skin tone"]={ 0x1F9D6, 0x1F3FB, 0x200D, 0x2642 },
+ ["man in steamy room: medium skin tone"]={ 0x1F9D6, 0x1F3FD, 0x200D, 0x2642 },
+ ["man in steamy room: medium-dark skin tone"]={ 0x1F9D6, 0x1F3FE, 0x200D, 0x2642 },
+ ["man in steamy room: medium-light skin tone"]={ 0x1F9D6, 0x1F3FC, 0x200D, 0x2642 },
+ ["man in tuxedo"]={ 0x1F935 },
+ ["man in tuxedo: dark skin tone"]={ 0x1F935, 0x1F3FF },
+ ["man in tuxedo: light skin tone"]={ 0x1F935, 0x1F3FB },
+ ["man in tuxedo: medium skin tone"]={ 0x1F935, 0x1F3FD },
+ ["man in tuxedo: medium-dark skin tone"]={ 0x1F935, 0x1F3FE },
+ ["man in tuxedo: medium-light skin tone"]={ 0x1F935, 0x1F3FC },
+ ["man judge"]={ 0x1F468, 0x200D, 0x2696 },
+ ["man judge: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x2696 },
+ ["man judge: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x2696 },
+ ["man judge: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x2696 },
+ ["man judge: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x2696 },
+ ["man judge: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x2696 },
+ ["man juggling"]={ 0x1F939, 0x200D, 0x2642 },
+ ["man juggling: dark skin tone"]={ 0x1F939, 0x1F3FF, 0x200D, 0x2642 },
+ ["man juggling: light skin tone"]={ 0x1F939, 0x1F3FB, 0x200D, 0x2642 },
+ ["man juggling: medium skin tone"]={ 0x1F939, 0x1F3FD, 0x200D, 0x2642 },
+ ["man juggling: medium-dark skin tone"]={ 0x1F939, 0x1F3FE, 0x200D, 0x2642 },
+ ["man juggling: medium-light skin tone"]={ 0x1F939, 0x1F3FC, 0x200D, 0x2642 },
+ ["man lifting weights"]={ 0x1F3CB, 0x200D, 0x2642 },
+ ["man lifting weights: dark skin tone"]={ 0x1F3CB, 0x1F3FF, 0x200D, 0x2642 },
+ ["man lifting weights: light skin tone"]={ 0x1F3CB, 0x1F3FB, 0x200D, 0x2642 },
+ ["man lifting weights: medium skin tone"]={ 0x1F3CB, 0x1F3FD, 0x200D, 0x2642 },
+ ["man lifting weights: medium-dark skin tone"]={ 0x1F3CB, 0x1F3FE, 0x200D, 0x2642 },
+ ["man lifting weights: medium-light skin tone"]={ 0x1F3CB, 0x1F3FC, 0x200D, 0x2642 },
+ ["man mage"]={ 0x1F9D9, 0x200D, 0x2642 },
+ ["man mage: dark skin tone"]={ 0x1F9D9, 0x1F3FF, 0x200D, 0x2642 },
+ ["man mage: light skin tone"]={ 0x1F9D9, 0x1F3FB, 0x200D, 0x2642 },
+ ["man mage: medium skin tone"]={ 0x1F9D9, 0x1F3FD, 0x200D, 0x2642 },
+ ["man mage: medium-dark skin tone"]={ 0x1F9D9, 0x1F3FE, 0x200D, 0x2642 },
+ ["man mage: medium-light skin tone"]={ 0x1F9D9, 0x1F3FC, 0x200D, 0x2642 },
+ ["man mechanic"]={ 0x1F468, 0x200D, 0x1F527 },
+ ["man mechanic: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F527 },
+ ["man mechanic: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F527 },
+ ["man mechanic: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F527 },
+ ["man mechanic: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F527 },
+ ["man mechanic: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F527 },
+ ["man mountain biking"]={ 0x1F6B5, 0x200D, 0x2642 },
+ ["man mountain biking: dark skin tone"]={ 0x1F6B5, 0x1F3FF, 0x200D, 0x2642 },
+ ["man mountain biking: light skin tone"]={ 0x1F6B5, 0x1F3FB, 0x200D, 0x2642 },
+ ["man mountain biking: medium skin tone"]={ 0x1F6B5, 0x1F3FD, 0x200D, 0x2642 },
+ ["man mountain biking: medium-dark skin tone"]={ 0x1F6B5, 0x1F3FE, 0x200D, 0x2642 },
+ ["man mountain biking: medium-light skin tone"]={ 0x1F6B5, 0x1F3FC, 0x200D, 0x2642 },
+ ["man office worker"]={ 0x1F468, 0x200D, 0x1F4BC },
+ ["man office worker: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F4BC },
+ ["man office worker: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F4BC },
+ ["man office worker: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F4BC },
+ ["man office worker: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F4BC },
+ ["man office worker: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F4BC },
+ ["man pilot"]={ 0x1F468, 0x200D, 0x2708 },
+ ["man pilot: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x2708 },
+ ["man pilot: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x2708 },
+ ["man pilot: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x2708 },
+ ["man pilot: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x2708 },
+ ["man pilot: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x2708 },
+ ["man playing handball"]={ 0x1F93E, 0x200D, 0x2642 },
+ ["man playing handball: dark skin tone"]={ 0x1F93E, 0x1F3FF, 0x200D, 0x2642 },
+ ["man playing handball: light skin tone"]={ 0x1F93E, 0x1F3FB, 0x200D, 0x2642 },
+ ["man playing handball: medium skin tone"]={ 0x1F93E, 0x1F3FD, 0x200D, 0x2642 },
+ ["man playing handball: medium-dark skin tone"]={ 0x1F93E, 0x1F3FE, 0x200D, 0x2642 },
+ ["man playing handball: medium-light skin tone"]={ 0x1F93E, 0x1F3FC, 0x200D, 0x2642 },
+ ["man playing water polo"]={ 0x1F93D, 0x200D, 0x2642 },
+ ["man playing water polo: dark skin tone"]={ 0x1F93D, 0x1F3FF, 0x200D, 0x2642 },
+ ["man playing water polo: light skin tone"]={ 0x1F93D, 0x1F3FB, 0x200D, 0x2642 },
+ ["man playing water polo: medium skin tone"]={ 0x1F93D, 0x1F3FD, 0x200D, 0x2642 },
+ ["man playing water polo: medium-dark skin tone"]={ 0x1F93D, 0x1F3FE, 0x200D, 0x2642 },
+ ["man playing water polo: medium-light skin tone"]={ 0x1F93D, 0x1F3FC, 0x200D, 0x2642 },
+ ["man police officer"]={ 0x1F46E, 0x200D, 0x2642 },
+ ["man police officer: dark skin tone"]={ 0x1F46E, 0x1F3FF, 0x200D, 0x2642 },
+ ["man police officer: light skin tone"]={ 0x1F46E, 0x1F3FB, 0x200D, 0x2642 },
+ ["man police officer: medium skin tone"]={ 0x1F46E, 0x1F3FD, 0x200D, 0x2642 },
+ ["man police officer: medium-dark skin tone"]={ 0x1F46E, 0x1F3FE, 0x200D, 0x2642 },
+ ["man police officer: medium-light skin tone"]={ 0x1F46E, 0x1F3FC, 0x200D, 0x2642 },
+ ["man pouting"]={ 0x1F64E, 0x200D, 0x2642 },
+ ["man pouting: dark skin tone"]={ 0x1F64E, 0x1F3FF, 0x200D, 0x2642 },
+ ["man pouting: light skin tone"]={ 0x1F64E, 0x1F3FB, 0x200D, 0x2642 },
+ ["man pouting: medium skin tone"]={ 0x1F64E, 0x1F3FD, 0x200D, 0x2642 },
+ ["man pouting: medium-dark skin tone"]={ 0x1F64E, 0x1F3FE, 0x200D, 0x2642 },
+ ["man pouting: medium-light skin tone"]={ 0x1F64E, 0x1F3FC, 0x200D, 0x2642 },
+ ["man raising hand"]={ 0x1F64B, 0x200D, 0x2642 },
+ ["man raising hand: dark skin tone"]={ 0x1F64B, 0x1F3FF, 0x200D, 0x2642 },
+ ["man raising hand: light skin tone"]={ 0x1F64B, 0x1F3FB, 0x200D, 0x2642 },
+ ["man raising hand: medium skin tone"]={ 0x1F64B, 0x1F3FD, 0x200D, 0x2642 },
+ ["man raising hand: medium-dark skin tone"]={ 0x1F64B, 0x1F3FE, 0x200D, 0x2642 },
+ ["man raising hand: medium-light skin tone"]={ 0x1F64B, 0x1F3FC, 0x200D, 0x2642 },
+ ["man rowing boat"]={ 0x1F6A3, 0x200D, 0x2642 },
+ ["man rowing boat: dark skin tone"]={ 0x1F6A3, 0x1F3FF, 0x200D, 0x2642 },
+ ["man rowing boat: light skin tone"]={ 0x1F6A3, 0x1F3FB, 0x200D, 0x2642 },
+ ["man rowing boat: medium skin tone"]={ 0x1F6A3, 0x1F3FD, 0x200D, 0x2642 },
+ ["man rowing boat: medium-dark skin tone"]={ 0x1F6A3, 0x1F3FE, 0x200D, 0x2642 },
+ ["man rowing boat: medium-light skin tone"]={ 0x1F6A3, 0x1F3FC, 0x200D, 0x2642 },
+ ["man running"]={ 0x1F3C3, 0x200D, 0x2642 },
+ ["man running: dark skin tone"]={ 0x1F3C3, 0x1F3FF, 0x200D, 0x2642 },
+ ["man running: light skin tone"]={ 0x1F3C3, 0x1F3FB, 0x200D, 0x2642 },
+ ["man running: medium skin tone"]={ 0x1F3C3, 0x1F3FD, 0x200D, 0x2642 },
+ ["man running: medium-dark skin tone"]={ 0x1F3C3, 0x1F3FE, 0x200D, 0x2642 },
+ ["man running: medium-light skin tone"]={ 0x1F3C3, 0x1F3FC, 0x200D, 0x2642 },
+ ["man scientist"]={ 0x1F468, 0x200D, 0x1F52C },
+ ["man scientist: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F52C },
+ ["man scientist: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F52C },
+ ["man scientist: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F52C },
+ ["man scientist: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F52C },
+ ["man scientist: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F52C },
+ ["man shrugging"]={ 0x1F937, 0x200D, 0x2642 },
+ ["man shrugging: dark skin tone"]={ 0x1F937, 0x1F3FF, 0x200D, 0x2642 },
+ ["man shrugging: light skin tone"]={ 0x1F937, 0x1F3FB, 0x200D, 0x2642 },
+ ["man shrugging: medium skin tone"]={ 0x1F937, 0x1F3FD, 0x200D, 0x2642 },
+ ["man shrugging: medium-dark skin tone"]={ 0x1F937, 0x1F3FE, 0x200D, 0x2642 },
+ ["man shrugging: medium-light skin tone"]={ 0x1F937, 0x1F3FC, 0x200D, 0x2642 },
+ ["man singer"]={ 0x1F468, 0x200D, 0x1F3A4 },
+ ["man singer: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F3A4 },
+ ["man singer: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F3A4 },
+ ["man singer: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F3A4 },
+ ["man singer: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F3A4 },
+ ["man singer: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F3A4 },
+ ["man student"]={ 0x1F468, 0x200D, 0x1F393 },
+ ["man student: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F393 },
+ ["man student: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F393 },
+ ["man student: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F393 },
+ ["man student: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F393 },
+ ["man student: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F393 },
+ ["man surfing"]={ 0x1F3C4, 0x200D, 0x2642 },
+ ["man surfing: dark skin tone"]={ 0x1F3C4, 0x1F3FF, 0x200D, 0x2642 },
+ ["man surfing: light skin tone"]={ 0x1F3C4, 0x1F3FB, 0x200D, 0x2642 },
+ ["man surfing: medium skin tone"]={ 0x1F3C4, 0x1F3FD, 0x200D, 0x2642 },
+ ["man surfing: medium-dark skin tone"]={ 0x1F3C4, 0x1F3FE, 0x200D, 0x2642 },
+ ["man surfing: medium-light skin tone"]={ 0x1F3C4, 0x1F3FC, 0x200D, 0x2642 },
+ ["man swimming"]={ 0x1F3CA, 0x200D, 0x2642 },
+ ["man swimming: dark skin tone"]={ 0x1F3CA, 0x1F3FF, 0x200D, 0x2642 },
+ ["man swimming: light skin tone"]={ 0x1F3CA, 0x1F3FB, 0x200D, 0x2642 },
+ ["man swimming: medium skin tone"]={ 0x1F3CA, 0x1F3FD, 0x200D, 0x2642 },
+ ["man swimming: medium-dark skin tone"]={ 0x1F3CA, 0x1F3FE, 0x200D, 0x2642 },
+ ["man swimming: medium-light skin tone"]={ 0x1F3CA, 0x1F3FC, 0x200D, 0x2642 },
+ ["man teacher"]={ 0x1F468, 0x200D, 0x1F3EB },
+ ["man teacher: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F3EB },
+ ["man teacher: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F3EB },
+ ["man teacher: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F3EB },
+ ["man teacher: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F3EB },
+ ["man teacher: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F3EB },
+ ["man technologist"]={ 0x1F468, 0x200D, 0x1F4BB },
+ ["man technologist: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F4BB },
+ ["man technologist: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F4BB },
+ ["man technologist: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F4BB },
+ ["man technologist: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F4BB },
+ ["man technologist: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F4BB },
+ ["man tipping hand"]={ 0x1F481, 0x200D, 0x2642 },
+ ["man tipping hand: dark skin tone"]={ 0x1F481, 0x1F3FF, 0x200D, 0x2642 },
+ ["man tipping hand: light skin tone"]={ 0x1F481, 0x1F3FB, 0x200D, 0x2642 },
+ ["man tipping hand: medium skin tone"]={ 0x1F481, 0x1F3FD, 0x200D, 0x2642 },
+ ["man tipping hand: medium-dark skin tone"]={ 0x1F481, 0x1F3FE, 0x200D, 0x2642 },
+ ["man tipping hand: medium-light skin tone"]={ 0x1F481, 0x1F3FC, 0x200D, 0x2642 },
+ ["man vampire"]={ 0x1F9DB, 0x200D, 0x2642 },
+ ["man vampire: dark skin tone"]={ 0x1F9DB, 0x1F3FF, 0x200D, 0x2642 },
+ ["man vampire: light skin tone"]={ 0x1F9DB, 0x1F3FB, 0x200D, 0x2642 },
+ ["man vampire: medium skin tone"]={ 0x1F9DB, 0x1F3FD, 0x200D, 0x2642 },
+ ["man vampire: medium-dark skin tone"]={ 0x1F9DB, 0x1F3FE, 0x200D, 0x2642 },
+ ["man vampire: medium-light skin tone"]={ 0x1F9DB, 0x1F3FC, 0x200D, 0x2642 },
+ ["man walking"]={ 0x1F6B6, 0x200D, 0x2642 },
+ ["man walking: dark skin tone"]={ 0x1F6B6, 0x1F3FF, 0x200D, 0x2642 },
+ ["man walking: light skin tone"]={ 0x1F6B6, 0x1F3FB, 0x200D, 0x2642 },
+ ["man walking: medium skin tone"]={ 0x1F6B6, 0x1F3FD, 0x200D, 0x2642 },
+ ["man walking: medium-dark skin tone"]={ 0x1F6B6, 0x1F3FE, 0x200D, 0x2642 },
+ ["man walking: medium-light skin tone"]={ 0x1F6B6, 0x1F3FC, 0x200D, 0x2642 },
+ ["man wearing turban"]={ 0x1F473, 0x200D, 0x2642 },
+ ["man wearing turban: dark skin tone"]={ 0x1F473, 0x1F3FF, 0x200D, 0x2642 },
+ ["man wearing turban: light skin tone"]={ 0x1F473, 0x1F3FB, 0x200D, 0x2642 },
+ ["man wearing turban: medium skin tone"]={ 0x1F473, 0x1F3FD, 0x200D, 0x2642 },
+ ["man wearing turban: medium-dark skin tone"]={ 0x1F473, 0x1F3FE, 0x200D, 0x2642 },
+ ["man wearing turban: medium-light skin tone"]={ 0x1F473, 0x1F3FC, 0x200D, 0x2642 },
+ ["man with chinese cap"]={ 0x1F472 },
+ ["man with chinese cap: dark skin tone"]={ 0x1F472, 0x1F3FF },
+ ["man with chinese cap: light skin tone"]={ 0x1F472, 0x1F3FB },
+ ["man with chinese cap: medium skin tone"]={ 0x1F472, 0x1F3FD },
+ ["man with chinese cap: medium-dark skin tone"]={ 0x1F472, 0x1F3FE },
+ ["man with chinese cap: medium-light skin tone"]={ 0x1F472, 0x1F3FC },
+ ["man zombie"]={ 0x1F9DF, 0x200D, 0x2642 },
+ ["man: dark skin tone"]={ 0x1F468, 0x1F3FF },
+ ["man: light skin tone"]={ 0x1F468, 0x1F3FB },
+ ["man: medium skin tone"]={ 0x1F468, 0x1F3FD },
+ ["man: medium-dark skin tone"]={ 0x1F468, 0x1F3FE },
+ ["man: medium-light skin tone"]={ 0x1F468, 0x1F3FC },
+ ["mantelpiece clock"]={ 0x1F570 },
+ ["man’s shoe"]={ 0x1F45E },
+ ["map of japan"]={ 0x1F5FE },
+ ["maple leaf"]={ 0x1F341 },
+ ["marshall islands"]={ 0x1F1F2, 0x1F1ED },
+ ["martial arts uniform"]={ 0x1F94B },
+ ["martinique"]={ 0x1F1F2, 0x1F1F6 },
+ ["mauritania"]={ 0x1F1F2, 0x1F1F7 },
+ ["mauritius"]={ 0x1F1F2, 0x1F1FA },
+ ["mayotte"]={ 0x1F1FE, 0x1F1F9 },
+ ["meat on bone"]={ 0x1F356 },
+ ["medical symbol"]={ 0x2695 },
+ ["megaphone"]={ 0x1F4E3 },
+ ["melon"]={ 0x1F348 },
+ ["memo"]={ 0x1F4DD },
+ ["men with bunny ears partying"]={ 0x1F46F, 0x200D, 0x2642 },
+ ["men wrestling"]={ 0x1F93C, 0x200D, 0x2642 },
+ ["menorah"]={ 0x1F54E },
+ ["men’s room"]={ 0x1F6B9 },
+ ["mermaid"]={ 0x1F9DC, 0x200D, 0x2640 },
+ ["mermaid: dark skin tone"]={ 0x1F9DC, 0x1F3FF, 0x200D, 0x2640 },
+ ["mermaid: light skin tone"]={ 0x1F9DC, 0x1F3FB, 0x200D, 0x2640 },
+ ["mermaid: medium skin tone"]={ 0x1F9DC, 0x1F3FD, 0x200D, 0x2640 },
+ ["mermaid: medium-dark skin tone"]={ 0x1F9DC, 0x1F3FE, 0x200D, 0x2640 },
+ ["mermaid: medium-light skin tone"]={ 0x1F9DC, 0x1F3FC, 0x200D, 0x2640 },
+ ["merman"]={ 0x1F9DC, 0x200D, 0x2642 },
+ ["merman: dark skin tone"]={ 0x1F9DC, 0x1F3FF, 0x200D, 0x2642 },
+ ["merman: light skin tone"]={ 0x1F9DC, 0x1F3FB, 0x200D, 0x2642 },
+ ["merman: medium skin tone"]={ 0x1F9DC, 0x1F3FD, 0x200D, 0x2642 },
+ ["merman: medium-dark skin tone"]={ 0x1F9DC, 0x1F3FE, 0x200D, 0x2642 },
+ ["merman: medium-light skin tone"]={ 0x1F9DC, 0x1F3FC, 0x200D, 0x2642 },
+ ["merperson"]={ 0x1F9DC },
+ ["merperson: dark skin tone"]={ 0x1F9DC, 0x1F3FF },
+ ["merperson: light skin tone"]={ 0x1F9DC, 0x1F3FB },
+ ["merperson: medium skin tone"]={ 0x1F9DC, 0x1F3FD },
+ ["merperson: medium-dark skin tone"]={ 0x1F9DC, 0x1F3FE },
+ ["merperson: medium-light skin tone"]={ 0x1F9DC, 0x1F3FC },
+ ["metro"]={ 0x1F687 },
+ ["mexico"]={ 0x1F1F2, 0x1F1FD },
+ ["micronesia"]={ 0x1F1EB, 0x1F1F2 },
+ ["microphone"]={ 0x1F3A4 },
+ ["microscope"]={ 0x1F52C },
+ ["middle finger"]={ 0x1F595 },
+ ["middle finger: dark skin tone"]={ 0x1F595, 0x1F3FF },
+ ["middle finger: light skin tone"]={ 0x1F595, 0x1F3FB },
+ ["middle finger: medium skin tone"]={ 0x1F595, 0x1F3FD },
+ ["middle finger: medium-dark skin tone"]={ 0x1F595, 0x1F3FE },
+ ["middle finger: medium-light skin tone"]={ 0x1F595, 0x1F3FC },
+ ["military medal"]={ 0x1F396 },
+ ["milky way"]={ 0x1F30C },
+ ["minibus"]={ 0x1F690 },
+ ["moai"]={ 0x1F5FF },
+ ["mobile phone"]={ 0x1F4F1 },
+ ["mobile phone off"]={ 0x1F4F4 },
+ ["mobile phone with arrow"]={ 0x1F4F2 },
+ ["moldova"]={ 0x1F1F2, 0x1F1E9 },
+ ["monaco"]={ 0x1F1F2, 0x1F1E8 },
+ ["money bag"]={ 0x1F4B0 },
+ ["money with wings"]={ 0x1F4B8 },
+ ["money-mouth face"]={ 0x1F911 },
+ ["mongolia"]={ 0x1F1F2, 0x1F1F3 },
+ ["monkey"]={ 0x1F412 },
+ ["monkey face"]={ 0x1F435 },
+ ["monorail"]={ 0x1F69D },
+ ["montenegro"]={ 0x1F1F2, 0x1F1EA },
+ ["montserrat"]={ 0x1F1F2, 0x1F1F8 },
+ ["moon viewing ceremony"]={ 0x1F391 },
+ ["morocco"]={ 0x1F1F2, 0x1F1E6 },
+ ["mosque"]={ 0x1F54C },
+ ["motor boat"]={ 0x1F6E5 },
+ ["motor scooter"]={ 0x1F6F5 },
+ ["motorcycle"]={ 0x1F3CD },
+ ["motorway"]={ 0x1F6E3 },
+ ["mount fuji"]={ 0x1F5FB },
+ ["mountain"]={ 0x26F0 },
+ ["mountain cableway"]={ 0x1F6A0 },
+ ["mountain railway"]={ 0x1F69E },
+ ["mouse"]={ 0x1F401 },
+ ["mouse face"]={ 0x1F42D },
+ ["mouth"]={ 0x1F444 },
+ ["movie camera"]={ 0x1F3A5 },
+ ["mozambique"]={ 0x1F1F2, 0x1F1FF },
+ ["mrs. claus"]={ 0x1F936 },
+ ["mrs. claus: dark skin tone"]={ 0x1F936, 0x1F3FF },
+ ["mrs. claus: light skin tone"]={ 0x1F936, 0x1F3FB },
+ ["mrs. claus: medium skin tone"]={ 0x1F936, 0x1F3FD },
+ ["mrs. claus: medium-dark skin tone"]={ 0x1F936, 0x1F3FE },
+ ["mrs. claus: medium-light skin tone"]={ 0x1F936, 0x1F3FC },
+ ["mushroom"]={ 0x1F344 },
+ ["musical keyboard"]={ 0x1F3B9 },
+ ["musical note"]={ 0x1F3B5 },
+ ["musical notes"]={ 0x1F3B6 },
+ ["musical score"]={ 0x1F3BC },
+ ["muted speaker"]={ 0x1F507 },
+ ["myanmar (burma)"]={ 0x1F1F2, 0x1F1F2 },
+ ["nail polish"]={ 0x1F485 },
+ ["nail polish: dark skin tone"]={ 0x1F485, 0x1F3FF },
+ ["nail polish: light skin tone"]={ 0x1F485, 0x1F3FB },
+ ["nail polish: medium skin tone"]={ 0x1F485, 0x1F3FD },
+ ["nail polish: medium-dark skin tone"]={ 0x1F485, 0x1F3FE },
+ ["nail polish: medium-light skin tone"]={ 0x1F485, 0x1F3FC },
+ ["name badge"]={ 0x1F4DB },
+ ["namibia"]={ 0x1F1F3, 0x1F1E6 },
+ ["national park"]={ 0x1F3DE },
+ ["nauru"]={ 0x1F1F3, 0x1F1F7 },
+ ["nauseated face"]={ 0x1F922 },
+ ["necktie"]={ 0x1F454 },
+ ["nepal"]={ 0x1F1F3, 0x1F1F5 },
+ ["nerd face"]={ 0x1F913 },
+ ["netherlands"]={ 0x1F1F3, 0x1F1F1 },
+ ["neutral face"]={ 0x1F610 },
+ ["new button"]={ 0x1F195 },
+ ["new caledonia"]={ 0x1F1F3, 0x1F1E8 },
+ ["new moon"]={ 0x1F311 },
+ ["new moon face"]={ 0x1F31A },
+ ["new zealand"]={ 0x1F1F3, 0x1F1FF },
+ ["newspaper"]={ 0x1F4F0 },
+ ["next track button"]={ 0x23ED },
+ ["ng button"]={ 0x1F196 },
+ ["nicaragua"]={ 0x1F1F3, 0x1F1EE },
+ ["niger"]={ 0x1F1F3, 0x1F1EA },
+ ["nigeria"]={ 0x1F1F3, 0x1F1EC },
+ ["night with stars"]={ 0x1F303 },
+ ["nine o’clock"]={ 0x1F558 },
+ ["nine-thirty"]={ 0x1F564 },
+ ["niue"]={ 0x1F1F3, 0x1F1FA },
+ ["no bicycles"]={ 0x1F6B3 },
+ ["no entry"]={ 0x26D4 },
+ ["no littering"]={ 0x1F6AF },
+ ["no mobile phones"]={ 0x1F4F5 },
+ ["no one under eighteen"]={ 0x1F51E },
+ ["no pedestrians"]={ 0x1F6B7 },
+ ["no smoking"]={ 0x1F6AD },
+ ["non-potable water"]={ 0x1F6B1 },
+ ["norfolk island"]={ 0x1F1F3, 0x1F1EB },
+ ["north korea"]={ 0x1F1F0, 0x1F1F5 },
+ ["northern mariana islands"]={ 0x1F1F2, 0x1F1F5 },
+ ["norway"]={ 0x1F1F3, 0x1F1F4 },
+ ["nose"]={ 0x1F443 },
+ ["nose: dark skin tone"]={ 0x1F443, 0x1F3FF },
+ ["nose: light skin tone"]={ 0x1F443, 0x1F3FB },
+ ["nose: medium skin tone"]={ 0x1F443, 0x1F3FD },
+ ["nose: medium-dark skin tone"]={ 0x1F443, 0x1F3FE },
+ ["nose: medium-light skin tone"]={ 0x1F443, 0x1F3FC },
+ ["notebook"]={ 0x1F4D3 },
+ ["notebook with decorative cover"]={ 0x1F4D4 },
+ ["nut and bolt"]={ 0x1F529 },
+ ["o button (blood type)"]={ 0x1F17E },
+ ["octopus"]={ 0x1F419 },
+ ["oden"]={ 0x1F362 },
+ ["office building"]={ 0x1F3E2 },
+ ["ogre"]={ 0x1F479 },
+ ["oil drum"]={ 0x1F6E2 },
+ ["ok button"]={ 0x1F197 },
+ ["ok hand"]={ 0x1F44C },
+ ["ok hand: dark skin tone"]={ 0x1F44C, 0x1F3FF },
+ ["ok hand: light skin tone"]={ 0x1F44C, 0x1F3FB },
+ ["ok hand: medium skin tone"]={ 0x1F44C, 0x1F3FD },
+ ["ok hand: medium-dark skin tone"]={ 0x1F44C, 0x1F3FE },
+ ["ok hand: medium-light skin tone"]={ 0x1F44C, 0x1F3FC },
+ ["old key"]={ 0x1F5DD },
+ ["old man"]={ 0x1F474 },
+ ["old man: dark skin tone"]={ 0x1F474, 0x1F3FF },
+ ["old man: light skin tone"]={ 0x1F474, 0x1F3FB },
+ ["old man: medium skin tone"]={ 0x1F474, 0x1F3FD },
+ ["old man: medium-dark skin tone"]={ 0x1F474, 0x1F3FE },
+ ["old man: medium-light skin tone"]={ 0x1F474, 0x1F3FC },
+ ["old woman"]={ 0x1F475 },
+ ["old woman: dark skin tone"]={ 0x1F475, 0x1F3FF },
+ ["old woman: light skin tone"]={ 0x1F475, 0x1F3FB },
+ ["old woman: medium skin tone"]={ 0x1F475, 0x1F3FD },
+ ["old woman: medium-dark skin tone"]={ 0x1F475, 0x1F3FE },
+ ["old woman: medium-light skin tone"]={ 0x1F475, 0x1F3FC },
+ ["older adult"]={ 0x1F9D3 },
+ ["older adult: dark skin tone"]={ 0x1F9D3, 0x1F3FF },
+ ["older adult: light skin tone"]={ 0x1F9D3, 0x1F3FB },
+ ["older adult: medium skin tone"]={ 0x1F9D3, 0x1F3FD },
+ ["older adult: medium-dark skin tone"]={ 0x1F9D3, 0x1F3FE },
+ ["older adult: medium-light skin tone"]={ 0x1F9D3, 0x1F3FC },
+ ["om"]={ 0x1F549 },
+ ["oman"]={ 0x1F1F4, 0x1F1F2 },
+ ["on! arrow"]={ 0x1F51B },
+ ["oncoming automobile"]={ 0x1F698 },
+ ["oncoming bus"]={ 0x1F68D },
+ ["oncoming fist"]={ 0x1F44A },
+ ["oncoming fist: dark skin tone"]={ 0x1F44A, 0x1F3FF },
+ ["oncoming fist: light skin tone"]={ 0x1F44A, 0x1F3FB },
+ ["oncoming fist: medium skin tone"]={ 0x1F44A, 0x1F3FD },
+ ["oncoming fist: medium-dark skin tone"]={ 0x1F44A, 0x1F3FE },
+ ["oncoming fist: medium-light skin tone"]={ 0x1F44A, 0x1F3FC },
+ ["oncoming police car"]={ 0x1F694 },
+ ["oncoming taxi"]={ 0x1F696 },
+ ["one o’clock"]={ 0x1F550 },
+ ["one-thirty"]={ 0x1F55C },
+ ["open book"]={ 0x1F4D6 },
+ ["open file folder"]={ 0x1F4C2 },
+ ["open hands"]={ 0x1F450 },
+ ["open hands: dark skin tone"]={ 0x1F450, 0x1F3FF },
+ ["open hands: light skin tone"]={ 0x1F450, 0x1F3FB },
+ ["open hands: medium skin tone"]={ 0x1F450, 0x1F3FD },
+ ["open hands: medium-dark skin tone"]={ 0x1F450, 0x1F3FE },
+ ["open hands: medium-light skin tone"]={ 0x1F450, 0x1F3FC },
+ ["open mailbox with lowered flag"]={ 0x1F4ED },
+ ["open mailbox with raised flag"]={ 0x1F4EC },
+ ["ophiuchus"]={ 0x26CE },
+ ["optical disk"]={ 0x1F4BF },
+ ["orange book"]={ 0x1F4D9 },
+ ["orange heart"]={ 0x1F9E1 },
+ ["orthodox cross"]={ 0x2626 },
+ ["outbox tray"]={ 0x1F4E4 },
+ ["owl"]={ 0x1F989 },
+ ["ox"]={ 0x1F402 },
+ ["p button"]={ 0x1F17F },
+ ["package"]={ 0x1F4E6 },
+ ["page facing up"]={ 0x1F4C4 },
+ ["page with curl"]={ 0x1F4C3 },
+ ["pager"]={ 0x1F4DF },
+ ["paintbrush"]={ 0x1F58C },
+ ["pakistan"]={ 0x1F1F5, 0x1F1F0 },
+ ["palau"]={ 0x1F1F5, 0x1F1FC },
+ ["palestinian territories"]={ 0x1F1F5, 0x1F1F8 },
+ ["palm tree"]={ 0x1F334 },
+ ["palms up together"]={ 0x1F932 },
+ ["palms up together: dark skin tone"]={ 0x1F932, 0x1F3FF },
+ ["palms up together: light skin tone"]={ 0x1F932, 0x1F3FB },
+ ["palms up together: medium skin tone"]={ 0x1F932, 0x1F3FD },
+ ["palms up together: medium-dark skin tone"]={ 0x1F932, 0x1F3FE },
+ ["palms up together: medium-light skin tone"]={ 0x1F932, 0x1F3FC },
+ ["panama"]={ 0x1F1F5, 0x1F1E6 },
+ ["pancakes"]={ 0x1F95E },
+ ["panda face"]={ 0x1F43C },
+ ["paperclip"]={ 0x1F4CE },
+ ["papua new guinea"]={ 0x1F1F5, 0x1F1EC },
+ ["paraguay"]={ 0x1F1F5, 0x1F1FE },
+ ["part alternation mark"]={ 0x303D },
+ ["party popper"]={ 0x1F389 },
+ ["passenger ship"]={ 0x1F6F3 },
+ ["passport control"]={ 0x1F6C2 },
+ ["pause button"]={ 0x23F8 },
+ ["paw prints"]={ 0x1F43E },
+ ["peace symbol"]={ 0x262E },
+ ["peach"]={ 0x1F351 },
+ ["peanuts"]={ 0x1F95C },
+ ["pear"]={ 0x1F350 },
+ ["pen"]={ 0x1F58A },
+ ["pencil"]={ 0x270F },
+ ["penguin"]={ 0x1F427 },
+ ["pensive face"]={ 0x1F614 },
+ ["people with bunny ears partying"]={ 0x1F46F },
+ ["people wrestling"]={ 0x1F93C },
+ ["performing arts"]={ 0x1F3AD },
+ ["persevering face"]={ 0x1F623 },
+ ["person biking"]={ 0x1F6B4 },
+ ["person biking: dark skin tone"]={ 0x1F6B4, 0x1F3FF },
+ ["person biking: light skin tone"]={ 0x1F6B4, 0x1F3FB },
+ ["person biking: medium skin tone"]={ 0x1F6B4, 0x1F3FD },
+ ["person biking: medium-dark skin tone"]={ 0x1F6B4, 0x1F3FE },
+ ["person biking: medium-light skin tone"]={ 0x1F6B4, 0x1F3FC },
+ ["person bouncing ball"]={ 0x26F9 },
+ ["person bouncing ball: dark skin tone"]={ 0x26F9, 0x1F3FF },
+ ["person bouncing ball: light skin tone"]={ 0x26F9, 0x1F3FB },
+ ["person bouncing ball: medium skin tone"]={ 0x26F9, 0x1F3FD },
+ ["person bouncing ball: medium-dark skin tone"]={ 0x26F9, 0x1F3FE },
+ ["person bouncing ball: medium-light skin tone"]={ 0x26F9, 0x1F3FC },
+ ["person bowing"]={ 0x1F647 },
+ ["person bowing: dark skin tone"]={ 0x1F647, 0x1F3FF },
+ ["person bowing: light skin tone"]={ 0x1F647, 0x1F3FB },
+ ["person bowing: medium skin tone"]={ 0x1F647, 0x1F3FD },
+ ["person bowing: medium-dark skin tone"]={ 0x1F647, 0x1F3FE },
+ ["person bowing: medium-light skin tone"]={ 0x1F647, 0x1F3FC },
+ ["person cartwheeling"]={ 0x1F938 },
+ ["person cartwheeling: dark skin tone"]={ 0x1F938, 0x1F3FF },
+ ["person cartwheeling: light skin tone"]={ 0x1F938, 0x1F3FB },
+ ["person cartwheeling: medium skin tone"]={ 0x1F938, 0x1F3FD },
+ ["person cartwheeling: medium-dark skin tone"]={ 0x1F938, 0x1F3FE },
+ ["person cartwheeling: medium-light skin tone"]={ 0x1F938, 0x1F3FC },
+ ["person climbing"]={ 0x1F9D7 },
+ ["person climbing: dark skin tone"]={ 0x1F9D7, 0x1F3FF },
+ ["person climbing: light skin tone"]={ 0x1F9D7, 0x1F3FB },
+ ["person climbing: medium skin tone"]={ 0x1F9D7, 0x1F3FD },
+ ["person climbing: medium-dark skin tone"]={ 0x1F9D7, 0x1F3FE },
+ ["person climbing: medium-light skin tone"]={ 0x1F9D7, 0x1F3FC },
+ ["person facepalming"]={ 0x1F926 },
+ ["person facepalming: dark skin tone"]={ 0x1F926, 0x1F3FF },
+ ["person facepalming: light skin tone"]={ 0x1F926, 0x1F3FB },
+ ["person facepalming: medium skin tone"]={ 0x1F926, 0x1F3FD },
+ ["person facepalming: medium-dark skin tone"]={ 0x1F926, 0x1F3FE },
+ ["person facepalming: medium-light skin tone"]={ 0x1F926, 0x1F3FC },
+ ["person fencing"]={ 0x1F93A },
+ ["person frowning"]={ 0x1F64D },
+ ["person frowning: dark skin tone"]={ 0x1F64D, 0x1F3FF },
+ ["person frowning: light skin tone"]={ 0x1F64D, 0x1F3FB },
+ ["person frowning: medium skin tone"]={ 0x1F64D, 0x1F3FD },
+ ["person frowning: medium-dark skin tone"]={ 0x1F64D, 0x1F3FE },
+ ["person frowning: medium-light skin tone"]={ 0x1F64D, 0x1F3FC },
+ ["person gesturing no"]={ 0x1F645 },
+ ["person gesturing no: dark skin tone"]={ 0x1F645, 0x1F3FF },
+ ["person gesturing no: light skin tone"]={ 0x1F645, 0x1F3FB },
+ ["person gesturing no: medium skin tone"]={ 0x1F645, 0x1F3FD },
+ ["person gesturing no: medium-dark skin tone"]={ 0x1F645, 0x1F3FE },
+ ["person gesturing no: medium-light skin tone"]={ 0x1F645, 0x1F3FC },
+ ["person gesturing ok"]={ 0x1F646 },
+ ["person gesturing ok: dark skin tone"]={ 0x1F646, 0x1F3FF },
+ ["person gesturing ok: light skin tone"]={ 0x1F646, 0x1F3FB },
+ ["person gesturing ok: medium skin tone"]={ 0x1F646, 0x1F3FD },
+ ["person gesturing ok: medium-dark skin tone"]={ 0x1F646, 0x1F3FE },
+ ["person gesturing ok: medium-light skin tone"]={ 0x1F646, 0x1F3FC },
+ ["person getting haircut"]={ 0x1F487 },
+ ["person getting haircut: dark skin tone"]={ 0x1F487, 0x1F3FF },
+ ["person getting haircut: light skin tone"]={ 0x1F487, 0x1F3FB },
+ ["person getting haircut: medium skin tone"]={ 0x1F487, 0x1F3FD },
+ ["person getting haircut: medium-dark skin tone"]={ 0x1F487, 0x1F3FE },
+ ["person getting haircut: medium-light skin tone"]={ 0x1F487, 0x1F3FC },
+ ["person getting massage"]={ 0x1F486 },
+ ["person getting massage: dark skin tone"]={ 0x1F486, 0x1F3FF },
+ ["person getting massage: light skin tone"]={ 0x1F486, 0x1F3FB },
+ ["person getting massage: medium skin tone"]={ 0x1F486, 0x1F3FD },
+ ["person getting massage: medium-dark skin tone"]={ 0x1F486, 0x1F3FE },
+ ["person getting massage: medium-light skin tone"]={ 0x1F486, 0x1F3FC },
+ ["person golfing"]={ 0x1F3CC },
+ ["person golfing: dark skin tone"]={ 0x1F3CC, 0x1F3FF },
+ ["person golfing: light skin tone"]={ 0x1F3CC, 0x1F3FB },
+ ["person golfing: medium skin tone"]={ 0x1F3CC, 0x1F3FD },
+ ["person golfing: medium-dark skin tone"]={ 0x1F3CC, 0x1F3FE },
+ ["person golfing: medium-light skin tone"]={ 0x1F3CC, 0x1F3FC },
+ ["person in bed"]={ 0x1F6CC },
+ ["person in bed: dark skin tone"]={ 0x1F6CC, 0x1F3FF },
+ ["person in bed: light skin tone"]={ 0x1F6CC, 0x1F3FB },
+ ["person in bed: medium skin tone"]={ 0x1F6CC, 0x1F3FD },
+ ["person in bed: medium-dark skin tone"]={ 0x1F6CC, 0x1F3FE },
+ ["person in bed: medium-light skin tone"]={ 0x1F6CC, 0x1F3FC },
+ ["person in lotus position"]={ 0x1F9D8 },
+ ["person in lotus position: dark skin tone"]={ 0x1F9D8, 0x1F3FF },
+ ["person in lotus position: light skin tone"]={ 0x1F9D8, 0x1F3FB },
+ ["person in lotus position: medium skin tone"]={ 0x1F9D8, 0x1F3FD },
+ ["person in lotus position: medium-dark skin tone"]={ 0x1F9D8, 0x1F3FE },
+ ["person in lotus position: medium-light skin tone"]={ 0x1F9D8, 0x1F3FC },
+ ["person in steamy room"]={ 0x1F9D6 },
+ ["person in steamy room: dark skin tone"]={ 0x1F9D6, 0x1F3FF },
+ ["person in steamy room: light skin tone"]={ 0x1F9D6, 0x1F3FB },
+ ["person in steamy room: medium skin tone"]={ 0x1F9D6, 0x1F3FD },
+ ["person in steamy room: medium-dark skin tone"]={ 0x1F9D6, 0x1F3FE },
+ ["person in steamy room: medium-light skin tone"]={ 0x1F9D6, 0x1F3FC },
+ ["person juggling"]={ 0x1F939 },
+ ["person juggling: dark skin tone"]={ 0x1F939, 0x1F3FF },
+ ["person juggling: light skin tone"]={ 0x1F939, 0x1F3FB },
+ ["person juggling: medium skin tone"]={ 0x1F939, 0x1F3FD },
+ ["person juggling: medium-dark skin tone"]={ 0x1F939, 0x1F3FE },
+ ["person juggling: medium-light skin tone"]={ 0x1F939, 0x1F3FC },
+ ["person lifting weights"]={ 0x1F3CB },
+ ["person lifting weights: dark skin tone"]={ 0x1F3CB, 0x1F3FF },
+ ["person lifting weights: light skin tone"]={ 0x1F3CB, 0x1F3FB },
+ ["person lifting weights: medium skin tone"]={ 0x1F3CB, 0x1F3FD },
+ ["person lifting weights: medium-dark skin tone"]={ 0x1F3CB, 0x1F3FE },
+ ["person lifting weights: medium-light skin tone"]={ 0x1F3CB, 0x1F3FC },
+ ["person mountain biking"]={ 0x1F6B5 },
+ ["person mountain biking: dark skin tone"]={ 0x1F6B5, 0x1F3FF },
+ ["person mountain biking: light skin tone"]={ 0x1F6B5, 0x1F3FB },
+ ["person mountain biking: medium skin tone"]={ 0x1F6B5, 0x1F3FD },
+ ["person mountain biking: medium-dark skin tone"]={ 0x1F6B5, 0x1F3FE },
+ ["person mountain biking: medium-light skin tone"]={ 0x1F6B5, 0x1F3FC },
+ ["person playing handball"]={ 0x1F93E },
+ ["person playing handball: dark skin tone"]={ 0x1F93E, 0x1F3FF },
+ ["person playing handball: light skin tone"]={ 0x1F93E, 0x1F3FB },
+ ["person playing handball: medium skin tone"]={ 0x1F93E, 0x1F3FD },
+ ["person playing handball: medium-dark skin tone"]={ 0x1F93E, 0x1F3FE },
+ ["person playing handball: medium-light skin tone"]={ 0x1F93E, 0x1F3FC },
+ ["person playing water polo"]={ 0x1F93D },
+ ["person playing water polo: dark skin tone"]={ 0x1F93D, 0x1F3FF },
+ ["person playing water polo: light skin tone"]={ 0x1F93D, 0x1F3FB },
+ ["person playing water polo: medium skin tone"]={ 0x1F93D, 0x1F3FD },
+ ["person playing water polo: medium-dark skin tone"]={ 0x1F93D, 0x1F3FE },
+ ["person playing water polo: medium-light skin tone"]={ 0x1F93D, 0x1F3FC },
+ ["person pouting"]={ 0x1F64E },
+ ["person pouting: dark skin tone"]={ 0x1F64E, 0x1F3FF },
+ ["person pouting: light skin tone"]={ 0x1F64E, 0x1F3FB },
+ ["person pouting: medium skin tone"]={ 0x1F64E, 0x1F3FD },
+ ["person pouting: medium-dark skin tone"]={ 0x1F64E, 0x1F3FE },
+ ["person pouting: medium-light skin tone"]={ 0x1F64E, 0x1F3FC },
+ ["person raising hand"]={ 0x1F64B },
+ ["person raising hand: dark skin tone"]={ 0x1F64B, 0x1F3FF },
+ ["person raising hand: light skin tone"]={ 0x1F64B, 0x1F3FB },
+ ["person raising hand: medium skin tone"]={ 0x1F64B, 0x1F3FD },
+ ["person raising hand: medium-dark skin tone"]={ 0x1F64B, 0x1F3FE },
+ ["person raising hand: medium-light skin tone"]={ 0x1F64B, 0x1F3FC },
+ ["person rowing boat"]={ 0x1F6A3 },
+ ["person rowing boat: dark skin tone"]={ 0x1F6A3, 0x1F3FF },
+ ["person rowing boat: light skin tone"]={ 0x1F6A3, 0x1F3FB },
+ ["person rowing boat: medium skin tone"]={ 0x1F6A3, 0x1F3FD },
+ ["person rowing boat: medium-dark skin tone"]={ 0x1F6A3, 0x1F3FE },
+ ["person rowing boat: medium-light skin tone"]={ 0x1F6A3, 0x1F3FC },
+ ["person running"]={ 0x1F3C3 },
+ ["person running: dark skin tone"]={ 0x1F3C3, 0x1F3FF },
+ ["person running: light skin tone"]={ 0x1F3C3, 0x1F3FB },
+ ["person running: medium skin tone"]={ 0x1F3C3, 0x1F3FD },
+ ["person running: medium-dark skin tone"]={ 0x1F3C3, 0x1F3FE },
+ ["person running: medium-light skin tone"]={ 0x1F3C3, 0x1F3FC },
+ ["person shrugging"]={ 0x1F937 },
+ ["person shrugging: dark skin tone"]={ 0x1F937, 0x1F3FF },
+ ["person shrugging: light skin tone"]={ 0x1F937, 0x1F3FB },
+ ["person shrugging: medium skin tone"]={ 0x1F937, 0x1F3FD },
+ ["person shrugging: medium-dark skin tone"]={ 0x1F937, 0x1F3FE },
+ ["person shrugging: medium-light skin tone"]={ 0x1F937, 0x1F3FC },
+ ["person surfing"]={ 0x1F3C4 },
+ ["person surfing: dark skin tone"]={ 0x1F3C4, 0x1F3FF },
+ ["person surfing: light skin tone"]={ 0x1F3C4, 0x1F3FB },
+ ["person surfing: medium skin tone"]={ 0x1F3C4, 0x1F3FD },
+ ["person surfing: medium-dark skin tone"]={ 0x1F3C4, 0x1F3FE },
+ ["person surfing: medium-light skin tone"]={ 0x1F3C4, 0x1F3FC },
+ ["person swimming"]={ 0x1F3CA },
+ ["person swimming: dark skin tone"]={ 0x1F3CA, 0x1F3FF },
+ ["person swimming: light skin tone"]={ 0x1F3CA, 0x1F3FB },
+ ["person swimming: medium skin tone"]={ 0x1F3CA, 0x1F3FD },
+ ["person swimming: medium-dark skin tone"]={ 0x1F3CA, 0x1F3FE },
+ ["person swimming: medium-light skin tone"]={ 0x1F3CA, 0x1F3FC },
+ ["person taking bath"]={ 0x1F6C0 },
+ ["person taking bath: dark skin tone"]={ 0x1F6C0, 0x1F3FF },
+ ["person taking bath: light skin tone"]={ 0x1F6C0, 0x1F3FB },
+ ["person taking bath: medium skin tone"]={ 0x1F6C0, 0x1F3FD },
+ ["person taking bath: medium-dark skin tone"]={ 0x1F6C0, 0x1F3FE },
+ ["person taking bath: medium-light skin tone"]={ 0x1F6C0, 0x1F3FC },
+ ["person tipping hand"]={ 0x1F481 },
+ ["person tipping hand: dark skin tone"]={ 0x1F481, 0x1F3FF },
+ ["person tipping hand: light skin tone"]={ 0x1F481, 0x1F3FB },
+ ["person tipping hand: medium skin tone"]={ 0x1F481, 0x1F3FD },
+ ["person tipping hand: medium-dark skin tone"]={ 0x1F481, 0x1F3FE },
+ ["person tipping hand: medium-light skin tone"]={ 0x1F481, 0x1F3FC },
+ ["person walking"]={ 0x1F6B6 },
+ ["person walking: dark skin tone"]={ 0x1F6B6, 0x1F3FF },
+ ["person walking: light skin tone"]={ 0x1F6B6, 0x1F3FB },
+ ["person walking: medium skin tone"]={ 0x1F6B6, 0x1F3FD },
+ ["person walking: medium-dark skin tone"]={ 0x1F6B6, 0x1F3FE },
+ ["person walking: medium-light skin tone"]={ 0x1F6B6, 0x1F3FC },
+ ["person wearing turban"]={ 0x1F473 },
+ ["person wearing turban: dark skin tone"]={ 0x1F473, 0x1F3FF },
+ ["person wearing turban: light skin tone"]={ 0x1F473, 0x1F3FB },
+ ["person wearing turban: medium skin tone"]={ 0x1F473, 0x1F3FD },
+ ["person wearing turban: medium-dark skin tone"]={ 0x1F473, 0x1F3FE },
+ ["person wearing turban: medium-light skin tone"]={ 0x1F473, 0x1F3FC },
+ ["peru"]={ 0x1F1F5, 0x1F1EA },
+ ["philippines"]={ 0x1F1F5, 0x1F1ED },
+ ["pick"]={ 0x26CF },
+ ["pie"]={ 0x1F967 },
+ ["pig"]={ 0x1F416 },
+ ["pig face"]={ 0x1F437 },
+ ["pig nose"]={ 0x1F43D },
+ ["pile of poo"]={ 0x1F4A9 },
+ ["pill"]={ 0x1F48A },
+ ["pine decoration"]={ 0x1F38D },
+ ["pineapple"]={ 0x1F34D },
+ ["ping pong"]={ 0x1F3D3 },
+ ["pisces"]={ 0x2653 },
+ ["pistol"]={ 0x1F52B },
+ ["pitcairn islands"]={ 0x1F1F5, 0x1F1F3 },
+ ["pizza"]={ 0x1F355 },
+ ["place of worship"]={ 0x1F6D0 },
+ ["play button"]={ 0x25B6 },
+ ["play or pause button"]={ 0x23EF },
+ ["poland"]={ 0x1F1F5, 0x1F1F1 },
+ ["police car"]={ 0x1F693 },
+ ["police car light"]={ 0x1F6A8 },
+ ["police officer"]={ 0x1F46E },
+ ["police officer: dark skin tone"]={ 0x1F46E, 0x1F3FF },
+ ["police officer: light skin tone"]={ 0x1F46E, 0x1F3FB },
+ ["police officer: medium skin tone"]={ 0x1F46E, 0x1F3FD },
+ ["police officer: medium-dark skin tone"]={ 0x1F46E, 0x1F3FE },
+ ["police officer: medium-light skin tone"]={ 0x1F46E, 0x1F3FC },
+ ["poodle"]={ 0x1F429 },
+ ["pool 8 ball"]={ 0x1F3B1 },
+ ["popcorn"]={ 0x1F37F },
+ ["portugal"]={ 0x1F1F5, 0x1F1F9 },
+ ["post office"]={ 0x1F3E4 },
+ ["postal horn"]={ 0x1F4EF },
+ ["postbox"]={ 0x1F4EE },
+ ["pot of food"]={ 0x1F372 },
+ ["potable water"]={ 0x1F6B0 },
+ ["potato"]={ 0x1F954 },
+ ["poultry leg"]={ 0x1F357 },
+ ["pound banknote"]={ 0x1F4B7 },
+ ["pouting cat face"]={ 0x1F63E },
+ ["pouting face"]={ 0x1F621 },
+ ["prayer beads"]={ 0x1F4FF },
+ ["pregnant woman"]={ 0x1F930 },
+ ["pregnant woman: dark skin tone"]={ 0x1F930, 0x1F3FF },
+ ["pregnant woman: light skin tone"]={ 0x1F930, 0x1F3FB },
+ ["pregnant woman: medium skin tone"]={ 0x1F930, 0x1F3FD },
+ ["pregnant woman: medium-dark skin tone"]={ 0x1F930, 0x1F3FE },
+ ["pregnant woman: medium-light skin tone"]={ 0x1F930, 0x1F3FC },
+ ["pretzel"]={ 0x1F968 },
+ ["prince"]={ 0x1F934 },
+ ["prince: dark skin tone"]={ 0x1F934, 0x1F3FF },
+ ["prince: light skin tone"]={ 0x1F934, 0x1F3FB },
+ ["prince: medium skin tone"]={ 0x1F934, 0x1F3FD },
+ ["prince: medium-dark skin tone"]={ 0x1F934, 0x1F3FE },
+ ["prince: medium-light skin tone"]={ 0x1F934, 0x1F3FC },
+ ["princess"]={ 0x1F478 },
+ ["princess: dark skin tone"]={ 0x1F478, 0x1F3FF },
+ ["princess: light skin tone"]={ 0x1F478, 0x1F3FB },
+ ["princess: medium skin tone"]={ 0x1F478, 0x1F3FD },
+ ["princess: medium-dark skin tone"]={ 0x1F478, 0x1F3FE },
+ ["princess: medium-light skin tone"]={ 0x1F478, 0x1F3FC },
+ ["printer"]={ 0x1F5A8 },
+ ["prohibited"]={ 0x1F6AB },
+ ["puerto rico"]={ 0x1F1F5, 0x1F1F7 },
+ ["purple heart"]={ 0x1F49C },
+ ["purse"]={ 0x1F45B },
+ ["pushpin"]={ 0x1F4CC },
+ ["qatar"]={ 0x1F1F6, 0x1F1E6 },
+ ["question mark"]={ 0x2753 },
+ ["rabbit"]={ 0x1F407 },
+ ["rabbit face"]={ 0x1F430 },
+ ["racing car"]={ 0x1F3CE },
+ ["radio"]={ 0x1F4FB },
+ ["radio button"]={ 0x1F518 },
+ ["radioactive"]={ 0x2622 },
+ ["railway car"]={ 0x1F683 },
+ ["railway track"]={ 0x1F6E4 },
+ ["rainbow"]={ 0x1F308 },
+ ["rainbow flag"]={ 0x1F3F3, 0x200D, 0x1F308 },
+ ["raised back of hand"]={ 0x1F91A },
+ ["raised back of hand: dark skin tone"]={ 0x1F91A, 0x1F3FF },
+ ["raised back of hand: light skin tone"]={ 0x1F91A, 0x1F3FB },
+ ["raised back of hand: medium skin tone"]={ 0x1F91A, 0x1F3FD },
+ ["raised back of hand: medium-dark skin tone"]={ 0x1F91A, 0x1F3FE },
+ ["raised back of hand: medium-light skin tone"]={ 0x1F91A, 0x1F3FC },
+ ["raised fist"]={ 0x270A },
+ ["raised fist: dark skin tone"]={ 0x270A, 0x1F3FF },
+ ["raised fist: light skin tone"]={ 0x270A, 0x1F3FB },
+ ["raised fist: medium skin tone"]={ 0x270A, 0x1F3FD },
+ ["raised fist: medium-dark skin tone"]={ 0x270A, 0x1F3FE },
+ ["raised fist: medium-light skin tone"]={ 0x270A, 0x1F3FC },
+ ["raised hand"]={ 0x270B },
+ ["raised hand with fingers splayed"]={ 0x1F590 },
+ ["raised hand with fingers splayed: dark skin tone"]={ 0x1F590, 0x1F3FF },
+ ["raised hand with fingers splayed: light skin tone"]={ 0x1F590, 0x1F3FB },
+ ["raised hand with fingers splayed: medium skin tone"]={ 0x1F590, 0x1F3FD },
+ ["raised hand with fingers splayed: medium-dark skin tone"]={ 0x1F590, 0x1F3FE },
+ ["raised hand with fingers splayed: medium-light skin tone"]={ 0x1F590, 0x1F3FC },
+ ["raised hand: dark skin tone"]={ 0x270B, 0x1F3FF },
+ ["raised hand: light skin tone"]={ 0x270B, 0x1F3FB },
+ ["raised hand: medium skin tone"]={ 0x270B, 0x1F3FD },
+ ["raised hand: medium-dark skin tone"]={ 0x270B, 0x1F3FE },
+ ["raised hand: medium-light skin tone"]={ 0x270B, 0x1F3FC },
+ ["raising hands"]={ 0x1F64C },
+ ["raising hands: dark skin tone"]={ 0x1F64C, 0x1F3FF },
+ ["raising hands: light skin tone"]={ 0x1F64C, 0x1F3FB },
+ ["raising hands: medium skin tone"]={ 0x1F64C, 0x1F3FD },
+ ["raising hands: medium-dark skin tone"]={ 0x1F64C, 0x1F3FE },
+ ["raising hands: medium-light skin tone"]={ 0x1F64C, 0x1F3FC },
+ ["ram"]={ 0x1F40F },
+ ["rat"]={ 0x1F400 },
+ ["record button"]={ 0x23FA },
+ ["recycling symbol"]={ 0x267B },
+ ["red apple"]={ 0x1F34E },
+ ["red circle"]={ 0x1F534 },
+ ["red heart"]={ 0x2764 },
+ ["red paper lantern"]={ 0x1F3EE },
+ ["red triangle pointed down"]={ 0x1F53B },
+ ["red triangle pointed up"]={ 0x1F53A },
+ ["registered"]={ 0xAE },
+ ["relieved face"]={ 0x1F60C },
+ ["reminder ribbon"]={ 0x1F397 },
+ ["repeat button"]={ 0x1F501 },
+ ["repeat single button"]={ 0x1F502 },
+ ["rescue worker’s helmet"]={ 0x26D1 },
+ ["restroom"]={ 0x1F6BB },
+ ["reverse button"]={ 0x25C0 },
+ ["revolving hearts"]={ 0x1F49E },
+ ["rhinoceros"]={ 0x1F98F },
+ ["ribbon"]={ 0x1F380 },
+ ["rice ball"]={ 0x1F359 },
+ ["rice cracker"]={ 0x1F358 },
+ ["right anger bubble"]={ 0x1F5EF },
+ ["right arrow"]={ 0x27A1 },
+ ["right arrow curving down"]={ 0x2935 },
+ ["right arrow curving left"]={ 0x21A9 },
+ ["right arrow curving up"]={ 0x2934 },
+ ["right-facing fist"]={ 0x1F91C },
+ ["right-facing fist: dark skin tone"]={ 0x1F91C, 0x1F3FF },
+ ["right-facing fist: light skin tone"]={ 0x1F91C, 0x1F3FB },
+ ["right-facing fist: medium skin tone"]={ 0x1F91C, 0x1F3FD },
+ ["right-facing fist: medium-dark skin tone"]={ 0x1F91C, 0x1F3FE },
+ ["right-facing fist: medium-light skin tone"]={ 0x1F91C, 0x1F3FC },
+ ["right-pointing magnifying glass"]={ 0x1F50E },
+ ["ring"]={ 0x1F48D },
+ ["roasted sweet potato"]={ 0x1F360 },
+ ["robot face"]={ 0x1F916 },
+ ["rocket"]={ 0x1F680 },
+ ["rolled-up newspaper"]={ 0x1F5DE },
+ ["roller coaster"]={ 0x1F3A2 },
+ ["rolling on the floor laughing"]={ 0x1F923 },
+ ["romania"]={ 0x1F1F7, 0x1F1F4 },
+ ["rooster"]={ 0x1F413 },
+ ["rose"]={ 0x1F339 },
+ ["rosette"]={ 0x1F3F5 },
+ ["round pushpin"]={ 0x1F4CD },
+ ["rugby football"]={ 0x1F3C9 },
+ ["running shirt"]={ 0x1F3BD },
+ ["running shoe"]={ 0x1F45F },
+ ["russia"]={ 0x1F1F7, 0x1F1FA },
+ ["rwanda"]={ 0x1F1F7, 0x1F1FC },
+ ["réunion"]={ 0x1F1F7, 0x1F1EA },
+ ["sagittarius"]={ 0x2650 },
+ ["sailboat"]={ 0x26F5 },
+ ["sake"]={ 0x1F376 },
+ ["samoa"]={ 0x1F1FC, 0x1F1F8 },
+ ["san marino"]={ 0x1F1F8, 0x1F1F2 },
+ ["sandwich"]={ 0x1F96A },
+ ["santa claus"]={ 0x1F385 },
+ ["santa claus: dark skin tone"]={ 0x1F385, 0x1F3FF },
+ ["santa claus: light skin tone"]={ 0x1F385, 0x1F3FB },
+ ["santa claus: medium skin tone"]={ 0x1F385, 0x1F3FD },
+ ["santa claus: medium-dark skin tone"]={ 0x1F385, 0x1F3FE },
+ ["santa claus: medium-light skin tone"]={ 0x1F385, 0x1F3FC },
+ ["satellite"]={ 0x1F6F0 },
+ ["satellite antenna"]={ 0x1F4E1 },
+ ["saudi arabia"]={ 0x1F1F8, 0x1F1E6 },
+ ["sauropod"]={ 0x1F995 },
+ ["saxophone"]={ 0x1F3B7 },
+ ["scarf"]={ 0x1F9E3 },
+ ["school"]={ 0x1F3EB },
+ ["school backpack"]={ 0x1F392 },
+ ["scissors"]={ 0x2702 },
+ ["scorpion"]={ 0x1F982 },
+ ["scorpius"]={ 0x264F },
+ ["scotland"]={ 0x1F3F4, 0xE0067, 0xE0062, 0xE0073, 0xE0063, 0xE0074, 0xE007F },
+ ["scroll"]={ 0x1F4DC },
+ ["seat"]={ 0x1F4BA },
+ ["see-no-evil monkey"]={ 0x1F648 },
+ ["seedling"]={ 0x1F331 },
+ ["selfie"]={ 0x1F933 },
+ ["selfie: dark skin tone"]={ 0x1F933, 0x1F3FF },
+ ["selfie: light skin tone"]={ 0x1F933, 0x1F3FB },
+ ["selfie: medium skin tone"]={ 0x1F933, 0x1F3FD },
+ ["selfie: medium-dark skin tone"]={ 0x1F933, 0x1F3FE },
+ ["selfie: medium-light skin tone"]={ 0x1F933, 0x1F3FC },
+ ["senegal"]={ 0x1F1F8, 0x1F1F3 },
+ ["serbia"]={ 0x1F1F7, 0x1F1F8 },
+ ["seven o’clock"]={ 0x1F556 },
+ ["seven-thirty"]={ 0x1F562 },
+ ["seychelles"]={ 0x1F1F8, 0x1F1E8 },
+ ["shallow pan of food"]={ 0x1F958 },
+ ["shamrock"]={ 0x2618 },
+ ["shark"]={ 0x1F988 },
+ ["shaved ice"]={ 0x1F367 },
+ ["sheaf of rice"]={ 0x1F33E },
+ ["shield"]={ 0x1F6E1 },
+ ["shinto shrine"]={ 0x26E9 },
+ ["ship"]={ 0x1F6A2 },
+ ["shooting star"]={ 0x1F320 },
+ ["shopping bags"]={ 0x1F6CD },
+ ["shopping cart"]={ 0x1F6D2 },
+ ["shortcake"]={ 0x1F370 },
+ ["shower"]={ 0x1F6BF },
+ ["shrimp"]={ 0x1F990 },
+ ["shuffle tracks button"]={ 0x1F500 },
+ ["shushing face"]={ 0x1F92B },
+ ["sierra leone"]={ 0x1F1F8, 0x1F1F1 },
+ ["sign of the horns"]={ 0x1F918 },
+ ["sign of the horns: dark skin tone"]={ 0x1F918, 0x1F3FF },
+ ["sign of the horns: light skin tone"]={ 0x1F918, 0x1F3FB },
+ ["sign of the horns: medium skin tone"]={ 0x1F918, 0x1F3FD },
+ ["sign of the horns: medium-dark skin tone"]={ 0x1F918, 0x1F3FE },
+ ["sign of the horns: medium-light skin tone"]={ 0x1F918, 0x1F3FC },
+ ["singapore"]={ 0x1F1F8, 0x1F1EC },
+ ["sint maarten"]={ 0x1F1F8, 0x1F1FD },
+ ["six o’clock"]={ 0x1F555 },
+ ["six-thirty"]={ 0x1F561 },
+ ["skier"]={ 0x26F7 },
+ ["skis"]={ 0x1F3BF },
+ ["skull"]={ 0x1F480 },
+ ["skull and crossbones"]={ 0x2620 },
+ ["sled"]={ 0x1F6F7 },
+ ["sleeping face"]={ 0x1F634 },
+ ["sleepy face"]={ 0x1F62A },
+ ["slightly frowning face"]={ 0x1F641 },
+ ["slightly smiling face"]={ 0x1F642 },
+ ["slot machine"]={ 0x1F3B0 },
+ ["slovakia"]={ 0x1F1F8, 0x1F1F0 },
+ ["slovenia"]={ 0x1F1F8, 0x1F1EE },
+ ["small airplane"]={ 0x1F6E9 },
+ ["small blue diamond"]={ 0x1F539 },
+ ["small orange diamond"]={ 0x1F538 },
+ ["smiling cat face with heart-eyes"]={ 0x1F63B },
+ ["smiling cat face with open mouth"]={ 0x1F63A },
+ ["smiling face"]={ 0x263A },
+ ["smiling face with halo"]={ 0x1F607 },
+ ["smiling face with heart-eyes"]={ 0x1F60D },
+ ["smiling face with horns"]={ 0x1F608 },
+ ["smiling face with open mouth"]={ 0x1F603 },
+ ["smiling face with open mouth & closed eyes"]={ 0x1F606 },
+ ["smiling face with open mouth & cold sweat"]={ 0x1F605 },
+ ["smiling face with open mouth & smiling eyes"]={ 0x1F604 },
+ ["smiling face with smiling eyes"]={ 0x1F60A },
+ ["smiling face with sunglasses"]={ 0x1F60E },
+ ["smirking face"]={ 0x1F60F },
+ ["snail"]={ 0x1F40C },
+ ["snake"]={ 0x1F40D },
+ ["sneezing face"]={ 0x1F927 },
+ ["snow-capped mountain"]={ 0x1F3D4 },
+ ["snowboarder"]={ 0x1F3C2 },
+ ["snowboarder: dark skin tone"]={ 0x1F3C2, 0x1F3FF },
+ ["snowboarder: light skin tone"]={ 0x1F3C2, 0x1F3FB },
+ ["snowboarder: medium skin tone"]={ 0x1F3C2, 0x1F3FD },
+ ["snowboarder: medium-dark skin tone"]={ 0x1F3C2, 0x1F3FE },
+ ["snowboarder: medium-light skin tone"]={ 0x1F3C2, 0x1F3FC },
+ ["snowflake"]={ 0x2744 },
+ ["snowman"]={ 0x2603 },
+ ["snowman without snow"]={ 0x26C4 },
+ ["soccer ball"]={ 0x26BD },
+ ["socks"]={ 0x1F9E6 },
+ ["soft ice cream"]={ 0x1F366 },
+ ["solomon islands"]={ 0x1F1F8, 0x1F1E7 },
+ ["somalia"]={ 0x1F1F8, 0x1F1F4 },
+ ["soon arrow"]={ 0x1F51C },
+ ["sos button"]={ 0x1F198 },
+ ["south africa"]={ 0x1F1FF, 0x1F1E6 },
+ ["south georgia & south sandwich islands"]={ 0x1F1EC, 0x1F1F8 },
+ ["south korea"]={ 0x1F1F0, 0x1F1F7 },
+ ["south sudan"]={ 0x1F1F8, 0x1F1F8 },
+ ["spade suit"]={ 0x2660 },
+ ["spaghetti"]={ 0x1F35D },
+ ["spain"]={ 0x1F1EA, 0x1F1F8 },
+ ["sparkle"]={ 0x2747 },
+ ["sparkler"]={ 0x1F387 },
+ ["sparkles"]={ 0x2728 },
+ ["sparkling heart"]={ 0x1F496 },
+ ["speak-no-evil monkey"]={ 0x1F64A },
+ ["speaker high volume"]={ 0x1F50A },
+ ["speaker low volume"]={ 0x1F508 },
+ ["speaker medium volume"]={ 0x1F509 },
+ ["speaking head"]={ 0x1F5E3 },
+ ["speech balloon"]={ 0x1F4AC },
+ ["speedboat"]={ 0x1F6A4 },
+ ["spider"]={ 0x1F577 },
+ ["spider web"]={ 0x1F578 },
+ ["spiral calendar"]={ 0x1F5D3 },
+ ["spiral notepad"]={ 0x1F5D2 },
+ ["spiral shell"]={ 0x1F41A },
+ ["spoon"]={ 0x1F944 },
+ ["sport utility vehicle"]={ 0x1F699 },
+ ["sports medal"]={ 0x1F3C5 },
+ ["spouting whale"]={ 0x1F433 },
+ ["squid"]={ 0x1F991 },
+ ["sri lanka"]={ 0x1F1F1, 0x1F1F0 },
+ ["st. barthélemy"]={ 0x1F1E7, 0x1F1F1 },
+ ["st. helena"]={ 0x1F1F8, 0x1F1ED },
+ ["st. kitts & nevis"]={ 0x1F1F0, 0x1F1F3 },
+ ["st. lucia"]={ 0x1F1F1, 0x1F1E8 },
+ ["st. martin"]={ 0x1F1F2, 0x1F1EB },
+ ["st. pierre & miquelon"]={ 0x1F1F5, 0x1F1F2 },
+ ["st. vincent & grenadines"]={ 0x1F1FB, 0x1F1E8 },
+ ["stadium"]={ 0x1F3DF },
+ ["star and crescent"]={ 0x262A },
+ ["star of david"]={ 0x2721 },
+ ["star-struck"]={ 0x1F929 },
+ ["station"]={ 0x1F689 },
+ ["statue of liberty"]={ 0x1F5FD },
+ ["steaming bowl"]={ 0x1F35C },
+ ["stop button"]={ 0x23F9 },
+ ["stop sign"]={ 0x1F6D1 },
+ ["stopwatch"]={ 0x23F1 },
+ ["straight ruler"]={ 0x1F4CF },
+ ["strawberry"]={ 0x1F353 },
+ ["studio microphone"]={ 0x1F399 },
+ ["stuffed flatbread"]={ 0x1F959 },
+ ["sudan"]={ 0x1F1F8, 0x1F1E9 },
+ ["sun"]={ 0x2600 },
+ ["sun behind cloud"]={ 0x26C5 },
+ ["sun behind large cloud"]={ 0x1F325 },
+ ["sun behind rain cloud"]={ 0x1F326 },
+ ["sun behind small cloud"]={ 0x1F324 },
+ ["sun with face"]={ 0x1F31E },
+ ["sunflower"]={ 0x1F33B },
+ ["sunglasses"]={ 0x1F576 },
+ ["sunrise"]={ 0x1F305 },
+ ["sunrise over mountains"]={ 0x1F304 },
+ ["sunset"]={ 0x1F307 },
+ ["suriname"]={ 0x1F1F8, 0x1F1F7 },
+ ["sushi"]={ 0x1F363 },
+ ["suspension railway"]={ 0x1F69F },
+ ["svalbard & jan mayen"]={ 0x1F1F8, 0x1F1EF },
+ ["swaziland"]={ 0x1F1F8, 0x1F1FF },
+ ["sweat droplets"]={ 0x1F4A6 },
+ ["sweden"]={ 0x1F1F8, 0x1F1EA },
+ ["switzerland"]={ 0x1F1E8, 0x1F1ED },
+ ["synagogue"]={ 0x1F54D },
+ ["syria"]={ 0x1F1F8, 0x1F1FE },
+ ["syringe"]={ 0x1F489 },
+ ["são tomé & príncipe"]={ 0x1F1F8, 0x1F1F9 },
+ ["t-rex"]={ 0x1F996 },
+ ["t-shirt"]={ 0x1F455 },
+ ["taco"]={ 0x1F32E },
+ ["taiwan"]={ 0x1F1F9, 0x1F1FC },
+ ["tajikistan"]={ 0x1F1F9, 0x1F1EF },
+ ["takeout box"]={ 0x1F961 },
+ ["tanabata tree"]={ 0x1F38B },
+ ["tangerine"]={ 0x1F34A },
+ ["tanzania"]={ 0x1F1F9, 0x1F1FF },
+ ["taurus"]={ 0x2649 },
+ ["taxi"]={ 0x1F695 },
+ ["teacup without handle"]={ 0x1F375 },
+ ["tear-off calendar"]={ 0x1F4C6 },
+ ["telephone"]={ 0x260E },
+ ["telephone receiver"]={ 0x1F4DE },
+ ["telescope"]={ 0x1F52D },
+ ["television"]={ 0x1F4FA },
+ ["ten o’clock"]={ 0x1F559 },
+ ["ten-thirty"]={ 0x1F565 },
+ ["tennis"]={ 0x1F3BE },
+ ["tent"]={ 0x26FA },
+ ["thailand"]={ 0x1F1F9, 0x1F1ED },
+ ["thermometer"]={ 0x1F321 },
+ ["thinking face"]={ 0x1F914 },
+ ["thought balloon"]={ 0x1F4AD },
+ ["three o’clock"]={ 0x1F552 },
+ ["three-thirty"]={ 0x1F55E },
+ ["thumbs down"]={ 0x1F44E },
+ ["thumbs down: dark skin tone"]={ 0x1F44E, 0x1F3FF },
+ ["thumbs down: light skin tone"]={ 0x1F44E, 0x1F3FB },
+ ["thumbs down: medium skin tone"]={ 0x1F44E, 0x1F3FD },
+ ["thumbs down: medium-dark skin tone"]={ 0x1F44E, 0x1F3FE },
+ ["thumbs down: medium-light skin tone"]={ 0x1F44E, 0x1F3FC },
+ ["thumbs up"]={ 0x1F44D },
+ ["thumbs up: dark skin tone"]={ 0x1F44D, 0x1F3FF },
+ ["thumbs up: light skin tone"]={ 0x1F44D, 0x1F3FB },
+ ["thumbs up: medium skin tone"]={ 0x1F44D, 0x1F3FD },
+ ["thumbs up: medium-dark skin tone"]={ 0x1F44D, 0x1F3FE },
+ ["thumbs up: medium-light skin tone"]={ 0x1F44D, 0x1F3FC },
+ ["ticket"]={ 0x1F3AB },
+ ["tiger"]={ 0x1F405 },
+ ["tiger face"]={ 0x1F42F },
+ ["timer clock"]={ 0x23F2 },
+ ["timor-leste"]={ 0x1F1F9, 0x1F1F1 },
+ ["tired face"]={ 0x1F62B },
+ ["togo"]={ 0x1F1F9, 0x1F1EC },
+ ["toilet"]={ 0x1F6BD },
+ ["tokelau"]={ 0x1F1F9, 0x1F1F0 },
+ ["tokyo tower"]={ 0x1F5FC },
+ ["tomato"]={ 0x1F345 },
+ ["tonga"]={ 0x1F1F9, 0x1F1F4 },
+ ["tongue"]={ 0x1F445 },
+ ["top arrow"]={ 0x1F51D },
+ ["top hat"]={ 0x1F3A9 },
+ ["tornado"]={ 0x1F32A },
+ ["trackball"]={ 0x1F5B2 },
+ ["tractor"]={ 0x1F69C },
+ ["trade mark"]={ 0x2122 },
+ ["train"]={ 0x1F686 },
+ ["tram"]={ 0x1F68A },
+ ["tram car"]={ 0x1F68B },
+ ["triangular flag"]={ 0x1F6A9 },
+ ["triangular ruler"]={ 0x1F4D0 },
+ ["trident emblem"]={ 0x1F531 },
+ ["trinidad & tobago"]={ 0x1F1F9, 0x1F1F9 },
+ ["tristan da cunha"]={ 0x1F1F9, 0x1F1E6 },
+ ["trolleybus"]={ 0x1F68E },
+ ["trophy"]={ 0x1F3C6 },
+ ["tropical drink"]={ 0x1F379 },
+ ["tropical fish"]={ 0x1F420 },
+ ["trumpet"]={ 0x1F3BA },
+ ["tulip"]={ 0x1F337 },
+ ["tumbler glass"]={ 0x1F943 },
+ ["tunisia"]={ 0x1F1F9, 0x1F1F3 },
+ ["turkey"]={ 0x1F1F9, 0x1F1F7 },
+ ["turkmenistan"]={ 0x1F1F9, 0x1F1F2 },
+ ["turks & caicos islands"]={ 0x1F1F9, 0x1F1E8 },
+ ["turtle"]={ 0x1F422 },
+ ["tuvalu"]={ 0x1F1F9, 0x1F1FB },
+ ["twelve o’clock"]={ 0x1F55B },
+ ["twelve-thirty"]={ 0x1F567 },
+ ["two hearts"]={ 0x1F495 },
+ ["two men holding hands"]={ 0x1F46C },
+ ["two o’clock"]={ 0x1F551 },
+ ["two women holding hands"]={ 0x1F46D },
+ ["two-hump camel"]={ 0x1F42B },
+ ["two-thirty"]={ 0x1F55D },
+ ["u.s. outlying islands"]={ 0x1F1FA, 0x1F1F2 },
+ ["u.s. virgin islands"]={ 0x1F1FB, 0x1F1EE },
+ ["uganda"]={ 0x1F1FA, 0x1F1EC },
+ ["ukraine"]={ 0x1F1FA, 0x1F1E6 },
+ ["umbrella"]={ 0x2602 },
+ ["umbrella on ground"]={ 0x26F1 },
+ ["umbrella with rain drops"]={ 0x2614 },
+ ["unamused face"]={ 0x1F612 },
+ ["unicorn face"]={ 0x1F984 },
+ ["united arab emirates"]={ 0x1F1E6, 0x1F1EA },
+ ["united kingdom"]={ 0x1F1EC, 0x1F1E7 },
+ ["united nations"]={ 0x1F1FA, 0x1F1F3 },
+ ["united states"]={ 0x1F1FA, 0x1F1F8 },
+ ["unlocked"]={ 0x1F513 },
+ ["up arrow"]={ 0x2B06 },
+ ["up button"]={ 0x1F53C },
+ ["up! button"]={ 0x1F199 },
+ ["up-down arrow"]={ 0x2195 },
+ ["up-left arrow"]={ 0x2196 },
+ ["up-right arrow"]={ 0x2197 },
+ ["upside-down face"]={ 0x1F643 },
+ ["uruguay"]={ 0x1F1FA, 0x1F1FE },
+ ["uzbekistan"]={ 0x1F1FA, 0x1F1FF },
+ ["vampire"]={ 0x1F9DB },
+ ["vampire: dark skin tone"]={ 0x1F9DB, 0x1F3FF },
+ ["vampire: light skin tone"]={ 0x1F9DB, 0x1F3FB },
+ ["vampire: medium skin tone"]={ 0x1F9DB, 0x1F3FD },
+ ["vampire: medium-dark skin tone"]={ 0x1F9DB, 0x1F3FE },
+ ["vampire: medium-light skin tone"]={ 0x1F9DB, 0x1F3FC },
+ ["vanuatu"]={ 0x1F1FB, 0x1F1FA },
+ ["vatican city"]={ 0x1F1FB, 0x1F1E6 },
+ ["venezuela"]={ 0x1F1FB, 0x1F1EA },
+ ["vertical traffic light"]={ 0x1F6A6 },
+ ["vibration mode"]={ 0x1F4F3 },
+ ["victory hand"]={ 0x270C },
+ ["victory hand: dark skin tone"]={ 0x270C, 0x1F3FF },
+ ["victory hand: light skin tone"]={ 0x270C, 0x1F3FB },
+ ["victory hand: medium skin tone"]={ 0x270C, 0x1F3FD },
+ ["victory hand: medium-dark skin tone"]={ 0x270C, 0x1F3FE },
+ ["victory hand: medium-light skin tone"]={ 0x270C, 0x1F3FC },
+ ["video camera"]={ 0x1F4F9 },
+ ["video game"]={ 0x1F3AE },
+ ["videocassette"]={ 0x1F4FC },
+ ["vietnam"]={ 0x1F1FB, 0x1F1F3 },
+ ["violin"]={ 0x1F3BB },
+ ["virgo"]={ 0x264D },
+ ["volcano"]={ 0x1F30B },
+ ["volleyball"]={ 0x1F3D0 },
+ ["vs button"]={ 0x1F19A },
+ ["vulcan salute"]={ 0x1F596 },
+ ["vulcan salute: dark skin tone"]={ 0x1F596, 0x1F3FF },
+ ["vulcan salute: light skin tone"]={ 0x1F596, 0x1F3FB },
+ ["vulcan salute: medium skin tone"]={ 0x1F596, 0x1F3FD },
+ ["vulcan salute: medium-dark skin tone"]={ 0x1F596, 0x1F3FE },
+ ["vulcan salute: medium-light skin tone"]={ 0x1F596, 0x1F3FC },
+ ["wales"]={ 0x1F3F4, 0xE0067, 0xE0062, 0xE0077, 0xE006C, 0xE0073, 0xE007F },
+ ["wallis & futuna"]={ 0x1F1FC, 0x1F1EB },
+ ["waning crescent moon"]={ 0x1F318 },
+ ["waning gibbous moon"]={ 0x1F316 },
+ ["warning"]={ 0x26A0 },
+ ["wastebasket"]={ 0x1F5D1 },
+ ["watch"]={ 0x231A },
+ ["water buffalo"]={ 0x1F403 },
+ ["water closet"]={ 0x1F6BE },
+ ["water wave"]={ 0x1F30A },
+ ["watermelon"]={ 0x1F349 },
+ ["waving hand"]={ 0x1F44B },
+ ["waving hand: dark skin tone"]={ 0x1F44B, 0x1F3FF },
+ ["waving hand: light skin tone"]={ 0x1F44B, 0x1F3FB },
+ ["waving hand: medium skin tone"]={ 0x1F44B, 0x1F3FD },
+ ["waving hand: medium-dark skin tone"]={ 0x1F44B, 0x1F3FE },
+ ["waving hand: medium-light skin tone"]={ 0x1F44B, 0x1F3FC },
+ ["wavy dash"]={ 0x3030 },
+ ["waxing crescent moon"]={ 0x1F312 },
+ ["waxing gibbous moon"]={ 0x1F314 },
+ ["weary cat face"]={ 0x1F640 },
+ ["weary face"]={ 0x1F629 },
+ ["wedding"]={ 0x1F492 },
+ ["western sahara"]={ 0x1F1EA, 0x1F1ED },
+ ["whale"]={ 0x1F40B },
+ ["wheel of dharma"]={ 0x2638 },
+ ["wheelchair symbol"]={ 0x267F },
+ ["white circle"]={ 0x26AA },
+ ["white exclamation mark"]={ 0x2755 },
+ ["white flag"]={ 0x1F3F3 },
+ ["white flower"]={ 0x1F4AE },
+ ["white heavy check mark"]={ 0x2705 },
+ ["white large square"]={ 0x2B1C },
+ ["white medium square"]={ 0x25FB },
+ ["white medium star"]={ 0x2B50 },
+ ["white medium-small square"]={ 0x25FD },
+ ["white question mark"]={ 0x2754 },
+ ["white small square"]={ 0x25AB },
+ ["white square button"]={ 0x1F533 },
+ ["wilted flower"]={ 0x1F940 },
+ ["wind chime"]={ 0x1F390 },
+ ["wind face"]={ 0x1F32C },
+ ["wine glass"]={ 0x1F377 },
+ ["winking face"]={ 0x1F609 },
+ ["wolf face"]={ 0x1F43A },
+ ["woman"]={ 0x1F469 },
+ ["woman artist"]={ 0x1F469, 0x200D, 0x1F3A8 },
+ ["woman artist: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F3A8 },
+ ["woman artist: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F3A8 },
+ ["woman artist: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F3A8 },
+ ["woman artist: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F3A8 },
+ ["woman artist: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F3A8 },
+ ["woman astronaut"]={ 0x1F469, 0x200D, 0x1F680 },
+ ["woman astronaut: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F680 },
+ ["woman astronaut: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F680 },
+ ["woman astronaut: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F680 },
+ ["woman astronaut: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F680 },
+ ["woman astronaut: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F680 },
+ ["woman biking"]={ 0x1F6B4, 0x200D, 0x2640 },
+ ["woman biking: dark skin tone"]={ 0x1F6B4, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman biking: light skin tone"]={ 0x1F6B4, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman biking: medium skin tone"]={ 0x1F6B4, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman biking: medium-dark skin tone"]={ 0x1F6B4, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman biking: medium-light skin tone"]={ 0x1F6B4, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman bouncing ball"]={ 0x26F9, 0x200D, 0x2640 },
+ ["woman bouncing ball: dark skin tone"]={ 0x26F9, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman bouncing ball: light skin tone"]={ 0x26F9, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman bouncing ball: medium skin tone"]={ 0x26F9, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman bouncing ball: medium-dark skin tone"]={ 0x26F9, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman bouncing ball: medium-light skin tone"]={ 0x26F9, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman bowing"]={ 0x1F647, 0x200D, 0x2640 },
+ ["woman bowing: dark skin tone"]={ 0x1F647, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman bowing: light skin tone"]={ 0x1F647, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman bowing: medium skin tone"]={ 0x1F647, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman bowing: medium-dark skin tone"]={ 0x1F647, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman bowing: medium-light skin tone"]={ 0x1F647, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman cartwheeling"]={ 0x1F938, 0x200D, 0x2640 },
+ ["woman cartwheeling: dark skin tone"]={ 0x1F938, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman cartwheeling: light skin tone"]={ 0x1F938, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman cartwheeling: medium skin tone"]={ 0x1F938, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman cartwheeling: medium-dark skin tone"]={ 0x1F938, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman cartwheeling: medium-light skin tone"]={ 0x1F938, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman climbing"]={ 0x1F9D7, 0x200D, 0x2640 },
+ ["woman climbing: dark skin tone"]={ 0x1F9D7, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman climbing: light skin tone"]={ 0x1F9D7, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman climbing: medium skin tone"]={ 0x1F9D7, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman climbing: medium-dark skin tone"]={ 0x1F9D7, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman climbing: medium-light skin tone"]={ 0x1F9D7, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman construction worker"]={ 0x1F477, 0x200D, 0x2640 },
+ ["woman construction worker: dark skin tone"]={ 0x1F477, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman construction worker: light skin tone"]={ 0x1F477, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman construction worker: medium skin tone"]={ 0x1F477, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman construction worker: medium-dark skin tone"]={ 0x1F477, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman construction worker: medium-light skin tone"]={ 0x1F477, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman cook"]={ 0x1F469, 0x200D, 0x1F373 },
+ ["woman cook: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F373 },
+ ["woman cook: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F373 },
+ ["woman cook: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F373 },
+ ["woman cook: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F373 },
+ ["woman cook: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F373 },
+ ["woman dancing"]={ 0x1F483 },
+ ["woman dancing: dark skin tone"]={ 0x1F483, 0x1F3FF },
+ ["woman dancing: light skin tone"]={ 0x1F483, 0x1F3FB },
+ ["woman dancing: medium skin tone"]={ 0x1F483, 0x1F3FD },
+ ["woman dancing: medium-dark skin tone"]={ 0x1F483, 0x1F3FE },
+ ["woman dancing: medium-light skin tone"]={ 0x1F483, 0x1F3FC },
+ ["woman detective"]={ 0x1F575, 0x200D, 0x2640 },
+ ["woman detective: dark skin tone"]={ 0x1F575, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman detective: light skin tone"]={ 0x1F575, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman detective: medium skin tone"]={ 0x1F575, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman detective: medium-dark skin tone"]={ 0x1F575, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman detective: medium-light skin tone"]={ 0x1F575, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman elf"]={ 0x1F9DD, 0x200D, 0x2640 },
+ ["woman elf: dark skin tone"]={ 0x1F9DD, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman elf: light skin tone"]={ 0x1F9DD, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman elf: medium skin tone"]={ 0x1F9DD, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman elf: medium-dark skin tone"]={ 0x1F9DD, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman elf: medium-light skin tone"]={ 0x1F9DD, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman facepalming"]={ 0x1F926, 0x200D, 0x2640 },
+ ["woman facepalming: dark skin tone"]={ 0x1F926, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman facepalming: light skin tone"]={ 0x1F926, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman facepalming: medium skin tone"]={ 0x1F926, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman facepalming: medium-dark skin tone"]={ 0x1F926, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman facepalming: medium-light skin tone"]={ 0x1F926, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman factory worker"]={ 0x1F469, 0x200D, 0x1F3ED },
+ ["woman factory worker: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F3ED },
+ ["woman factory worker: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F3ED },
+ ["woman factory worker: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F3ED },
+ ["woman factory worker: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F3ED },
+ ["woman factory worker: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F3ED },
+ ["woman fairy"]={ 0x1F9DA, 0x200D, 0x2640 },
+ ["woman fairy: dark skin tone"]={ 0x1F9DA, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman fairy: light skin tone"]={ 0x1F9DA, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman fairy: medium skin tone"]={ 0x1F9DA, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman fairy: medium-dark skin tone"]={ 0x1F9DA, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman fairy: medium-light skin tone"]={ 0x1F9DA, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman farmer"]={ 0x1F469, 0x200D, 0x1F33E },
+ ["woman farmer: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F33E },
+ ["woman farmer: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F33E },
+ ["woman farmer: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F33E },
+ ["woman farmer: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F33E },
+ ["woman farmer: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F33E },
+ ["woman firefighter"]={ 0x1F469, 0x200D, 0x1F692 },
+ ["woman firefighter: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F692 },
+ ["woman firefighter: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F692 },
+ ["woman firefighter: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F692 },
+ ["woman firefighter: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F692 },
+ ["woman firefighter: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F692 },
+ ["woman frowning"]={ 0x1F64D, 0x200D, 0x2640 },
+ ["woman frowning: dark skin tone"]={ 0x1F64D, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman frowning: light skin tone"]={ 0x1F64D, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman frowning: medium skin tone"]={ 0x1F64D, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman frowning: medium-dark skin tone"]={ 0x1F64D, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman frowning: medium-light skin tone"]={ 0x1F64D, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman genie"]={ 0x1F9DE, 0x200D, 0x2640 },
+ ["woman gesturing no"]={ 0x1F645, 0x200D, 0x2640 },
+ ["woman gesturing no: dark skin tone"]={ 0x1F645, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman gesturing no: light skin tone"]={ 0x1F645, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman gesturing no: medium skin tone"]={ 0x1F645, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman gesturing no: medium-dark skin tone"]={ 0x1F645, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman gesturing no: medium-light skin tone"]={ 0x1F645, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman gesturing ok"]={ 0x1F646, 0x200D, 0x2640 },
+ ["woman gesturing ok: dark skin tone"]={ 0x1F646, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman gesturing ok: light skin tone"]={ 0x1F646, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman gesturing ok: medium skin tone"]={ 0x1F646, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman gesturing ok: medium-dark skin tone"]={ 0x1F646, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman gesturing ok: medium-light skin tone"]={ 0x1F646, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman getting haircut"]={ 0x1F487, 0x200D, 0x2640 },
+ ["woman getting haircut: dark skin tone"]={ 0x1F487, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman getting haircut: light skin tone"]={ 0x1F487, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman getting haircut: medium skin tone"]={ 0x1F487, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman getting haircut: medium-dark skin tone"]={ 0x1F487, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman getting haircut: medium-light skin tone"]={ 0x1F487, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman getting massage"]={ 0x1F486, 0x200D, 0x2640 },
+ ["woman getting massage: dark skin tone"]={ 0x1F486, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman getting massage: light skin tone"]={ 0x1F486, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman getting massage: medium skin tone"]={ 0x1F486, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman getting massage: medium-dark skin tone"]={ 0x1F486, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman getting massage: medium-light skin tone"]={ 0x1F486, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman golfing"]={ 0x1F3CC, 0x200D, 0x2640 },
+ ["woman golfing: dark skin tone"]={ 0x1F3CC, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman golfing: light skin tone"]={ 0x1F3CC, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman golfing: medium skin tone"]={ 0x1F3CC, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman golfing: medium-dark skin tone"]={ 0x1F3CC, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman golfing: medium-light skin tone"]={ 0x1F3CC, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman guard"]={ 0x1F482, 0x200D, 0x2640 },
+ ["woman guard: dark skin tone"]={ 0x1F482, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman guard: light skin tone"]={ 0x1F482, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman guard: medium skin tone"]={ 0x1F482, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman guard: medium-dark skin tone"]={ 0x1F482, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman guard: medium-light skin tone"]={ 0x1F482, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman health worker"]={ 0x1F469, 0x200D, 0x2695 },
+ ["woman health worker: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x2695 },
+ ["woman health worker: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x2695 },
+ ["woman health worker: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x2695 },
+ ["woman health worker: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x2695 },
+ ["woman health worker: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x2695 },
+ ["woman in lotus position"]={ 0x1F9D8, 0x200D, 0x2640 },
+ ["woman in lotus position: dark skin tone"]={ 0x1F9D8, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman in lotus position: light skin tone"]={ 0x1F9D8, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman in lotus position: medium skin tone"]={ 0x1F9D8, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman in lotus position: medium-dark skin tone"]={ 0x1F9D8, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman in lotus position: medium-light skin tone"]={ 0x1F9D8, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman in steamy room"]={ 0x1F9D6, 0x200D, 0x2640 },
+ ["woman in steamy room: dark skin tone"]={ 0x1F9D6, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman in steamy room: light skin tone"]={ 0x1F9D6, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman in steamy room: medium skin tone"]={ 0x1F9D6, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman in steamy room: medium-dark skin tone"]={ 0x1F9D6, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman in steamy room: medium-light skin tone"]={ 0x1F9D6, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman judge"]={ 0x1F469, 0x200D, 0x2696 },
+ ["woman judge: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x2696 },
+ ["woman judge: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x2696 },
+ ["woman judge: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x2696 },
+ ["woman judge: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x2696 },
+ ["woman judge: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x2696 },
+ ["woman juggling"]={ 0x1F939, 0x200D, 0x2640 },
+ ["woman juggling: dark skin tone"]={ 0x1F939, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman juggling: light skin tone"]={ 0x1F939, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman juggling: medium skin tone"]={ 0x1F939, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman juggling: medium-dark skin tone"]={ 0x1F939, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman juggling: medium-light skin tone"]={ 0x1F939, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman lifting weights"]={ 0x1F3CB, 0x200D, 0x2640 },
+ ["woman lifting weights: dark skin tone"]={ 0x1F3CB, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman lifting weights: light skin tone"]={ 0x1F3CB, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman lifting weights: medium skin tone"]={ 0x1F3CB, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman lifting weights: medium-dark skin tone"]={ 0x1F3CB, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman lifting weights: medium-light skin tone"]={ 0x1F3CB, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman mage"]={ 0x1F9D9, 0x200D, 0x2640 },
+ ["woman mage: dark skin tone"]={ 0x1F9D9, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman mage: light skin tone"]={ 0x1F9D9, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman mage: medium skin tone"]={ 0x1F9D9, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman mage: medium-dark skin tone"]={ 0x1F9D9, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman mage: medium-light skin tone"]={ 0x1F9D9, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman mechanic"]={ 0x1F469, 0x200D, 0x1F527 },
+ ["woman mechanic: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F527 },
+ ["woman mechanic: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F527 },
+ ["woman mechanic: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F527 },
+ ["woman mechanic: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F527 },
+ ["woman mechanic: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F527 },
+ ["woman mountain biking"]={ 0x1F6B5, 0x200D, 0x2640 },
+ ["woman mountain biking: dark skin tone"]={ 0x1F6B5, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman mountain biking: light skin tone"]={ 0x1F6B5, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman mountain biking: medium skin tone"]={ 0x1F6B5, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman mountain biking: medium-dark skin tone"]={ 0x1F6B5, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman mountain biking: medium-light skin tone"]={ 0x1F6B5, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman office worker"]={ 0x1F469, 0x200D, 0x1F4BC },
+ ["woman office worker: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F4BC },
+ ["woman office worker: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F4BC },
+ ["woman office worker: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F4BC },
+ ["woman office worker: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F4BC },
+ ["woman office worker: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F4BC },
+ ["woman pilot"]={ 0x1F469, 0x200D, 0x2708 },
+ ["woman pilot: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x2708 },
+ ["woman pilot: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x2708 },
+ ["woman pilot: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x2708 },
+ ["woman pilot: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x2708 },
+ ["woman pilot: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x2708 },
+ ["woman playing handball"]={ 0x1F93E, 0x200D, 0x2640 },
+ ["woman playing handball: dark skin tone"]={ 0x1F93E, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman playing handball: light skin tone"]={ 0x1F93E, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman playing handball: medium skin tone"]={ 0x1F93E, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman playing handball: medium-dark skin tone"]={ 0x1F93E, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman playing handball: medium-light skin tone"]={ 0x1F93E, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman playing water polo"]={ 0x1F93D, 0x200D, 0x2640 },
+ ["woman playing water polo: dark skin tone"]={ 0x1F93D, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman playing water polo: light skin tone"]={ 0x1F93D, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman playing water polo: medium skin tone"]={ 0x1F93D, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman playing water polo: medium-dark skin tone"]={ 0x1F93D, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman playing water polo: medium-light skin tone"]={ 0x1F93D, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman police officer"]={ 0x1F46E, 0x200D, 0x2640 },
+ ["woman police officer: dark skin tone"]={ 0x1F46E, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman police officer: light skin tone"]={ 0x1F46E, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman police officer: medium skin tone"]={ 0x1F46E, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman police officer: medium-dark skin tone"]={ 0x1F46E, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman police officer: medium-light skin tone"]={ 0x1F46E, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman pouting"]={ 0x1F64E, 0x200D, 0x2640 },
+ ["woman pouting: dark skin tone"]={ 0x1F64E, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman pouting: light skin tone"]={ 0x1F64E, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman pouting: medium skin tone"]={ 0x1F64E, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman pouting: medium-dark skin tone"]={ 0x1F64E, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman pouting: medium-light skin tone"]={ 0x1F64E, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman raising hand"]={ 0x1F64B, 0x200D, 0x2640 },
+ ["woman raising hand: dark skin tone"]={ 0x1F64B, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman raising hand: light skin tone"]={ 0x1F64B, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman raising hand: medium skin tone"]={ 0x1F64B, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman raising hand: medium-dark skin tone"]={ 0x1F64B, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman raising hand: medium-light skin tone"]={ 0x1F64B, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman rowing boat"]={ 0x1F6A3, 0x200D, 0x2640 },
+ ["woman rowing boat: dark skin tone"]={ 0x1F6A3, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman rowing boat: light skin tone"]={ 0x1F6A3, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman rowing boat: medium skin tone"]={ 0x1F6A3, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman rowing boat: medium-dark skin tone"]={ 0x1F6A3, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman rowing boat: medium-light skin tone"]={ 0x1F6A3, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman running"]={ 0x1F3C3, 0x200D, 0x2640 },
+ ["woman running: dark skin tone"]={ 0x1F3C3, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman running: light skin tone"]={ 0x1F3C3, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman running: medium skin tone"]={ 0x1F3C3, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman running: medium-dark skin tone"]={ 0x1F3C3, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman running: medium-light skin tone"]={ 0x1F3C3, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman scientist"]={ 0x1F469, 0x200D, 0x1F52C },
+ ["woman scientist: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F52C },
+ ["woman scientist: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F52C },
+ ["woman scientist: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F52C },
+ ["woman scientist: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F52C },
+ ["woman scientist: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F52C },
+ ["woman shrugging"]={ 0x1F937, 0x200D, 0x2640 },
+ ["woman shrugging: dark skin tone"]={ 0x1F937, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman shrugging: light skin tone"]={ 0x1F937, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman shrugging: medium skin tone"]={ 0x1F937, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman shrugging: medium-dark skin tone"]={ 0x1F937, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman shrugging: medium-light skin tone"]={ 0x1F937, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman singer"]={ 0x1F469, 0x200D, 0x1F3A4 },
+ ["woman singer: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F3A4 },
+ ["woman singer: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F3A4 },
+ ["woman singer: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F3A4 },
+ ["woman singer: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F3A4 },
+ ["woman singer: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F3A4 },
+ ["woman student"]={ 0x1F469, 0x200D, 0x1F393 },
+ ["woman student: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F393 },
+ ["woman student: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F393 },
+ ["woman student: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F393 },
+ ["woman student: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F393 },
+ ["woman student: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F393 },
+ ["woman surfing"]={ 0x1F3C4, 0x200D, 0x2640 },
+ ["woman surfing: dark skin tone"]={ 0x1F3C4, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman surfing: light skin tone"]={ 0x1F3C4, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman surfing: medium skin tone"]={ 0x1F3C4, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman surfing: medium-dark skin tone"]={ 0x1F3C4, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman surfing: medium-light skin tone"]={ 0x1F3C4, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman swimming"]={ 0x1F3CA, 0x200D, 0x2640 },
+ ["woman swimming: dark skin tone"]={ 0x1F3CA, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman swimming: light skin tone"]={ 0x1F3CA, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman swimming: medium skin tone"]={ 0x1F3CA, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman swimming: medium-dark skin tone"]={ 0x1F3CA, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman swimming: medium-light skin tone"]={ 0x1F3CA, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman teacher"]={ 0x1F469, 0x200D, 0x1F3EB },
+ ["woman teacher: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F3EB },
+ ["woman teacher: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F3EB },
+ ["woman teacher: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F3EB },
+ ["woman teacher: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F3EB },
+ ["woman teacher: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F3EB },
+ ["woman technologist"]={ 0x1F469, 0x200D, 0x1F4BB },
+ ["woman technologist: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F4BB },
+ ["woman technologist: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F4BB },
+ ["woman technologist: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F4BB },
+ ["woman technologist: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F4BB },
+ ["woman technologist: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F4BB },
+ ["woman tipping hand"]={ 0x1F481, 0x200D, 0x2640 },
+ ["woman tipping hand: dark skin tone"]={ 0x1F481, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman tipping hand: light skin tone"]={ 0x1F481, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman tipping hand: medium skin tone"]={ 0x1F481, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman tipping hand: medium-dark skin tone"]={ 0x1F481, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman tipping hand: medium-light skin tone"]={ 0x1F481, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman vampire"]={ 0x1F9DB, 0x200D, 0x2640 },
+ ["woman vampire: dark skin tone"]={ 0x1F9DB, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman vampire: light skin tone"]={ 0x1F9DB, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman vampire: medium skin tone"]={ 0x1F9DB, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman vampire: medium-dark skin tone"]={ 0x1F9DB, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman vampire: medium-light skin tone"]={ 0x1F9DB, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman walking"]={ 0x1F6B6, 0x200D, 0x2640 },
+ ["woman walking: dark skin tone"]={ 0x1F6B6, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman walking: light skin tone"]={ 0x1F6B6, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman walking: medium skin tone"]={ 0x1F6B6, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman walking: medium-dark skin tone"]={ 0x1F6B6, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman walking: medium-light skin tone"]={ 0x1F6B6, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman wearing turban"]={ 0x1F473, 0x200D, 0x2640 },
+ ["woman wearing turban: dark skin tone"]={ 0x1F473, 0x1F3FF, 0x200D, 0x2640 },
+ ["woman wearing turban: light skin tone"]={ 0x1F473, 0x1F3FB, 0x200D, 0x2640 },
+ ["woman wearing turban: medium skin tone"]={ 0x1F473, 0x1F3FD, 0x200D, 0x2640 },
+ ["woman wearing turban: medium-dark skin tone"]={ 0x1F473, 0x1F3FE, 0x200D, 0x2640 },
+ ["woman wearing turban: medium-light skin tone"]={ 0x1F473, 0x1F3FC, 0x200D, 0x2640 },
+ ["woman with headscarf"]={ 0x1F9D5 },
+ ["woman with headscarf: dark skin tone"]={ 0x1F9D5, 0x1F3FF },
+ ["woman with headscarf: light skin tone"]={ 0x1F9D5, 0x1F3FB },
+ ["woman with headscarf: medium skin tone"]={ 0x1F9D5, 0x1F3FD },
+ ["woman with headscarf: medium-dark skin tone"]={ 0x1F9D5, 0x1F3FE },
+ ["woman with headscarf: medium-light skin tone"]={ 0x1F9D5, 0x1F3FC },
+ ["woman zombie"]={ 0x1F9DF, 0x200D, 0x2640 },
+ ["woman: dark skin tone"]={ 0x1F469, 0x1F3FF },
+ ["woman: light skin tone"]={ 0x1F469, 0x1F3FB },
+ ["woman: medium skin tone"]={ 0x1F469, 0x1F3FD },
+ ["woman: medium-dark skin tone"]={ 0x1F469, 0x1F3FE },
+ ["woman: medium-light skin tone"]={ 0x1F469, 0x1F3FC },
+ ["woman’s boot"]={ 0x1F462 },
+ ["woman’s clothes"]={ 0x1F45A },
+ ["woman’s hat"]={ 0x1F452 },
+ ["woman’s sandal"]={ 0x1F461 },
+ ["women with bunny ears partying"]={ 0x1F46F, 0x200D, 0x2640 },
+ ["women wrestling"]={ 0x1F93C, 0x200D, 0x2640 },
+ ["women’s room"]={ 0x1F6BA },
+ ["world map"]={ 0x1F5FA },
+ ["worried face"]={ 0x1F61F },
+ ["wrapped gift"]={ 0x1F381 },
+ ["wrench"]={ 0x1F527 },
+ ["writing hand"]={ 0x270D },
+ ["writing hand: dark skin tone"]={ 0x270D, 0x1F3FF },
+ ["writing hand: light skin tone"]={ 0x270D, 0x1F3FB },
+ ["writing hand: medium skin tone"]={ 0x270D, 0x1F3FD },
+ ["writing hand: medium-dark skin tone"]={ 0x270D, 0x1F3FE },
+ ["writing hand: medium-light skin tone"]={ 0x270D, 0x1F3FC },
+ ["yellow heart"]={ 0x1F49B },
+ ["yemen"]={ 0x1F1FE, 0x1F1EA },
+ ["yen banknote"]={ 0x1F4B4 },
+ ["yin yang"]={ 0x262F },
+ ["zambia"]={ 0x1F1FF, 0x1F1F2 },
+ ["zebra"]={ 0x1F993 },
+ ["zimbabwe"]={ 0x1F1FF, 0x1F1FC },
+ ["zipper-mouth face"]={ 0x1F910 },
+ ["zombie"]={ 0x1F9DF },
+ ["zzz"]={ 0x1F4A4 },
+ ["Åland islands"]={ 0x1F1E6, 0x1F1FD },
+}
diff --git a/tex/context/base/mkiv/char-ini.lua b/tex/context/base/mkiv/char-ini.lua
index 3cebeabd9..4f2b7a4d5 100644
--- a/tex/context/base/mkiv/char-ini.lua
+++ b/tex/context/base/mkiv/char-ini.lua
@@ -14,8 +14,9 @@ if not modules then modules = { } end modules ['char-ini'] = {
local utfchar, utfbyte, utfvalues, ustring, utotable = utf.char, utf.byte, utf.values, utf.ustring, utf.totable
local concat, unpack, tohash, insert = table.concat, table.unpack, table.tohash, table.insert
local next, tonumber, type, rawget, rawset = next, tonumber, type, rawget, rawset
-local format, lower, gsub, find = string.format, string.lower, string.gsub, string.find
-local P, R, S, Cs = lpeg.P, lpeg.R, lpeg.S, lpeg.Cs
+local format, lower, gsub, find, match = string.format, string.lower, string.gsub, string.find, string.match
+local P, R, S, C, Cs, Ct, Cc, V = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.Cc, lpeg.V
+local formatters = string.formatters
if not characters then require("char-def") end
@@ -1387,6 +1388,174 @@ function characters.showstring(str)
end
end
+do
+
+ -- There is no need to preload this table.
+
+ local any = P(1)
+ local special = S([['".,:;-+()]])
+ + P('“') + P('”')
+ local apostrofe = P("’") + P("'")
+
+ local pattern = Cs ( (
+ (P("medium light") / "medium-light" + P("medium dark") / "medium-dark") * P(" skin tone")
+ + (apostrofe * P("s"))/""
+ + special/""
+ + any
+ )^1)
+
+ local function load()
+ local name = resolvers.find_file("char-emj.lua")
+ local data = name and name ~= "" and dofile(name) or { }
+ local hash = { }
+ for d, c in next, data do
+ local k = lpegmatch(pattern,d) or d
+ local u = { }
+ for i=1,#c do
+ u[i] = utfchar(c[i])
+ end
+ u = concat(u)
+ hash[k] = u
+ end
+ return data, hash
+ end
+
+ local data, hash = nil, nil
+
+ function characters.emojized(name)
+ local t = lpegmatch(pattern,name)
+ if t then
+ return t
+ else
+ return { name }
+ end
+ end
+
+ local start = P(" ")
+ local finish = P(-1) + P(" ")
+ local skintone = P("medium ")^0 * (P("light ") + P("dark "))^0 * P("skin tone")
+ local gender = P("woman") + P("man")
+ local expanded = (
+ P("m-l-")/"medium-light"
+ + P("m-d-")/"medium-dark"
+ + P("l-") /"light"
+ + P("m-") /"medium"
+ + P("d-") /"dark"
+ )
+ * (P("s-t")/" skin tone")
+ local compacted = (
+ (P("medium-")/"m-" * (P("light")/"l" + P("dark")/"d"))
+ + (P("medium")/"m" + P("light")/"l" + P("dark")/"d")
+ )
+ * (P(" skin tone")/"-s-t")
+
+ local pattern_0 = Cs((expanded + any)^1)
+ local pattern_1 = Cs(((start * skintone + skintone * finish)/"" + any)^1)
+ local pattern_2 = Cs(((start * gender + gender * finish)/"" + any)^1)
+ local pattern_4 = Cs((compacted + any)^1)
+
+ -- print(lpegmatch(pattern_0,"kiss woman l-s-t man d-s-t"))
+ -- print(lpegmatch(pattern_0,"something m-l-s-t"))
+ -- print(lpegmatch(pattern_0,"something m-s-t"))
+ -- print(lpegmatch(pattern_4,"something medium-light skin tone"))
+ -- print(lpegmatch(pattern_4,"something medium skin tone"))
+
+ local skin =
+ P("light skin tone") / utfchar(0x1F3FB)
+ + P("medium-light skin tone") / utfchar(0x1F3FC)
+ + P("medium skin tone") / utfchar(0x1F3FD)
+ + P("medium-dark skin tone") / utfchar(0x1F3FE)
+ + P("dark skin tone") / utfchar(0x1F3FF)
+
+ local parent =
+ P("man") / utfchar(0x1F468)
+ + P("woman") / utfchar(0x1F469)
+
+ local child =
+ P("baby") / utfchar(0x1F476)
+ + P("boy") / utfchar(0x1F466)
+ + P("girl") / utfchar(0x1F467)
+
+ local zwj = utfchar(0x200D)
+ local heart = utfchar(0x2764) .. utfchar(0xFE0F) .. zwj
+ local kiss = utfchar(0x2764) .. utfchar(0xFE0F) .. utfchar(0x200D) .. utfchar(0x1F48B) .. zwj
+
+ ----- member = parent + child
+
+ local space = P(" ")
+ local final = P(-1)
+
+ local p_done = (space^1/zwj) + P(-1)
+ local p_rest = space/"" * (skin * p_done) + p_done
+ local p_parent = parent * p_rest
+ local p_child = child * p_rest
+
+ local p_family = Cs ( (P("family") * space^1)/"" * p_parent^-2 * p_child^-2 )
+ local p_couple = Cs ( (P("couple with heart") * space^1)/"" * p_parent * Cc(heart) * p_parent )
+ local p_kiss = Cs ( (P("kiss") * space^1)/"" * p_parent * Cc(kiss) * p_parent )
+
+ local p_special = p_family + p_couple + p_kiss
+
+-- print(lpeg.match(p_special,"family man woman girl"))
+-- print(lpeg.match(p_special,"family man dark skin tone woman girl girl"))
+
+ -- local p_special = P { "all",
+ -- all = Cs (V("family") + V("couple") + V("kiss")),
+ -- family = C("family") * space^1 * V("parent")^-2 * V("child")^-2,
+ -- couple = P("couple with heart") * space^1 * V("parent") * Cc(heart) * V("parent"),
+ -- kiss = P("kiss") * space^1 * V("parent") * Cc(kiss) * V("parent"),
+ -- parent = parent * V("rest"),
+ -- child = child * V("rest"),
+ -- rest = (space * skin)^0/"" * ((space^1/zwj) + P(-1)),
+ -- }
+
+ -- maybe characters.emoji.toutf
+
+ local emoji = { }
+ characters.emoji = emoji
+
+ function emoji.resolve(name)
+ if not hash then
+ data, hash = load()
+ end
+ local h = hash[name]
+ if h then
+ return h
+ end
+ -- expand shortcuts
+ local name = lpegmatch(pattern_0,name) or name
+ -- expand some 25K variants
+ local h = lpegmatch(p_special,name)
+ if h then
+ return h
+ end
+ -- simplify
+ local s = lpegmatch(pattern_1,name)
+ local h = hash[s]
+ if h then
+ return h
+ end
+ -- simplify
+ local s = lpegmatch(pattern_2,name)
+ local h = hash[s]
+ if h then
+ return h
+ end
+ end
+
+ function emoji.known()
+ if not hash then
+ data, hash = load()
+ end
+ return hash, data
+ end
+
+ function emoji.compact(name)
+ return lpegmatch(pattern_4,name) or name
+ end
+
+end
+
-- code moved to char-tex.lua
return characters
diff --git a/tex/context/base/mkiv/cldf-ini.lua b/tex/context/base/mkiv/cldf-ini.lua
index b0b731866..3c91f5fba 100644
--- a/tex/context/base/mkiv/cldf-ini.lua
+++ b/tex/context/base/mkiv/cldf-ini.lua
@@ -1450,11 +1450,19 @@ do
local p_texescape = patterns.texescape
function context.escaped(s)
- return context(lpegmatch(p_texescape,s) or s)
+ if s then
+ context(lpegmatch(p_texescape,s) or s)
+ else
+ -- context("")
+ end
end
function context.escape(s)
- return lpegmatch(p_texescape,s) or s or ""
+ if s then
+ return lpegmatch(p_texescape,s) or s
+ else
+ return ""
+ end
end
end
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index a6623f5c0..9e4ac8149 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2017.04.20 21:31}
+\newcontextversion{2017.04.27 01:00}
%D This file is loaded at runtime, thereby providing an excellent place for
%D hacks, patches, extensions and new features.
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index 220ec71db..51e0ae893 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -39,7 +39,7 @@
%D up and the dependencies are more consistent.
\edef\contextformat {\jobname}
-\edef\contextversion{2017.04.20 21:31}
+\edef\contextversion{2017.04.27 01:00}
\edef\contextkind {beta}
%D For those who want to use this:
@@ -443,6 +443,8 @@
\loadmarkfile{scrp-ini}
+\loadmarkfile{symb-emj}
+
\loadmarkfile{lang-wrd} % can be optional (discussion with mm sideeffect)
\loadmarkfile{lang-rep} % can be optional (bt 2013 side effect)
diff --git a/tex/context/base/mkiv/font-cff.lua b/tex/context/base/mkiv/font-cff.lua
index a799a67f5..1d4f01007 100644
--- a/tex/context/base/mkiv/font-cff.lua
+++ b/tex/context/base/mkiv/font-cff.lua
@@ -1831,6 +1831,9 @@ do
r = r + 1
result[r] = c_endchar
local stream = concat(result)
+ -- if trace_charstrings then
+ -- report("vdata: %s",stream)
+ -- end
if glyph then
glyph.stream = stream
else
@@ -2082,7 +2085,9 @@ local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams)
local dictionary = dictionaries[1]
readglobals(f,data)
readcharstrings(f,data,version)
- if version ~= "cff2" then
+ if version == "cff2" then
+ dictionary.charset = nil
+ else
readencodings(f,data)
readcharsets(f,data,dictionary)
end
@@ -2248,11 +2253,17 @@ function readers.cff2(f,fontdata,specification)
--
parsedictionaries(data,dictionaries,"cff2")
--
- local storeoffset = dictionaries[1].vstore + data.header.offset + 2 -- cff has a preceding size field
- local regions, deltas = readers.helpers.readvariationdata(f,storeoffset,factors)
- --
- data.regions = regions
- data.deltas = deltas
+ local offset = dictionaries[1].vstore
+ if offset > 0 then
+ local storeoffset = dictionaries[1].vstore + data.header.offset + 2 -- cff has a preceding size field
+ local regions, deltas = readers.helpers.readvariationdata(f,storeoffset,factors)
+ --
+ data.regions = regions
+ data.deltas = deltas
+ else
+ data.regions = { }
+ data.deltas = { }
+ end
data.factors = specification.factors
--
local cid = data.dictionaries[1].cid
diff --git a/tex/context/base/mkiv/font-col.lua b/tex/context/base/mkiv/font-col.lua
index d7b76a615..3698960b8 100644
--- a/tex/context/base/mkiv/font-col.lua
+++ b/tex/context/base/mkiv/font-col.lua
@@ -125,14 +125,15 @@ function collections.define(name,font,ranges,details)
offset = tonumber(offset) or false
end
d[#d+1] = {
- font = font,
- start = start,
- stop = stop,
- gaps = gaps,
- offset = offset,
- rscale = tonumber (details.rscale) or 1,
- force = toboolean(details.force,true),
- check = toboolean(details.check,true),
+ font = font,
+ start = start,
+ stop = stop,
+ gaps = gaps,
+ offset = offset,
+ rscale = tonumber (details.rscale) or 1,
+ force = toboolean(details.force,true),
+ check = toboolean(details.check,true),
+ features = details.features,
}
end
end
diff --git a/tex/context/base/mkiv/font-col.mkvi b/tex/context/base/mkiv/font-col.mkvi
index bc8e8151e..bd1109e5c 100644
--- a/tex/context/base/mkiv/font-col.mkvi
+++ b/tex/context/base/mkiv/font-col.mkvi
@@ -34,7 +34,9 @@
\unexpanded\def\resetfontfallback {\dodoubleempty \font_fallbacks_reset }
\def\font_fallbacks_define[#name][#font][#ranges][#settings]%
- {\clf_fontcollectiondefine{#name}{#font}{#ranges}{#settings}}
+ {\let\mathsizesuffix\relax
+ \clf_fontcollectiondefine{#name}{#font}{#ranges}{#settings}%
+ \let\mathsizesuffix\empty}
\def\font_fallbacks_reset[#name][#font]%
{\clf_fontcollectionreset{#name}{#font}}
@@ -92,6 +94,17 @@
\def\font_fallbacks_register_main #name{\clf_fontcollectionregister{#name}}
\def\font_fallbacks_prepare_clone_vectors#name{\clf_fontcollectionclone{#name}}
+% math (experiment, todo clf_)
+
+\def\font_fallbacks_register_math#1#2#3#4%
+ {\doifelsenothing{#3}%
+ {\definedfont[#2 at #4sp]}%
+ {\definedfont[#2*#3\space at #4\scaledpoint]}%
+ \ctxlua{mathematics.registerfallbackid(#1,\fontid\font)}}
+
+\def\font_fallbacks_finish_math
+ {\ctxlua{mathematics.finishfallbacks()}}
+
% check : only replace when present in replacement font (default: no)
% force : force replacent even when basefont has glyph (default: yes)
diff --git a/tex/context/base/mkiv/font-ctx.lua b/tex/context/base/mkiv/font-ctx.lua
index c81f9e2cb..b86ab59fb 100644
--- a/tex/context/base/mkiv/font-ctx.lua
+++ b/tex/context/base/mkiv/font-ctx.lua
@@ -2749,25 +2749,33 @@ end)
do
local settings_to_array = utilities.parsers.settings_to_array
- local namedcolorattributes = attributes.colors.namedcolorattributes
- local colorvalues = attributes.colors.values
+ -- local namedcolorattributes = attributes.colors.namedcolorattributes
+ -- local colorvalues = attributes.colors.values
+
+ -- implement {
+ -- name = "definefontcolorpalette",
+ -- arguments = { "string", "string" },
+ -- actions = function(name,set)
+ -- set = settings_to_array(set)
+ -- for i=1,#set do
+ -- local name = set[i]
+ -- local space, color = namedcolorattributes(name)
+ -- local values = colorvalues[color]
+ -- if values then
+ -- set[i] = { r = values[3], g = values[4], b = values[5] }
+ -- else
+ -- set[i] = { r = 0, g = 0, b = 0 }
+ -- end
+ -- end
+ -- otf.registerpalette(name,set)
+ -- end
+ -- }
implement {
name = "definefontcolorpalette",
arguments = { "string", "string" },
actions = function(name,set)
- set = settings_to_array(set)
- for i=1,#set do
- local name = set[i]
- local space, color = namedcolorattributes(name)
- local values = colorvalues[color]
- if values then
- set[i] = { r = values[3], g = values[4], b = values[5] }
- else
- set[i] = { r = 0, g = 0, b = 0 }
- end
- end
- otf.registerpalette(name,set)
+ otf.registerpalette(name,settings_to_array(set))
end
}
diff --git a/tex/context/base/mkiv/font-dsp.lua b/tex/context/base/mkiv/font-dsp.lua
index 1ea6a4908..d43348cdf 100644
--- a/tex/context/base/mkiv/font-dsp.lua
+++ b/tex/context/base/mkiv/font-dsp.lua
@@ -889,7 +889,13 @@ local function readlookuparray(f,noflookups,nofcurrent)
if index > length then
length = index
end
- lookups[index] = readushort(f) + 1
+ local lookup = readushort(f) + 1
+ local list = lookups[index]
+ if list then
+ list[#list+1] = lookup
+ else
+ lookups[index] = { lookup }
+ end
end
for index=1,length do
if not lookups[index] then
@@ -2185,50 +2191,63 @@ do
report_issue(i,what,sequence,"empty")
rule.lookups = nil
else
- -- we can have holes in rlookups
+ -- we can have holes in rlookups flagged false and we can have multiple lookups
+ -- applied (first time seen in seguemj)
local length = #rlookups
for index=1,length do
- local lookupid = rlookups[index]
- if lookupid then
- local h = sublookuphash[lookupid]
- if not h then
- -- here we have a lookup that is used independent as well
- -- as in another one
- local lookup = lookups[lookupid]
- if lookup then
- local d = lookup.done
- if d then
- nofsublookups = nofsublookups + 1
- -- report("registering %i as sublookup %i",lookupid,nofsublookups)
- h = {
- index = nofsublookups, -- handy for tracing
- name = f_lookupname(lookupprefix,"d",lookupid+lookupidoffset),
- derived = true, -- handy for tracing
- steps = d.steps,
- nofsteps = d.nofsteps,
- type = d.lookuptype or "gsub_single", -- todo: check type
- markclass = d.markclass or nil,
- flags = d.flags,
- -- chain = d.chain,
- }
- sublookuplist[nofsublookups] = copy(h) -- we repack later
- sublookuphash[lookupid] = nofsublookups
- sublookupcheck[lookupid] = 1
- h = nofsublookups
+ local lookuplist = rlookups[index]
+ if lookuplist then
+ local length = #lookuplist
+ local found = { }
+ local noffound = 0
+ for index=1,length do
+ local lookupid = lookuplist[index]
+ if lookupid then
+ local h = sublookuphash[lookupid]
+ if not h then
+ -- here we have a lookup that is used independent as well
+ -- as in another one
+ local lookup = lookups[lookupid]
+ if lookup then
+ local d = lookup.done
+ if d then
+ nofsublookups = nofsublookups + 1
+ -- report("registering %i as sublookup %i",lookupid,nofsublookups)
+ h = {
+ index = nofsublookups, -- handy for tracing
+ name = f_lookupname(lookupprefix,"d",lookupid+lookupidoffset),
+ derived = true, -- handy for tracing
+ steps = d.steps,
+ nofsteps = d.nofsteps,
+ type = d.lookuptype or "gsub_single", -- todo: check type
+ markclass = d.markclass or nil,
+ flags = d.flags,
+ -- chain = d.chain,
+ }
+ sublookuplist[nofsublookups] = copy(h) -- we repack later
+ sublookuphash[lookupid] = nofsublookups
+ sublookupcheck[lookupid] = 1
+ h = nofsublookups
+ else
+ report_issue(i,what,sequence,"missing")
+ rule.lookups = nil
+ break
+ end
+ else
+ report_issue(i,what,sequence,"bad")
+ rule.lookups = nil
+ break
+ end
else
- report_issue(i,what,sequence,"missing")
- rule.lookups = nil
- break
+ sublookupcheck[lookupid] = sublookupcheck[lookupid] + 1
+ end
+ if h then
+ noffound = noffound + 1
+ found[noffound] = h
end
- else
- report_issue(i,what,sequence,"bad")
- rule.lookups = nil
- break
end
- else
- sublookupcheck[lookupid] = sublookupcheck[lookupid] + 1
end
- rlookups[index] = h or false
+ rlookups[index] = noffound > 0 and found or false
else
rlookups[index] = false
end
@@ -3388,7 +3407,7 @@ function readers.fvar(f,fontdata,specification)
default = readfixed(f), -- idem
maximum = readfixed(f), -- idem
flags = readushort(f),
- name = lower(extras[readushort(f)]),
+ name = lower(extras[readushort(f)] or "bad name"),
}
local n = sizeofaxis - 20
if n > 0 then
diff --git a/tex/context/base/mkiv/font-mat.mkvi b/tex/context/base/mkiv/font-mat.mkvi
index 2e7c2080d..fb14f1114 100644
--- a/tex/context/base/mkiv/font-mat.mkvi
+++ b/tex/context/base/mkiv/font-mat.mkvi
@@ -127,14 +127,16 @@
\settrue \c_font_auto_size
\fi\fi}
+\let\mathsizesuffix\empty
+
\def\font_helpers_set_math_family_indeed#mrtag#family% \fontface etc are also used later on
{\let\savedfontbody\fontbody
\let\fontfamily#family%
% the order is important as we depend on known id's when completing fonts
- \let\fontface\!!plusthree\font_helpers_set_math_family_a\scriptscriptfont#mrtag\font
- \let\fontface\!!plustwo \font_helpers_set_math_family_a\scriptfont #mrtag\font
- \let\fontface\!!plusone \font_helpers_set_math_family_a\textfont #mrtag\font
- \let\fontface\!!zerocount
+ \let\mathsizesuffix\mathtextsuffix \let\fontface\!!plusthree\font_helpers_set_math_family_a\scriptscriptfont#mrtag\font
+ \let\mathsizesuffix\mathscriptsuffix \let\fontface\!!plustwo \font_helpers_set_math_family_a\scriptfont #mrtag\font
+ \let\mathsizesuffix\mathscriptscriptsuffix\let\fontface\!!plusone \font_helpers_set_math_family_a\textfont #mrtag\font
+ \let\mathsizesuffix\empty \let\fontface\!!zerocount
\let\fontbody\savedfontbody
\setfalse\c_font_auto_size}
@@ -159,10 +161,10 @@
\let\defaultfontclass\fontclass % else truefontname falls back on the wrong one
\let\savedfontbody\fontbody
\let\fontfamily#familytag%
- \let\fontface\!!plusthree\font_helpers_set_math_family_bold_a\scriptscriptfont#mbfam#mrfam%
- \let\fontface\!!plustwo \font_helpers_set_math_family_bold_a\scriptfont #mbfam#mrfam%
- \let\fontface\!!plusone \font_helpers_set_math_family_bold_a\textfont #mbfam#mrfam%
- \let\fontface\!!zerocount
+ \let\mathsizesuffix\mathtextsuffix \let\fontface\!!plusthree\font_helpers_set_math_family_bold_a\scriptscriptfont#mbfam#mrfam%
+ \let\mathsizesuffix\mathscriptsuffix \let\fontface\!!plustwo \font_helpers_set_math_family_bold_a\scriptfont #mbfam#mrfam%
+ \let\mathsizesuffix\mathscriptscriptsuffix\let\fontface\!!plusone \font_helpers_set_math_family_bold_a\textfont #mbfam#mrfam%
+ \let\mathsizesuffix\empty \let\fontface\!!zerocount
\let\fontbody\savedfontbody
\let\defaultfontclass\savedfontclass
\setfalse\c_font_auto_size}
diff --git a/tex/context/base/mkiv/font-mis.lua b/tex/context/base/mkiv/font-mis.lua
index 5a3bf4999..6d5c9fbf2 100644
--- a/tex/context/base/mkiv/font-mis.lua
+++ b/tex/context/base/mkiv/font-mis.lua
@@ -21,7 +21,7 @@ local readers = otf.readers
if readers then
- otf.version = otf.version or 3.027
+ otf.version = otf.version or 3.029
otf.cache = otf.cache or containers.define("fonts", "otl", otf.version, true)
function fonts.helpers.getfeatures(name,save)
diff --git a/tex/context/base/mkiv/font-nod.lua b/tex/context/base/mkiv/font-nod.lua
index 2b70ee104..9166970b8 100644
--- a/tex/context/base/mkiv/font-nod.lua
+++ b/tex/context/base/mkiv/font-nod.lua
@@ -439,7 +439,10 @@ function step_tracers.check(head)
local n = copy_node_list(h)
freeze(n,"check")
injections.keepcounts(n) -- one-time
- injections.handler(n,"trace")
+ local l = injections.handler(n,"trace")
+ if l then -- hm, can be false
+ n = tonut(l)
+ end
protect_glyphs(n)
collection[1] = n
end
@@ -453,7 +456,10 @@ function step_tracers.register(head)
local n = copy_node_list(h)
freeze(n,"register")
injections.keepcounts(n) -- one-time
- injections.handler(n,"trace")
+ local l = injections.handler(n,"trace")
+ if l then -- hm, can be false
+ n = tonut(l)
+ end
protect_glyphs(n)
collection[nc] = n
end
diff --git a/tex/context/base/mkiv/font-ocl.lua b/tex/context/base/mkiv/font-ocl.lua
index c1ab2e592..5ab90084b 100644
--- a/tex/context/base/mkiv/font-ocl.lua
+++ b/tex/context/base/mkiv/font-ocl.lua
@@ -19,7 +19,6 @@ local otf = fonts.handlers.otf
local f_color = formatters["pdf:direct:%f %f %f rg"]
local f_gray = formatters["pdf:direct:%f g"]
-local s_black = "pdf:direct:0 g"
if context then
@@ -48,32 +47,40 @@ end
local sharedpalettes = { }
+local hash = table.setmetatableindex(function(t,k)
+ local v = { "special", k }
+ t[k] = v
+ return v
+end)
+
if context then
- local graytorgb = attributes.colors.graytorgb
- local cmyktorgb = attributes.colors.cmyktorgb
+ local colors = attributes.list[attributes.private('color')] or { }
+ local transparencies = attributes.list[attributes.private('transparency')] or { }
function otf.registerpalette(name,values)
sharedpalettes[name] = values
for i=1,#values do
local v = values[i]
- local r, g, b
- local s = v.s
- if s then
- r, g, b = graytorgb(s)
+ local c = nil
+ local t = nil
+ if type(v) == "table" then
+ c = colors.register(name,"rgb",
+ max(round((v.r or 0)*255),255)/255,
+ max(round((v.g or 0)*255),255)/255,
+ max(round((v.b or 0)*255),255)/255
+ )
else
- local c, m, y, k = v.c, v.m, v.y, v.k
- if c or m or y or k then
- r, g, b = cmyktorgb(c or 0,m or 0,y or 0,k or 0)
- else
- r, g, b = v.r, v.g, v.b
- end
+ c = colors[v]
+ t = transparencies[v]
+ end
+ if c and t then
+ values[i] = hash["pdf:direct:" .. lpdf.color(1,c) .. " " .. lpdf.transparency(t)]
+ elseif c then
+ values[i] = hash["pdf:direct:" .. lpdf.color(1,c)]
+ elseif t then
+ values[i] = hash["pdf:direct:" .. lpdf.color(1,t)]
end
- values[i] = {
- max(r and round(r*255) or 0,255),
- max(g and round(g*255) or 0,255),
- max(b and round(b*255) or 0,255)
- }
end
end
@@ -83,23 +90,51 @@ else -- for generic
sharedpalettes[name] = values
for i=1,#values do
local v = values[i]
- values[i] = {
- max(round((v.r or 0)*255),255),
- max(round((v.g or 0)*255),255),
- max(round((v.b or 0)*255),255)
- }
+ values[i] = hash[f_color(
+ max(round((v.r or 0)*255),255)/255,
+ max(round((v.g or 0)*255),255)/255,
+ max(round((v.b or 0)*255),255)/255
+ )]
end
end
end
+-- We need to force page first because otherwise the q's get outside
+-- the font switch and as a consequence the next character has no font
+-- set (well, it has: the preceding one). As a consequence these fonts
+-- are somewhat inefficient as each glyph gets the font set. It's a
+-- side effect of the fact that a font is handled when a character gets
+-- flushed.
+
+local function convert(t,k)
+ local v = { }
+ for i=1,#k do
+ local p = k[i]
+ local r, g, b = p[1], p[2], p[3]
+ if r == g and g == b then
+ v[i] = hash[f_gray(r/255)]
+ else
+ v[i] = hash[f_color(r/255,g/255,b/255)]
+ end
+ end
+ t[k] = v
+ return v
+end
+
local function initializecolr(tfmdata,kind,value) -- hm, always value
if value then
- local palettes = tfmdata.resources.colorpalettes
+ local resources = tfmdata.resources
+ local palettes = resources.colorpalettes
if palettes then
--
- local palette = sharedpalettes[value] or palettes[tonumber(value) or 1] or palettes[1] or { }
- local classes = #palette
+ local converted = resources.converted
+ if not converted then
+ converted = table.setmetatableindex(convert)
+ resources.converted = converted
+ end
+ local colorvalues = sharedpalettes[value] or converted[palettes[tonumber(value) or 1] or palettes[1]] or { }
+ local classes = #colorvalues
if classes == 0 then
return
end
@@ -107,24 +142,22 @@ local function initializecolr(tfmdata,kind,value) -- hm, always value
local characters = tfmdata.characters
local descriptions = tfmdata.descriptions
local properties = tfmdata.properties
- local colorvalues = { }
--
properties.virtualized = true
tfmdata.fonts = {
{ id = 0 }
}
- --
- for i=1,classes do
- local p = palette[i]
- local r, g, b = p[1], p[2], p[3]
- if r == g and g == b then
- colorvalues[i] = { "special", f_gray(r/255) }
- else
- colorvalues[i] = { "special", f_color(r/255,g/255,b/255) }
- end
- end
+ local widths = table.setmetatableindex(function(t,k)
+ local v = { "right", -k }
+ t[k] = v
+ return v
+ end)
--
local getactualtext = otf.getactualtext
+ local default = colorvalues[#colorvalues]
+ local endactual = nil
+ local start = { "special", "pdf:page:q" }
+ local stop = { "special", "pdf:raw:Q" }
--
for unicode, character in next, characters do
local description = descriptions[unicode]
@@ -134,31 +167,30 @@ local function initializecolr(tfmdata,kind,value) -- hm, always value
local b, e = getactualtext(tounicode(characters[unicode].unicode or 0xFFFD))
local w = character.width or 0
local s = #colorlist
+ local goback = w ~= 0 and widths[w] or nil
local t = {
- -- We need to force page first because otherwise the q's get outside
- -- the font switch and as a consequence the next character has no font
- -- set (well, it has: the preceding one). As a consequence these fonts
- -- are somewhat inefficient as each glyph gets the font set. It's a
- -- side effect of the fact that a font is handled when a character gets
- -- flushed.
- { "special", "pdf:page:q" },
+ start,
{ "special", "pdf:raw:" .. b }
- -- This is not ok:
- -- { "special", "pdf:direct:q " .. b },
}
local n = #t
+ local l = nil
for i=1,s do
local entry = colorlist[i]
- n = n + 1 t[n] = colorvalues[entry.class] or s_black
+ local v = colorvalues[entry.class] or default
+ if v and l ~= v then
+ n = n + 1 t[n] = v
+ l = v
+ end
n = n + 1 t[n] = { "char", entry.slot }
- if s > 1 and i < s and w ~= 0 then
- n = n + 1 t[n] = { "right", -w }
+ if s > 1 and i < s and goback then
+ n = n + 1 t[n] = goback
end
end
- n = n + 1 t[n] = { "special", "pdf:page:" .. e }
- n = n + 1 t[n] = { "special", "pdf:raw:Q" }
- -- This is not ok:
- -- n = n + 1 t[n] = { "special", "pdf:direct:" .. e .. " Q"}
+ if not endactual then
+ endactual = { "special", "pdf:page:" .. e } -- saves tables
+ end
+ n = n + 1 t[n] = endactual
+ n = n + 1 t[n] = stop
character.commands = t
end
end
diff --git a/tex/context/base/mkiv/font-otc.lua b/tex/context/base/mkiv/font-otc.lua
index 1866591b4..5d879ec1d 100644
--- a/tex/context/base/mkiv/font-otc.lua
+++ b/tex/context/base/mkiv/font-otc.lua
@@ -446,10 +446,16 @@ local function addfeature(data,feature,specifications)
local t = type(v)
if t == "table" then
-- already ok
+ for i=1,#v do
+ local vi = v[i]
+ if type(vi) ~= "table" then
+ v[i] = { vi }
+ end
+ end
elseif t == "number" then
local lookup = sublookups[v]
if lookup then
- lookups[k] = lookup
+ lookups[k] = { lookup }
if not subtype then
subtype = lookup.type
end
diff --git a/tex/context/base/mkiv/font-otj.lua b/tex/context/base/mkiv/font-otj.lua
index 50330cb83..fb526ecbb 100644
--- a/tex/context/base/mkiv/font-otj.lua
+++ b/tex/context/base/mkiv/font-otj.lua
@@ -575,7 +575,7 @@ local function inject_kerns_only(head,where)
-- left|glyph|right
local leftkern = i.leftkern
if leftkern and leftkern ~= 0 then
- insert_node_before(head,current,newkern(leftkern))
+ head = insert_node_before(head,current,newkern(leftkern))
end
end
if prevdisc then
@@ -1007,7 +1007,7 @@ local function inject_everything(head,where)
ox = px - pn.markx
end
else
- ox = px - pn.markx
+ ox = px - pn.markx - rightkern -- seguiemj needs the rightkern
end
end
else
@@ -1032,6 +1032,7 @@ local function inject_everything(head,where)
-- -- we're too late anyway as kerns are already injected so
-- -- we do it the ugly way (no checking if the previous is
-- -- already a kern) .. maybe we should fix the font instead
+ -- hm, no head ?
insert_node_before(n,n,newkern(-wn))
insert_node_after(n,n,newkern(-wn))
end
@@ -1116,7 +1117,7 @@ local function inject_everything(head,where)
-- left|glyph|right
local leftkern = i.leftkern
if leftkern and leftkern ~= 0 then
- insert_node_before(head,current,newkern(leftkern))
+ head = insert_node_before(head,current,newkern(leftkern))
end
local rightkern = i.rightkern
if rightkern and rightkern ~= 0 then
diff --git a/tex/context/base/mkiv/font-otl.lua b/tex/context/base/mkiv/font-otl.lua
index c0b152a5b..9400096a0 100644
--- a/tex/context/base/mkiv/font-otl.lua
+++ b/tex/context/base/mkiv/font-otl.lua
@@ -52,7 +52,7 @@ local report_otf = logs.reporter("fonts","otf loading")
local fonts = fonts
local otf = fonts.handlers.otf
-otf.version = 3.028 -- beware: also sync font-mis.lua and in mtx-fonts
+otf.version = 3.029 -- beware: also sync font-mis.lua and in mtx-fonts
otf.cache = containers.define("fonts", "otl", otf.version, true)
otf.svgcache = containers.define("fonts", "svg", otf.version, true)
otf.sbixcache = containers.define("fonts", "sbix", otf.version, true)
diff --git a/tex/context/base/mkiv/font-otr.lua b/tex/context/base/mkiv/font-otr.lua
index fcfe6e824..4c29d05f6 100644
--- a/tex/context/base/mkiv/font-otr.lua
+++ b/tex/context/base/mkiv/font-otr.lua
@@ -83,6 +83,9 @@ local report = logs.reporter("otf reader")
local trace_cmap = false -- only for checking issues
local trace_cmap_detail = false -- only for checking issues
+-- local trace_cmap = true
+-- local trace_cmap_detail = true
+
fonts = fonts or { }
local handlers = fonts.handlers or { }
fonts.handlers = handlers
@@ -1275,6 +1278,7 @@ local sequence = {
-- variants
{ 0, 5, 14 },
-- last resort ranges
+{ 0, 4, 12 },
{ 3, 10, 13 },
}
@@ -2075,19 +2079,27 @@ local function readdata(f,offset,specification)
local instance = specification.instance
if type(instance) == "string" then
local factors = helpers.getfactors(fontdata,instance)
- specification.factors = factors
- fontdata.factors = factors
- fontdata.instance = instance
- report("user instance: %s, factors: % t",instance,factors)
+ if factors then
+ specification.factors = factors
+ fontdata.factors = factors
+ fontdata.instance = instance
+ report("user instance: %s, factors: % t",instance,factors)
+ else
+ report("user instance: %s, bad factors",instance)
+ end
end
end
if not fontdata.factors then
if fontdata.variabledata then
local factors = helpers.getfactors(fontdata,true)
- specification.factors = factors
- fontdata.factors = factors
- fontdata.instance = instance
- report("font instance: %s, factors: % t",instance,factors)
+ if factors then
+ specification.factors = factors
+ fontdata.factors = factors
+ fontdata.instance = instance
+ report("font instance: %s, factors: % t",instance,factors)
+ else
+ report("user instance: %s, bad factors",instance)
+ end
end
end
diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua
index c86a0ccda..16c2ce735 100644
--- a/tex/context/base/mkiv/font-ots.lua
+++ b/tex/context/base/mkiv/font-ots.lua
@@ -1943,16 +1943,19 @@ local function chainrun(head,start,last,dataset,sequence,rlmode,ck,skipped)
-- -- bad rules
-- end
local chainlookup = chainlookups[1]
- local chainkind = chainlookup.type
- local chainproc = chainprocs[chainkind]
- if chainproc then
- local ok
- head, start, ok = chainproc(head,start,last,dataset,sequence,chainlookup,rlmode,1)
- if ok then
- done = true
+ for j=1,#chainlookup do
+ local chainstep = chainlookup[j]
+ local chainkind = chainstep.type
+ local chainproc = chainprocs[chainkind]
+ if chainproc then
+ local ok
+ head, start, ok = chainproc(head,start,last,dataset,sequence,chainstep,rlmode,1)
+ if ok then
+ done = true
+ end
+ else
+ logprocess("%s: %s is not yet supported (1)",cref(dataset,sequence),chainkind)
end
- else
- logprocess("%s: %s is not yet supported (1)",cref(dataset,sequence),chainkind)
end
else
-- See LookupType 5: Contextual Substitution Subtable. Now it becomes messy. The
@@ -1963,6 +1966,8 @@ local function chainrun(head,start,last,dataset,sequence,rlmode,ck,skipped)
--
-- U+1105 U+119E U+1105 U+119E : sourcehansansklight: script=hang ccmp=yes
--
+ -- Even worse are these family emoji shapes as they can have multiple lookups
+ -- per slot (probably only for gpos).
local i = 1
while start do
if skipped then
@@ -1982,22 +1987,25 @@ local function chainrun(head,start,last,dataset,sequence,rlmode,ck,skipped)
end
local chainlookup = chainlookups[i]
if chainlookup then
- local chainkind = chainlookup.type
- local chainproc = chainprocs[chainkind]
- if chainproc then
- local ok, n
- head, start, ok, n = chainproc(head,start,last,dataset,sequence,chainlookup,rlmode,i)
- -- messy since last can be changed !
- if ok then
- done = true
- if n and n > 1 and i + n > nofchainlookups then
- -- this is a safeguard, we just ignore the rest of the lookups
- break
+ for j=1,#chainlookup do
+ local chainstep = chainlookup[j]
+ local chainkind = chainstep.type
+ local chainproc = chainprocs[chainkind]
+ if chainproc then
+ local ok, n
+ head, start, ok, n = chainproc(head,start,last,dataset,sequence,chainstep,rlmode,i)
+ -- messy since last can be changed !
+ if ok then
+ done = true
+ if n and n > 1 and i + n > nofchainlookups then
+ -- this is a safeguard, we just ignore the rest of the lookups
+ break
+ end
end
+ else
+ -- actually an error
+ logprocess("%s: %s is not yet supported (2)",cref(dataset,sequence),chainkind)
end
- else
- -- actually an error
- logprocess("%s: %s is not yet supported (2)",cref(dataset,sequence),chainkind)
end
end
i = i + 1
diff --git a/tex/context/base/mkiv/font-oup.lua b/tex/context/base/mkiv/font-oup.lua
index bbc8436b2..75ae08526 100644
--- a/tex/context/base/mkiv/font-oup.lua
+++ b/tex/context/base/mkiv/font-oup.lua
@@ -891,7 +891,7 @@ function readers.rehash(fontdata,hashmethod) -- TODO: combine loops in one
unifymissing(fontdata)
-- stripredundant(fontdata)
else
- fontdata.hashmethod = "unicode"
+ fontdata.hashmethod = "unicodes"
local indices = unifyglyphs(fontdata)
unifyresources(fontdata,indices)
copyduplicates(fontdata)
@@ -908,10 +908,10 @@ function readers.checkhash(fontdata)
elseif hashmethod == "names" and fontdata.names then
unifyresources(fontdata,fontdata.names)
copyduplicates(fontdata)
- fontdata.hashmethod = "unicode"
+ fontdata.hashmethod = "unicodes"
fontdata.names = nil -- no need for it
else
- readers.rehash(fontdata,"unicode")
+ readers.rehash(fontdata,"unicodes")
end
end
@@ -1332,7 +1332,7 @@ function readers.pack(data)
local r = rule.before if r then for i=1,#r do r[i] = pack_boolean(r[i]) end end
local r = rule.after if r then for i=1,#r do r[i] = pack_boolean(r[i]) end end
local r = rule.current if r then for i=1,#r do r[i] = pack_boolean(r[i]) end end
- local r = rule.lookups if r then rule.lookups = pack_mixed (r) end
+ -- local r = rule.lookups if r then rule.lookups = pack_mixed (r) end
local r = rule.replacements if r then rule.replacements = pack_flat (r) end
end
end
@@ -1795,13 +1795,13 @@ function readers.unpack(data)
end
end
end
- local lookups = rule.lookups
- if lookups then
- local tv = tables[lookups]
- if tv then
- rule.lookups = tv
- end
- end
+ -- local lookups = rule.lookups
+ -- if lookups then
+ -- local tv = tables[lookups]
+ -- if tv then
+ -- rule.lookups = tv
+ -- end
+ -- end
local replacements = rule.replacements
if replacements then
local tv = tables[replacements]
@@ -2334,16 +2334,20 @@ function readers.expand(data)
local lookups = rule.lookups or false
local subtype = nil
if lookups then
- -- is now indexed
- for k, v in next, lookups do
- local lookup = sublookups[v]
- if lookup then
- lookups[k] = lookup
- if not subtype then
- subtype = lookup.type
+ for i=1,#lookups do
+ local lookups = lookups[i]
+ if lookups then
+ for k, v in next, lookups do
+ local lookup = sublookups[v]
+ if lookup then
+ lookups[k] = lookup
+ if not subtype then
+ subtype = lookup.type
+ end
+ else
+ -- already expanded
+ end
end
- else
- -- already expanded
end
end
end
diff --git a/tex/context/base/mkiv/font-pre.mkiv b/tex/context/base/mkiv/font-pre.mkiv
index 0994221eb..9336fa352 100644
--- a/tex/context/base/mkiv/font-pre.mkiv
+++ b/tex/context/base/mkiv/font-pre.mkiv
@@ -336,6 +336,15 @@
[boldened]
[extend=1.2]
+%D Emoji:
+
+\definefontfeature[bandw:overlay][ccmp=yes,dist=yes]
+\definefontfeature[color:overlay][ccmp=yes,dist=yes,colr=yes]
+%definefontfeature[bandw:svg] [ccmp=yes,dist=yes]
+\definefontfeature[color:svg] [ccmp=yes,dist=yes,svg=yes]
+%definefontfeature[bandw:bitmap] [ccmp=yes,dist=yes,sbix=yes]
+\definefontfeature[color:bitmap] [ccmp=yes,dist=yes,sbix=yes]
+
%D We define some colors that are used in tracing (for instance \OPENTYPE\
%D features). We cannot yet inherit because no colors are predefined.
diff --git a/tex/context/base/mkiv/l-table.lua b/tex/context/base/mkiv/l-table.lua
index 6bb0ef637..3c1ce6daf 100644
--- a/tex/context/base/mkiv/l-table.lua
+++ b/tex/context/base/mkiv/l-table.lua
@@ -555,7 +555,7 @@ local reserved = table.tohash { -- intercept a language inconvenience: no reserv
-- return nil
-- end
-local function is_simple_table(t) -- also used in util-tab so maybe public
+local function is_simple_table(t,hexify) -- also used in util-tab so maybe public
local nt = #t
if nt > 0 then
local n = 0
@@ -699,7 +699,7 @@ local function do_serialize(root,name,depth,level,indexed)
if next(v) == nil then
handle(format("%s {},",depth))
elseif inline then -- and #t > 0
- local st = is_simple_table(v)
+ local st = is_simple_table(v,hexify)
if st then
handle(format("%s { %s },",depth,concat(st,", ")))
else
@@ -785,7 +785,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%q]={},",depth,k))
end
elseif inline then
- local st = is_simple_table(v)
+ local st = is_simple_table(v,hexify)
if st then
if tk == "number" then
if hexify then
diff --git a/tex/context/base/mkiv/lpdf-col.lua b/tex/context/base/mkiv/lpdf-col.lua
index 15d21cbf3..b5973ba88 100644
--- a/tex/context/base/mkiv/lpdf-col.lua
+++ b/tex/context/base/mkiv/lpdf-col.lua
@@ -421,7 +421,7 @@ end
-- transparency
-local transparencies = { [0] =
+local pdftransparencies = { [0] =
pdfconstant("Normal"),
pdfconstant("Normal"),
pdfconstant("Multiply"),
@@ -453,7 +453,7 @@ function registrations.transparency(n,a,t)
Type = pdf_extgstate,
ca = 1,
CA = 1,
- BM = transparencies[1],
+ BM = pdftransparencies[1],
AIS = false,
}
local m = pdfflushobject(d)
@@ -468,7 +468,7 @@ function registrations.transparency(n,a,t)
Type = pdf_extgstate,
ca = tonumber(t),
CA = tonumber(t),
- BM = transparencies[tonumber(a)] or transparencies[0],
+ BM = pdftransparencies[tonumber(a)] or pdftransparencies[0],
AIS = false,
}
local m = pdfflushobject(d)
diff --git a/tex/context/base/mkiv/math-act.lua b/tex/context/base/mkiv/math-act.lua
index 602c3dc89..ee78b64f0 100644
--- a/tex/context/base/mkiv/math-act.lua
+++ b/tex/context/base/mkiv/math-act.lua
@@ -590,7 +590,134 @@ blocks["uppercasedoublestruck"].gaps = {
-- todo: tounicode
+-- function mathematics.injectfallbacks(target,original)
+-- local properties = original.properties
+-- if properties and properties.hasmath then
+-- local specification = target.specification
+-- if specification then
+-- local fallbacks = specification.fallbacks
+-- if fallbacks then
+-- local definitions = fonts.collections.definitions[fallbacks]
+-- if definitions then
+-- if trace_collecting then
+-- report_math("adding fallback characters to font %a",specification.hash)
+-- end
+-- local definedfont = fonts.definers.internal
+-- local copiedglyph = fonts.handlers.vf.math.copy_glyph
+-- local fonts = target.fonts
+-- local size = specification.size -- target.size
+-- local characters = target.characters
+-- if not fonts then
+-- fonts = { }
+-- target.fonts = fonts
+-- target.type = "virtual"
+-- target.properties.virtualized = true
+-- end
+-- if #fonts == 0 then
+-- fonts[1] = { id = 0, size = size } -- sel, will be resolved later
+-- end
+-- local done = { }
+-- for i=1,#definitions do
+-- local definition = definitions[i]
+-- local name = definition.font
+-- local start = definition.start
+-- local stop = definition.stop
+-- local gaps = definition.gaps
+-- local check = definition.check
+-- local force = definition.force
+-- local rscale = definition.rscale or 1
+-- local offset = definition.offset or start
+-- local id = definedfont { name = name, size = size * rscale }
+-- local index = #fonts + 1
+-- fonts[index] = { id = id, size = size }
+-- local chars = fontchars[id]
+-- local function remap(unic,unicode,gap)
+-- local unic = unicode + offset - start
+-- if check and not chars[unicode] then
+-- -- not in font
+-- elseif force or (not done[unic] and not characters[unic]) then
+-- if trace_collecting then
+-- report_math("remapping math character, vector %a, font %a, character %C%s%s",
+-- fallbacks,name,unic,check and ", checked",gap and ", gap plugged")
+-- end
+-- characters[unic] = copiedglyph(target,characters,chars,unicode,index)
+-- done[unic] = true
+-- end
+-- end
+-- for unicode = start, stop do
+-- local unic = unicode + offset - start
+-- remap(unic,unicode,false)
+-- end
+-- if gaps then
+-- for unic, unicode in next, gaps do
+-- remap(unic,unicode,true)
+-- end
+-- end
+-- end
+-- end
+-- end
+-- end
+-- end
+-- end
+
+local stack = { }
+
+function mathematics.registerfallbackid(n,id)
+ local top = stack[#stack]
+ if top then
+ top.list[n] = id
+ else
+ report_math("stack underrun in math fallbacks")
+ end
+end
+
function mathematics.injectfallbacks(target,original)
+ if #stack > 0 then
+ -- for now
+ return
+ end
+ local properties = original.properties
+ if properties and properties.hasmath then
+ local specification = target.specification
+ if specification then
+ local fallbacks = specification.fallbacks
+ if fallbacks then
+ local definitions = fonts.collections.definitions[fallbacks]
+ if definitions then
+ table.insert(stack, {
+ target = target,
+ original = original,
+ list = { },
+ })
+ if trace_collecting then
+ report_math("adding fallback characters to font %a",specification.hash)
+ end
+ local size = specification.size -- target.size
+ context.pushcatcodes("prt") -- context.unprotect()
+ for i=1,#definitions do
+ local definition = definitions[i]
+ local name = definition.font
+ local features = definition.features or ""
+ local size = size * (definition.rscale or 1)
+ context.font_fallbacks_register_math(i,name,features,size)
+ end
+ context.font_fallbacks_finish_math()
+ context.popcatcodes()
+ end
+ end
+ end
+ end
+end
+
+function mathematics.finishfallbacks()
+ local top = table.remove(stack)
+ if not top then
+ report_math("finish error in math fallbacks")
+ return
+ end
+ local target = top.target
+ local original = top.original
+ local list = top.list
local properties = original.properties
if properties and properties.hasmath then
local specification = target.specification
@@ -627,33 +754,38 @@ function mathematics.injectfallbacks(target,original)
local force = definition.force
local rscale = definition.rscale or 1
local offset = definition.offset or start
- local id = definedfont { name = name, size = size * rscale }
- local index = #fonts + 1
- fonts[index] = { id = id, size = size }
- local chars = fontchars[id]
- local function remap(unic,unicode,gap)
- local unic = unicode + offset - start
- if check and not chars[unicode] then
- -- not in font
- elseif force or (not done[unic] and not characters[unic]) then
- if trace_collecting then
- report_math("remapping math character, vector %a, font %a, character %C%s%s",
- fallbacks,name,unic,check and ", checked",gap and ", gap plugged")
+ local id = list[i]
+ if id then
+ local index = #fonts + 1
+ fonts[index] = { id = id, size = size }
+ local chars = fontchars[id]
+ local function remap(unic,unicode,gap)
+ local unic = unicode + offset - start
+ if check and not chars[unicode] then
+ -- not in font
+ elseif force or (not done[unic] and not characters[unic]) then
+ if trace_collecting then
+ report_math("remapping math character, vector %a, font %a, character %C%s%s",
+ fallbacks,name,unic,check and ", checked",gap and ", gap plugged")
+ end
+ characters[unic] = copiedglyph(target,characters,chars,unicode,index)
+ done[unic] = true
end
- characters[unic] = copiedglyph(target,characters,chars,unicode,index)
- done[unic] = true
end
- end
- for unicode = start, stop do
- local unic = unicode + offset - start
- remap(unic,unicode,false)
- end
- if gaps then
- for unic, unicode in next, gaps do
- remap(unic,unicode,true)
+ for unicode = start, stop do
+ local unic = unicode + offset - start
+ remap(unic,unicode,false)
+ end
+ if gaps then
+ for unic, unicode in next, gaps do
+ remap(unic,unicode,true)
+ end
end
end
end
+ xlist = nil
+ xtarget = nil
+ xoriginal = nil
end
end
end
diff --git a/tex/context/base/mkiv/node-typ.lua b/tex/context/base/mkiv/node-typ.lua
index 06d0f13c2..dea48cda8 100644
--- a/tex/context/base/mkiv/node-typ.lua
+++ b/tex/context/base/mkiv/node-typ.lua
@@ -18,10 +18,11 @@ local tonut = nuts.tonut
local setfield = nuts.setfield
local setlink = nuts.setlink
local setchar = nuts.setchar
------ setattrlist = nuts.setattrlist
+local setattrlist = nuts.setattrlist
local getfield = nuts.getfield
local getfont = nuts.getfont
+local getattrlist = nuts.getattrlist
local hpack_node_list = nuts.hpack
local vpack_node_list = nuts.vpack
@@ -33,20 +34,26 @@ local new_glue = nodepool.glue
local utfvalues = utf.values
-local currentfont = font.current
------ current_attr = node.current_attr
+local currentfont = font.current -- mabe nicer is fonts .current
+local currentattr = node.current_attr -- mabe nicer is attributes.current
local fontparameters = fonts.hashes.parameters
-local function tonodes(str,fontid,spacing,templateglyph) -- quick and dirty
+-- when attrid == true then take from glyph or current else use the given value
+
+local function tonodes(str,fontid,spacing,templateglyph,attrid) -- quick and dirty
local head, prev = nil, nil
- -- local attrid = nil
if not fontid then
if templateglyph then
fontid = getfont(templateglyph)
- -- attrid = setattrlist(templateglyph)
else
fontid = currentfont()
- -- attrid = current_attr()
+ end
+ end
+ if attrid == true then
+ if templateglyph then
+ attrid = false -- we copy with the glyph
+ else
+ attrid = currentattr()
end
end
local fp = fontparameters[fontid]
@@ -75,10 +82,14 @@ local function tonodes(str,fontid,spacing,templateglyph) -- quick and dirty
if not next then
-- nothing
elseif not head then
- -- setattrlist(next,attrid)
+ if attrid then
+ setattrlist(next,attrid)
+ end
head = next
else
- -- setattrlist(next,attrid)
+ if attrid then
+ setattrlist(next,attrid)
+ end
setlink(prev,next)
end
prev = next
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index a27cfc42f..c923f8a0f 100644
--- a/tex/context/base/mkiv/status-files.pdf
+++ b/tex/context/base/mkiv/status-files.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf
index c80930664..1f3c85b74 100644
--- a/tex/context/base/mkiv/status-lua.pdf
+++ b/tex/context/base/mkiv/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/symb-emj.lua b/tex/context/base/mkiv/symb-emj.lua
new file mode 100644
index 000000000..3075e0985
--- /dev/null
+++ b/tex/context/base/mkiv/symb-emj.lua
@@ -0,0 +1,82 @@
+if not modules then modules = { } end modules ['symb-emj'] = {
+ version = 1.001,
+ comment = "companion to symb-emj.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local symbols = fonts.symbols
+
+-- emoji
+
+-- processors.hpack_filter does it all
+
+local resolvedemoji = characters.emoji.resolve
+local processfeatures = fonts.handlers.otf.featuresprocessor
+local injectspacing = nodes.injections.handler
+local protectglyphs = nodes.handlers.protectglyphs
+local tonodes = nodes.tonodes
+local currentfont = font.current
+
+-- fast enough, no need to memoize
+
+local glyph_code = nodes.nodecodes.glyph
+local remove_node = nodes.remove
+local getid = nodes.getid
+local getnext = nodes.getnext
+local getchar = nodes.getchar
+
+local function removemodifiers(head)
+ local current = head
+ while current do
+ if getid(current) == glyph_code then
+ local char = getchar(current) -- using categories is too much
+ if char == 0x200D or (char >= 0x1F3FB and char <= 0x1F3FF) then
+ head, current = remove_node(head,current,true)
+ else
+ current = getnext(current)
+ end
+ else
+ current = getnext(current)
+ end
+ end
+ return head
+end
+
+-- attributes
+
+local function checkedemoji(name,id)
+ local str = resolvedemoji(name)
+ if str then
+ if not id then
+ id = currentfont()
+ end
+ local head = tonodes(str,id,nil,nil,true) -- use current attributes
+ head = processfeatures(head,id,false)
+ if head then
+ head = injectspacing(head)
+ protectglyphs(head)
+ return removemodifiers(head)
+ end
+ end
+end
+
+symbols.emoji = {
+ resolved = resolvedemoji,
+ checked = checkedemoji,
+}
+
+interfaces.implement {
+ name = "resolvedemoji",
+ actions = { resolvedemoji, context.escaped },
+ arguments = "string",
+}
+
+interfaces.implement {
+ name = "checkedemoji",
+ actions = { checkedemoji, context },
+ arguments = "string",
+}
+
+
diff --git a/tex/context/base/mkiv/symb-emj.mkiv b/tex/context/base/mkiv/symb-emj.mkiv
new file mode 100644
index 000000000..22d8b4a07
--- /dev/null
+++ b/tex/context/base/mkiv/symb-emj.mkiv
@@ -0,0 +1,27 @@
+%D \module
+%D [ file=symb-emj,
+%D version=2017.04.21,
+%D title=\CONTEXT\ Symbol Libraries,
+%D subtitle=Emoji,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Symbol Libraries / Emoji}
+
+\registerctxluafile{symb-emj}{1.001}
+
+\unprotect
+
+ \def\expandedemoji#1{\clf_resolvedemoji{#1}}
+\unexpanded\def\resolvedemoji#1{\clf_resolvedemoji{#1}}
+\unexpanded\def\checkedemoji #1{\clf_checkedemoji {#1}}
+\unexpanded\def\emoji #1{\dontleavehmode{\setdirectsymbolicfont{emoji}\clf_resolvedemoji{#1}}}
+\unexpanded\def\robustemoji #1{\dontleavehmode{\setdirectsymbolicfont{emoji}\clf_checkedemoji {#1}}}
+
+
+\protect \endinput
diff --git a/tex/context/base/mkiv/trac-vis.lua b/tex/context/base/mkiv/trac-vis.lua
index 1e7165abd..5d98bc24f 100644
--- a/tex/context/base/mkiv/trac-vis.lua
+++ b/tex/context/base/mkiv/trac-vis.lua
@@ -575,7 +575,8 @@ local ruledbox do
local baseline, baseskip
if dp ~= 0 and ht ~= 0 then
if wd > 20*linewidth then
- baseline = b_cache[size]
+ local targetsize = wd - size
+ baseline = b_cache[targetsize]
if not baseline then
-- due to an optimized leader color/transparency we need to set the glue node in order
-- to trigger this mechanism
@@ -585,8 +586,8 @@ local ruledbox do
setleader(baseline,leader)
setsubtype(baseline,cleaders_code)
setlisttransparency(baseline,c_text)
- baseline = hpack_nodes(baseline,wd-size)
- b_cache[size] = baseline
+ baseline = hpack_nodes(baseline,targetsize)
+ b_cache[targetsize] = baseline
end
baseline = copy_list(baseline)
baseskip = new_kern(-wd+linewidth)
diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf
index bb6619b2e..60d780fef 100644
--- a/tex/context/interface/mkiv/i-context.pdf
+++ b/tex/context/interface/mkiv/i-context.pdf
Binary files differ
diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf
index 675d2a7c9..847d275cb 100644
--- a/tex/context/interface/mkiv/i-readme.pdf
+++ b/tex/context/interface/mkiv/i-readme.pdf
Binary files differ
diff --git a/tex/context/modules/mkiv/s-fonts-emoji.mkiv b/tex/context/modules/mkiv/s-fonts-emoji.mkiv
new file mode 100644
index 000000000..59fdda124
--- /dev/null
+++ b/tex/context/modules/mkiv/s-fonts-emoji.mkiv
@@ -0,0 +1,331 @@
+%D \module
+%D [ file=s-fonts-emoji,
+%D version=2017.04.26,
+%D title=\CONTEXT\ Style File,
+%D subtitle=Emoji Helpers,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\startluacode
+moduledata.emoji = moduledata.emoji or { }
+
+local find = string.find
+local sortedhash = table.sortedhash
+local utfvalues = string.utfvalues
+
+local context = context
+
+local traverse_id = node.traverse_id
+local glyph_code = nodes.nodecodes.glyph
+
+local descriptions = fonts.hashes.descriptions
+local checkedemoji = fonts.symbols.emoji.checked
+local compactemoji = characters.emoji.compact
+local resolvedemoji = characters.emoji.resolve
+local knownemoji = characters.emoji.known
+
+local function emojisnippets(name)
+ local d = descriptions[true]
+ if d then
+ local e = resolvedemoji(name)
+ local s = { }
+ for b in utfvalues(e) do
+ if not (b == 0x200D or (b >= 0x1F3FB and b <= 0x1F3FF)) then
+ local t = { }
+ s[#s+1] = t
+ local c = d[b]
+ if c then
+ c = c.colors
+ if c then
+ for i=1,#c do
+ t[#t+1] = c[i].slot
+ end
+ else
+ t[#t+1] = b
+ end
+ end
+ end
+ end
+ return #s > 0 and s or nil
+ end
+end
+
+local function emojiglyphs(name)
+ local d = descriptions[true]
+ if d then
+ local e = checkedemoji(name)
+ local s = { }
+ for n in traverse_id(glyph_code,e) do
+ local b = n.char
+ if not (b == 0x200D or (b >= 0x1F3FB and b <= 0x1F3FF)) then
+ local t = { }
+ s[#s+1] = t
+ local c = d[b]
+ if c then
+ c = c.colors
+ if c then
+ for i=1,#c do
+ t[#t+1] = c[i].slot
+ end
+ else
+ t[#t+1] = b
+ end
+ end
+ end
+ end
+ nodes.flush_list(e)
+ return #s > 0 and s or nil
+ end
+end
+
+characters.emojisnippets = emojisnippets
+fonts.symbols.emojiglyphs = emojiglyphs
+
+function moduledata.emoji.showsnippets(name)
+ local s = emojisnippets(name)
+ if s then
+ local ni = #s
+ for i=1,ni do
+ local si = s[i]
+ local nj = #si
+ for j=1,nj do
+ context.WrapEmojiSnippet(i,ni,j,nj,si[j])
+ end
+ end
+ end
+end
+
+function moduledata.emoji.showglyphs(name)
+ local s = emojiglyphs(name)
+ if s then
+ local ni = #s
+ for i=1,ni do
+ local si = s[i]
+ local nj = #si
+ for j=1,nj do
+ context.WrapEmojiSnippet(i,ni,j,nj,si[j])
+ end
+ end
+ end
+end
+
+function moduledata.emoji.showknown(list)
+ local hash = knownemoji()
+ local size = 0
+ if list then
+ list = utilities.parsers.settings_to_array(list)
+ size = #list
+ if size == 0 then
+ list = false
+ else
+ for i=1,size do
+ list[i] = string.escapedpattern(list[i])
+ end
+ end
+ end
+ for k, v in sortedhash(hash) do
+ local okay = true
+ if find(compactemoji(k),"%-s%-t") then
+ okay = false
+ elseif list then
+ okay = false
+ for i=1,size do
+ if find(k,list[i]) then
+ okay = true
+ break
+ end
+ end
+ end
+ if okay then
+ context("\\WrapEmojiPlusText{%s}{%!tex!}",k,v)
+ end
+ end
+end
+
+local function convert(t,k)
+ local v = { }
+ for i=1,#k do
+ local p = k[i]
+ end
+ return v
+end
+
+function moduledata.emoji.showpalette(list)
+ local colorpalettes = fonts.hashes.resources[true].colorpalettes
+ if colorpalettes then
+ if list then
+ list = utilities.parsers.settings_to_hash(list)
+ if not next(list) then
+ list = false
+ end
+ end
+ context.starttabulate { "||lp|" }
+ for i=1,#colorpalettes do
+ if not list or list[tostring(i)] then
+ local palette = colorpalettes[i]
+ context.BC()
+ context.type(i)
+ context.NC()
+ for j=1,#palette do
+ local p = palette[j]
+ local r, g, b = p[1]/255, p[2]/255, p[3]/255
+ local s = attributes.colors.rgbtogray(r,g,b)
+ context.WrapEmojiColorEntry(j,s,r,g,b)
+ end
+ context.NC()
+ context.NR()
+ end
+ end
+ context.stoptabulate()
+ end
+end
+
+\stopluacode
+
+\unexpanded\def\WrapEmojiPlusText#1#2%
+ {\dontleavehmode\hbox\bgroup
+ \tttf % determines em
+ \hpack to 8\emwidth{\setfontid\scratchcounter#2\hss}%
+ \hpack to 8\emwidth{\setfontid\scratchcounter\checkedemoji{#1}\hss}%
+ #1%
+ \egroup\par}
+
+\unexpanded\def\ShowEmoji
+ {\dosingleempty\doShowEmoji}
+
+\unexpanded\def\doShowEmoji[#1]%
+ {\begingroup
+ \scratchcounter\fontid\font
+ \ctxlua{moduledata.emoji.showknown([[#1]])}%
+ \endgroup}
+
+\unexpanded\def\WrapEmojiSnippet#1#2#3#4#5%
+ {\ifnum#3=\plusone
+ \par
+ \dontleavehmode\ruledhbox\bgroup
+ \fi
+ \ruledhbox to 2\emwidth{\hss\char#5\hss}%
+ \ifnum#3=#4\relax
+ \egroup
+ \par
+ \fi}
+
+\unexpanded\def\ShowEmojiSnippets[#1]%
+ {\ctxlua{moduledata.emoji.showsnippets("#1")}}
+
+\unexpanded\def\ShowEmojiGlyphs[#1]%
+ {\ctxlua{moduledata.emoji.showglyphs("#1")}}
+
+\unexpanded\def\OverlayEmojiSnippet#1#2#3#4#5%
+ {\setbox\scratchbox\hbox{\color[trace:#3]{\char#5}}%
+ \ifnum#3=\plusone
+ \ifnum#1=\plusone
+ \dontleavehmode\ruledhbox\bgroup
+ \fi
+ \hbox\bgroup
+ \else
+ \hskip-\wd\scratchbox
+ \fi
+ \box\scratchbox
+ \ifnum#3=#4\relax
+ \egroup
+ \ifnum#1=#2\relax
+ \egroup
+ \fi
+ \fi}
+
+\unexpanded\def\ShowEmojiSnippetsOverlay[#1]%
+ {\begingroup
+ \let\WrapEmojiSnippet\OverlayEmojiSnippet
+ \ctxlua{moduledata.emoji.showsnippets("#1")}%
+ \endgroup}
+
+\unexpanded\def\WrapEmojiColorEntry#1#2#3#4#5%
+ {\dontleavehmode\hpack\bgroup
+ \definecolor
+ [dummy]
+ [r=#3,g=#4,b=#5]%
+ \backgroundline
+ [dummy]
+ {\setbox\scratchbox\hpack to 2\emwidth{\hss\ifdim#2pt<.5pt\white\fi\ttx#1\hss}%
+ \ht\scratchbox.8\strutht\dp\scratchbox.6\strutdp\box\scratchbox}%
+ \egroup
+ \quad}
+
+\unexpanded\def\ShowEmojiPalettes
+ {\dosingleempty\doShowEmojiPalettes}
+
+\unexpanded\def\doShowEmojiPalettes[#1]%
+ {\ctxlua{moduledata.emoji.showpalette([[#1]])}}
+
+% \definefontfeature[bandw:overlay][ccmp=yes,dist=yes]
+% \definefontfeature[color:overlay][ccmp=yes,dist=yes,colr=yes]
+% %definefontfeature[bandw:svg] [ccmp=yes,dist=yes]
+% \definefontfeature[color:svg] [ccmp=yes,dist=yes,svg=yes]
+% %definefontfeature[bandw:bitmap] [ccmp=yes,dist=yes,sbix=yes]
+% \definefontfeature[color:bitmap] [ccmp=yes,dist=yes,sbix=yes]
+
+\definefontfeature[seguiemj-cl][color:overlay]
+\definefontfeature[seguiemj-bw][bandw:overlay]
+
+% \definefont[MyEmoji] [seguiemj*seguiemj-bw]
+% \definefont[MyEmoji] [seguiemj*seguiemj-cl]
+% \definefont[MyEmoji] [emojionecolor-svginot*default,svg]
+% \definefont[MyEmoji] [emojionemozilla*default,overlay]
+% \definefont[MyEmoji] [applecoloremoji*default,bitmap]
+
+% \definecolor[trace:1][s=0,t=.5,a=1]
+% \definecolor[trace:2][s=0,t=.5,a=1]
+% \definecolor[trace:3][s=0,t=.5,a=1]
+% \definecolor[trace:4][s=0,t=.5,a=1]
+% \definecolor[trace:5][s=0,t=.5,a=1]
+% \definecolor[trace:6][s=0,t=.5,a=1]
+
+\continueifinputfile{s-fonts-emoji.mkiv}
+
+\starttext
+
+\start
+
+\definedfont[seguiemj*seguiemj-cl]
+
+\ShowEmojiSnippets
+ [family man light skin tone woman dark skin tone girl medium skin tone boy medium skin tone]
+
+\ShowEmojiSnippetsOverlay
+ [family man light skin tone woman dark skin tone girl medium skin tone boy medium skin tone]
+
+\ShowEmojiGlyphs
+ [family man light skin tone woman dark skin tone girl medium skin tone boy medium skin tone]
+
+\page
+
+\ShowEmoji[^man]
+
+\page
+
+\definecolor[emoji-base][r=.4]
+\definecolor[emoji-gray][s=.5,t=.5,a=1]
+
+\definefontcolorpalette
+ [emoji-gray]
+ [emoji-base,emoji-gray]
+
+\definefontfeature[seguiemj-cl][ccmp=yes,dist=yes,colr=emoji-gray]
+
+\definedfont[seguiemj*seguiemj-cl]
+
+\ShowEmoji
+
+\page
+
+\ShowEmojiPalettes[1]
+
+\stop
+
+\stoptext
diff --git a/tex/context/modules/mkiv/s-fonts-variable.lua b/tex/context/modules/mkiv/s-fonts-variable.lua
index d50df0121..d166e320c 100644
--- a/tex/context/modules/mkiv/s-fonts-variable.lua
+++ b/tex/context/modules/mkiv/s-fonts-variable.lua
@@ -28,7 +28,6 @@ function moduledata.fonts.variable.showvariations(specification)
if not fontfile then
return
end
-
local id, fontdata = fonts.definers.define {
name = fontfile,
-- size = fontsize,
@@ -36,7 +35,7 @@ function moduledata.fonts.variable.showvariations(specification)
}
if not fontdata then
- context("no font with name %a found",fontname)
+ context.type("no font with name %a found",fontname)
end
local resources = fontdata.resources
@@ -45,11 +44,11 @@ function moduledata.fonts.variable.showvariations(specification)
return
end
- local variabledata = resources.variabledata
+ local variabledata = resources.variabledata or { }
- if not variabledata then
- return
- end
+-- if not variabledata then
+-- return
+-- end
context.starttitle { title = fontdata.shared.rawdata.metadata.fullname }
diff --git a/tex/context/modules/mkiv/s-fonts-variable.mkiv b/tex/context/modules/mkiv/s-fonts-variable.mkiv
index 564c40e11..176432630 100644
--- a/tex/context/modules/mkiv/s-fonts-variable.mkiv
+++ b/tex/context/modules/mkiv/s-fonts-variable.mkiv
@@ -43,4 +43,7 @@
% \showfontvariations
% [font=file:kairossansvariable.ttf]
+ \showfontvariations
+ [font=file:sourcecode-regular.otf]
+
\stoptext
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index 093846c7a..cb95e9a87 100644
--- a/tex/generic/context/luatex/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex/luatex-fonts-merged.lua
@@ -1,6 +1,6 @@
-- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua
-- parent file : c:/data/develop/context/sources/luatex-fonts.lua
--- merge date : 04/20/17 21:31:47
+-- merge date : 04/27/17 01:00:26
do -- begin closure to overcome local limits and interference
@@ -1372,7 +1372,7 @@ local reserved=table.tohash {
'in','local','nil','not','or','repeat','return','then','true','until','while',
'NaN','goto',
}
-local function is_simple_table(t)
+local function is_simple_table(t,hexify)
local nt=#t
if nt>0 then
local n=0
@@ -1490,7 +1490,7 @@ local function do_serialize(root,name,depth,level,indexed)
if next(v)==nil then
handle(format("%s {},",depth))
elseif inline then
- local st=is_simple_table(v)
+ local st=is_simple_table(v,hexify)
if st then
handle(format("%s { %s },",depth,concat(st,", ")))
else
@@ -1573,7 +1573,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%q]={},",depth,k))
end
elseif inline then
- local st=is_simple_table(v)
+ local st=is_simple_table(v,hexify)
if st then
if tk=="number" then
if hexify then
@@ -8149,7 +8149,7 @@ local stripstring=string.nospaces
local utf16_to_utf8_be=utf.utf16_to_utf8_be
local report=logs.reporter("otf reader")
local trace_cmap=false
-local trace_cmap_detail=false
+local trace_cmap_detail=false
fonts=fonts or {}
local handlers=fonts.handlers or {}
fonts.handlers=handlers
@@ -8854,6 +8854,7 @@ local sequence={
{ 0,0,6 },
{ 3,0,6 },
{ 0,5,14 },
+{ 0,4,12 },
{ 3,10,13 },
}
local supported={}
@@ -9538,19 +9539,27 @@ local function readdata(f,offset,specification)
local instance=specification.instance
if type(instance)=="string" then
local factors=helpers.getfactors(fontdata,instance)
- specification.factors=factors
- fontdata.factors=factors
- fontdata.instance=instance
- report("user instance: %s, factors: % t",instance,factors)
+ if factors then
+ specification.factors=factors
+ fontdata.factors=factors
+ fontdata.instance=instance
+ report("user instance: %s, factors: % t",instance,factors)
+ else
+ report("user instance: %s, bad factors",instance)
+ end
end
end
if not fontdata.factors then
if fontdata.variabledata then
local factors=helpers.getfactors(fontdata,true)
- specification.factors=factors
- fontdata.factors=factors
- fontdata.instance=instance
- report("font instance: %s, factors: % t",instance,factors)
+ if factors then
+ specification.factors=factors
+ fontdata.factors=factors
+ fontdata.instance=instance
+ report("font instance: %s, factors: % t",instance,factors)
+ else
+ report("user instance: %s, bad factors",instance)
+ end
end
end
end
@@ -11508,7 +11517,9 @@ local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams)
local dictionary=dictionaries[1]
readglobals(f,data)
readcharstrings(f,data,version)
- if version~="cff2" then
+ if version=="cff2" then
+ dictionary.charset=nil
+ else
readencodings(f,data)
readcharsets(f,data,dictionary)
end
@@ -11653,10 +11664,16 @@ function readers.cff2(f,fontdata,specification)
nofglyphs=fontdata.nofglyphs,
}
parsedictionaries(data,dictionaries,"cff2")
- local storeoffset=dictionaries[1].vstore+data.header.offset+2
- local regions,deltas=readers.helpers.readvariationdata(f,storeoffset,factors)
- data.regions=regions
- data.deltas=deltas
+ local offset=dictionaries[1].vstore
+ if offset>0 then
+ local storeoffset=dictionaries[1].vstore+data.header.offset+2
+ local regions,deltas=readers.helpers.readvariationdata(f,storeoffset,factors)
+ data.regions=regions
+ data.deltas=deltas
+ else
+ data.regions={}
+ data.deltas={}
+ end
data.factors=specification.factors
local cid=data.dictionaries[1].cid
local all=specification.shapes or false
@@ -13368,7 +13385,13 @@ local function readlookuparray(f,noflookups,nofcurrent)
if index>length then
length=index
end
- lookups[index]=readushort(f)+1
+ local lookup=readushort(f)+1
+ local list=lookups[index]
+ if list then
+ list[#list+1]=lookup
+ else
+ lookups[index]={ lookup }
+ end
end
for index=1,length do
if not lookups[index] then
@@ -14528,43 +14551,55 @@ do
else
local length=#rlookups
for index=1,length do
- local lookupid=rlookups[index]
- if lookupid then
- local h=sublookuphash[lookupid]
- if not h then
- local lookup=lookups[lookupid]
- if lookup then
- local d=lookup.done
- if d then
- nofsublookups=nofsublookups+1
- h={
- index=nofsublookups,
- name=f_lookupname(lookupprefix,"d",lookupid+lookupidoffset),
- derived=true,
- steps=d.steps,
- nofsteps=d.nofsteps,
- type=d.lookuptype or "gsub_single",
- markclass=d.markclass or nil,
- flags=d.flags,
- }
- sublookuplist[nofsublookups]=copy(h)
- sublookuphash[lookupid]=nofsublookups
- sublookupcheck[lookupid]=1
- h=nofsublookups
+ local lookuplist=rlookups[index]
+ if lookuplist then
+ local length=#lookuplist
+ local found={}
+ local noffound=0
+ for index=1,length do
+ local lookupid=lookuplist[index]
+ if lookupid then
+ local h=sublookuphash[lookupid]
+ if not h then
+ local lookup=lookups[lookupid]
+ if lookup then
+ local d=lookup.done
+ if d then
+ nofsublookups=nofsublookups+1
+ h={
+ index=nofsublookups,
+ name=f_lookupname(lookupprefix,"d",lookupid+lookupidoffset),
+ derived=true,
+ steps=d.steps,
+ nofsteps=d.nofsteps,
+ type=d.lookuptype or "gsub_single",
+ markclass=d.markclass or nil,
+ flags=d.flags,
+ }
+ sublookuplist[nofsublookups]=copy(h)
+ sublookuphash[lookupid]=nofsublookups
+ sublookupcheck[lookupid]=1
+ h=nofsublookups
+ else
+ report_issue(i,what,sequence,"missing")
+ rule.lookups=nil
+ break
+ end
+ else
+ report_issue(i,what,sequence,"bad")
+ rule.lookups=nil
+ break
+ end
else
- report_issue(i,what,sequence,"missing")
- rule.lookups=nil
- break
+ sublookupcheck[lookupid]=sublookupcheck[lookupid]+1
+ end
+ if h then
+ noffound=noffound+1
+ found[noffound]=h
end
- else
- report_issue(i,what,sequence,"bad")
- rule.lookups=nil
- break
end
- else
- sublookupcheck[lookupid]=sublookupcheck[lookupid]+1
end
- rlookups[index]=h or false
+ rlookups[index]=noffound>0 and found or false
else
rlookups[index]=false
end
@@ -15493,7 +15528,7 @@ function readers.fvar(f,fontdata,specification)
default=readfixed(f),
maximum=readfixed(f),
flags=readushort(f),
- name=lower(extras[readushort(f)]),
+ name=lower(extras[readushort(f)] or "bad name"),
}
local n=sizeofaxis-20
if n>0 then
@@ -16469,7 +16504,7 @@ function readers.rehash(fontdata,hashmethod)
copyduplicates(fontdata)
unifymissing(fontdata)
else
- fontdata.hashmethod="unicode"
+ fontdata.hashmethod="unicodes"
local indices=unifyglyphs(fontdata)
unifyresources(fontdata,indices)
copyduplicates(fontdata)
@@ -16484,10 +16519,10 @@ function readers.checkhash(fontdata)
elseif hashmethod=="names" and fontdata.names then
unifyresources(fontdata,fontdata.names)
copyduplicates(fontdata)
- fontdata.hashmethod="unicode"
+ fontdata.hashmethod="unicodes"
fontdata.names=nil
else
- readers.rehash(fontdata,"unicode")
+ readers.rehash(fontdata,"unicodes")
end
end
function readers.addunicodetable(fontdata)
@@ -16860,7 +16895,6 @@ function readers.pack(data)
local r=rule.before if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end
local r=rule.after if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end
local r=rule.current if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end
- local r=rule.lookups if r then rule.lookups=pack_mixed (r) end
local r=rule.replacements if r then rule.replacements=pack_flat (r) end
end
end
@@ -17258,13 +17292,6 @@ function readers.unpack(data)
end
end
end
- local lookups=rule.lookups
- if lookups then
- local tv=tables[lookups]
- if tv then
- rule.lookups=tv
- end
- end
local replacements=rule.replacements
if replacements then
local tv=tables[replacements]
@@ -17768,14 +17795,19 @@ function readers.expand(data)
local lookups=rule.lookups or false
local subtype=nil
if lookups then
- for k,v in next,lookups do
- local lookup=sublookups[v]
- if lookup then
- lookups[k]=lookup
- if not subtype then
- subtype=lookup.type
+ for i=1,#lookups do
+ local lookups=lookups[i]
+ if lookups then
+ for k,v in next,lookups do
+ local lookup=sublookups[v]
+ if lookup then
+ lookups[k]=lookup
+ if not subtype then
+ subtype=lookup.type
+ end
+ else
+ end
end
- else
end
end
end
@@ -17839,7 +17871,7 @@ local trace_defining=false registertracker("fonts.defining",function(v) trace_de
local report_otf=logs.reporter("fonts","otf loading")
local fonts=fonts
local otf=fonts.handlers.otf
-otf.version=3.028
+otf.version=3.029
otf.cache=containers.define("fonts","otl",otf.version,true)
otf.svgcache=containers.define("fonts","svg",otf.version,true)
otf.sbixcache=containers.define("fonts","sbix",otf.version,true)
@@ -19308,7 +19340,7 @@ local function inject_kerns_only(head,where)
if i then
local leftkern=i.leftkern
if leftkern and leftkern~=0 then
- insert_node_before(head,current,newkern(leftkern))
+ head=insert_node_before(head,current,newkern(leftkern))
end
end
if prevdisc then
@@ -19689,7 +19721,7 @@ local function inject_everything(head,where)
ox=px-pn.markx
end
else
- ox=px-pn.markx
+ ox=px-pn.markx-rightkern
end
end
else
@@ -19782,7 +19814,7 @@ local function inject_everything(head,where)
end
local leftkern=i.leftkern
if leftkern and leftkern~=0 then
- insert_node_before(head,current,newkern(leftkern))
+ head=insert_node_before(head,current,newkern(leftkern))
end
local rightkern=i.rightkern
if rightkern and rightkern~=0 then
@@ -22016,16 +22048,19 @@ local function chainrun(head,start,last,dataset,sequence,rlmode,ck,skipped)
local nofchainlookups=#chainlookups
if size==1 then
local chainlookup=chainlookups[1]
- local chainkind=chainlookup.type
- local chainproc=chainprocs[chainkind]
- if chainproc then
- local ok
- head,start,ok=chainproc(head,start,last,dataset,sequence,chainlookup,rlmode,1)
- if ok then
- done=true
+ for j=1,#chainlookup do
+ local chainstep=chainlookup[j]
+ local chainkind=chainstep.type
+ local chainproc=chainprocs[chainkind]
+ if chainproc then
+ local ok
+ head,start,ok=chainproc(head,start,last,dataset,sequence,chainstep,rlmode,1)
+ if ok then
+ done=true
+ end
+ else
+ logprocess("%s: %s is not yet supported (1)",cref(dataset,sequence),chainkind)
end
- else
- logprocess("%s: %s is not yet supported (1)",cref(dataset,sequence),chainkind)
end
else
local i=1
@@ -22047,19 +22082,22 @@ local function chainrun(head,start,last,dataset,sequence,rlmode,ck,skipped)
end
local chainlookup=chainlookups[i]
if chainlookup then
- local chainkind=chainlookup.type
- local chainproc=chainprocs[chainkind]
- if chainproc then
- local ok,n
- head,start,ok,n=chainproc(head,start,last,dataset,sequence,chainlookup,rlmode,i)
- if ok then
- done=true
- if n and n>1 and i+n>nofchainlookups then
- break
+ for j=1,#chainlookup do
+ local chainstep=chainlookup[j]
+ local chainkind=chainstep.type
+ local chainproc=chainprocs[chainkind]
+ if chainproc then
+ local ok,n
+ head,start,ok,n=chainproc(head,start,last,dataset,sequence,chainstep,rlmode,i)
+ if ok then
+ done=true
+ if n and n>1 and i+n>nofchainlookups then
+ break
+ end
end
+ else
+ logprocess("%s: %s is not yet supported (2)",cref(dataset,sequence),chainkind)
end
- else
- logprocess("%s: %s is not yet supported (2)",cref(dataset,sequence),chainkind)
end
end
i=i+1
@@ -25927,7 +25965,6 @@ local tounicode=fonts.mappings.tounicode
local otf=fonts.handlers.otf
local f_color=formatters["pdf:direct:%f %f %f rg"]
local f_gray=formatters["pdf:direct:%f g"]
-local s_black="pdf:direct:0 g"
if context then
local startactualtext=nil
local stopactualtext=nil
@@ -25947,30 +25984,37 @@ else
end
end
local sharedpalettes={}
+local hash=table.setmetatableindex(function(t,k)
+ local v={ "special",k }
+ t[k]=v
+ return v
+end)
if context then
- local graytorgb=attributes.colors.graytorgb
- local cmyktorgb=attributes.colors.cmyktorgb
+ local colors=attributes.list[attributes.private('color')] or {}
+ local transparencies=attributes.list[attributes.private('transparency')] or {}
function otf.registerpalette(name,values)
sharedpalettes[name]=values
for i=1,#values do
local v=values[i]
- local r,g,b
- local s=v.s
- if s then
- r,g,b=graytorgb(s)
+ local c=nil
+ local t=nil
+ if type(v)=="table" then
+ c=colors.register(name,"rgb",
+ max(round((v.r or 0)*255),255)/255,
+ max(round((v.g or 0)*255),255)/255,
+ max(round((v.b or 0)*255),255)/255
+ )
else
- local c,m,y,k=v.c,v.m,v.y,v.k
- if c or m or y or k then
- r,g,b=cmyktorgb(c or 0,m or 0,y or 0,k or 0)
- else
- r,g,b=v.r,v.g,v.b
- end
+ c=colors[v]
+ t=transparencies[v]
+ end
+ if c and t then
+ values[i]=hash["pdf:direct:"..lpdf.color(1,c).." "..lpdf.transparency(t)]
+ elseif c then
+ values[i]=hash["pdf:direct:"..lpdf.color(1,c)]
+ elseif t then
+ values[i]=hash["pdf:direct:"..lpdf.color(1,t)]
end
- values[i]={
- max(r and round(r*255) or 0,255),
- max(g and round(g*255) or 0,255),
- max(b and round(b*255) or 0,255)
- }
end
end
else
@@ -25978,41 +26022,60 @@ else
sharedpalettes[name]=values
for i=1,#values do
local v=values[i]
- values[i]={
- max(round((v.r or 0)*255),255),
- max(round((v.g or 0)*255),255),
- max(round((v.b or 0)*255),255)
- }
+ values[i]=hash[f_color(
+ max(round((v.r or 0)*255),255)/255,
+ max(round((v.g or 0)*255),255)/255,
+ max(round((v.b or 0)*255),255)/255
+ )]
end
end
end
+local function convert(t,k)
+ local v={}
+ for i=1,#k do
+ local p=k[i]
+ local r,g,b=p[1],p[2],p[3]
+ if r==g and g==b then
+ v[i]=hash[f_gray(r/255)]
+ else
+ v[i]=hash[f_color(r/255,g/255,b/255)]
+ end
+ end
+ t[k]=v
+ return v
+end
local function initializecolr(tfmdata,kind,value)
if value then
- local palettes=tfmdata.resources.colorpalettes
+ local resources=tfmdata.resources
+ local palettes=resources.colorpalettes
if palettes then
- local palette=sharedpalettes[value] or palettes[tonumber(value) or 1] or palettes[1] or {}
- local classes=#palette
+ local converted=resources.converted
+ if not converted then
+ converted=table.setmetatableindex(convert)
+ resources.converted=converted
+ end
+ local colorvalues=sharedpalettes[value] or converted[palettes[tonumber(value) or 1] or palettes[1]] or {}
+ local classes=#colorvalues
if classes==0 then
return
end
local characters=tfmdata.characters
local descriptions=tfmdata.descriptions
local properties=tfmdata.properties
- local colorvalues={}
properties.virtualized=true
tfmdata.fonts={
{ id=0 }
}
- for i=1,classes do
- local p=palette[i]
- local r,g,b=p[1],p[2],p[3]
- if r==g and g==b then
- colorvalues[i]={ "special",f_gray(r/255) }
- else
- colorvalues[i]={ "special",f_color(r/255,g/255,b/255) }
- end
- end
+ local widths=table.setmetatableindex(function(t,k)
+ local v={ "right",-k }
+ t[k]=v
+ return v
+ end)
local getactualtext=otf.getactualtext
+ local default=colorvalues[#colorvalues]
+ local endactual=nil
+ local start={ "special","pdf:page:q" }
+ local stop={ "special","pdf:raw:Q" }
for unicode,character in next,characters do
local description=descriptions[unicode]
if description then
@@ -26021,21 +26084,30 @@ local function initializecolr(tfmdata,kind,value)
local b,e=getactualtext(tounicode(characters[unicode].unicode or 0xFFFD))
local w=character.width or 0
local s=#colorlist
+ local goback=w~=0 and widths[w] or nil
local t={
- { "special","pdf:page:q" },
+ start,
{ "special","pdf:raw:"..b }
}
local n=#t
+ local l=nil
for i=1,s do
local entry=colorlist[i]
- n=n+1 t[n]=colorvalues[entry.class] or s_black
+ local v=colorvalues[entry.class] or default
+ if v and l~=v then
+ n=n+1 t[n]=v
+ l=v
+ end
n=n+1 t[n]={ "char",entry.slot }
- if s>1 and i<s and w~=0 then
- n=n+1 t[n]={ "right",-w }
+ if s>1 and i<s and goback then
+ n=n+1 t[n]=goback
end
end
- n=n+1 t[n]={ "special","pdf:page:"..e }
- n=n+1 t[n]={ "special","pdf:raw:Q" }
+ if not endactual then
+ endactual={ "special","pdf:page:"..e }
+ end
+ n=n+1 t[n]=endactual
+ n=n+1 t[n]=stop
character.commands=t
end
end
@@ -26726,10 +26798,16 @@ local function addfeature(data,feature,specifications)
for k,v in next,lookups do
local t=type(v)
if t=="table" then
+ for i=1,#v do
+ local vi=v[i]
+ if type(vi)~="table" then
+ v[i]={ vi }
+ end
+ end
elseif t=="number" then
local lookup=sublookups[v]
if lookup then
- lookups[k]=lookup
+ lookups[k]={ lookup }
if not subtype then
subtype=lookup.type
end